Skip to content

Commit 83a4a46

Browse files
miguelaranda0juergw
authored andcommitted
Project import generated by Copybara.
PiperOrigin-RevId: 914210972
1 parent 4b9f688 commit 83a4a46

9 files changed

Lines changed: 171 additions & 32 deletions

File tree

common/src/jni/main/cpp/conscrypt/native_crypto.cc

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3096,16 +3096,6 @@ static jbyteArray NativeCrypto_SLHDSA_SHA2_128S_sign(JNIEnv* env, jclass, jbyteA
30963096
return nullptr;
30973097
}
30983098

3099-
uint8_t result[SLHDSA_SHA2_128S_SIGNATURE_BYTES];
3100-
if (!SLHDSA_SHA2_128S_sign(result,
3101-
reinterpret_cast<const unsigned char*>(privateKeyArray.get()),
3102-
reinterpret_cast<const unsigned char*>(dataArray.get()), dataLen,
3103-
/* context */ NULL, /* context_len */ 0)) {
3104-
JNI_TRACE("SLHDSA_SHA2_128S_sign failed");
3105-
conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "SLHDSA_SHA2_128S_sign");
3106-
return nullptr;
3107-
}
3108-
31093099
ScopedLocalRef<jbyteArray> resultRef(
31103100
env, env->NewByteArray(static_cast<jsize>(SLHDSA_SHA2_128S_SIGNATURE_BYTES)));
31113101
if (resultRef.get() == nullptr) {
@@ -3116,7 +3106,16 @@ static jbyteArray NativeCrypto_SLHDSA_SHA2_128S_sign(JNIEnv* env, jclass, jbyteA
31163106
if (resultArray.get() == nullptr) {
31173107
return nullptr;
31183108
}
3119-
memcpy(resultArray.get(), result, SLHDSA_SHA2_128S_SIGNATURE_BYTES);
3109+
3110+
if (!SLHDSA_SHA2_128S_sign(reinterpret_cast<uint8_t*>(resultArray.get()),
3111+
reinterpret_cast<const unsigned char*>(privateKeyArray.get()),
3112+
reinterpret_cast<const unsigned char*>(dataArray.get()), dataLen,
3113+
/* context */ NULL, /* context_len */ 0)) {
3114+
JNI_TRACE("SLHDSA_SHA2_128S_sign failed");
3115+
conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "SLHDSA_SHA2_128S_sign");
3116+
return nullptr;
3117+
}
3118+
31203119
return resultRef.release();
31213120
}
31223121

@@ -3174,18 +3173,33 @@ static jboolean NativeCrypto_X25519(JNIEnv* env, jclass, jbyteArray outArray,
31743173
pubkeyArray);
31753174
return JNI_FALSE;
31763175
}
3176+
if (out.size() != 32) {
3177+
conscrypt::jniutil::throwException(env, "java/lang/IllegalArgumentException",
3178+
"Output array length != 32");
3179+
return JNI_FALSE;
3180+
}
31773181

31783182
ScopedByteArrayRO privkey(env, privkeyArray);
31793183
if (privkey.get() == nullptr) {
31803184
JNI_TRACE("X25519(%p) => privkey == null", outArray);
31813185
return JNI_FALSE;
31823186
}
3187+
if (privkey.size() != 32) {
3188+
conscrypt::jniutil::throwException(env, "java/lang/IllegalArgumentException",
3189+
"Private key array length != 32");
3190+
return JNI_FALSE;
3191+
}
31833192

31843193
ScopedByteArrayRO pubkey(env, pubkeyArray);
31853194
if (pubkey.get() == nullptr) {
31863195
JNI_TRACE("X25519(%p) => pubkey == null", outArray);
31873196
return JNI_FALSE;
31883197
}
3198+
if (pubkey.size() != 32) {
3199+
conscrypt::jniutil::throwException(env, "java/lang/IllegalArgumentException",
3200+
"Public key array length != 32");
3201+
return JNI_FALSE;
3202+
}
31893203

31903204
if (X25519(reinterpret_cast<uint8_t*>(out.get()),
31913205
reinterpret_cast<const uint8_t*>(privkey.get()),

common/src/test/java/org/conscrypt/javax/net/ssl/KeyManagerFactoryTest.java

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,18 +85,6 @@ private TestKeyStore getTestKeyStore() throws Exception {
8585
return testKeyStore;
8686
}
8787

88-
// Remove legacy EC_EC type, which Jdk now considers invalid. (may or may not be a bug:
89-
// https://bugs.openjdk.org/browse/JDK-8379191)
90-
private static String[] removeLegacyEcTypes(String[] input) {
91-
List<String> list = new ArrayList<>();
92-
for (String s : input) {
93-
if (s != null && !s.equals("EC_EC")) {
94-
list.add(s);
95-
}
96-
}
97-
return list.toArray(new String[0]);
98-
}
99-
10088
@Test
10189
public void test_KeyManagerFactory_getDefaultAlgorithm() throws Exception {
10290
String algorithm = KeyManagerFactory.getDefaultAlgorithm();
@@ -207,7 +195,7 @@ private void test_KeyManagerFactory_getKeyManagers(KeyManagerFactory kmf, boolea
207195

208196
private void test_X509KeyManager(X509KeyManager km, boolean empty, String algorithm)
209197
throws Exception {
210-
String[] keyTypes = removeLegacyEcTypes(keyTypes(algorithm));
198+
String[] keyTypes = keyTypes(algorithm);
211199
for (String keyType : keyTypes) {
212200
String[] aliases = km.getClientAliases(keyType, null);
213201
if (empty || keyType == null || keyType.isEmpty()) {
@@ -253,7 +241,7 @@ private void test_X509KeyManager(X509KeyManager km, boolean empty, String algori
253241

254242
private void test_X509ExtendedKeyManager(X509ExtendedKeyManager km, boolean empty,
255243
String algorithm) throws Exception {
256-
String[] keyTypes = removeLegacyEcTypes(keyTypes(algorithm));
244+
String[] keyTypes = keyTypes(algorithm);
257245
String[][] rotatedTypes = rotate(nonEmpty(keyTypes));
258246
for (String[] keyList : rotatedTypes) {
259247
String alias = km.chooseEngineClientAlias(keyList, null, null);

common/src/test/java/org/conscrypt/javax/net/ssl/SSLSocketTest.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ public void test_SSLSocket_setEnabledProtocols() throws Exception {
409409
ssl.setEnabledProtocols(ssl.getSupportedProtocols());
410410
// Check that setEnabledProtocols affects getEnabledProtocols
411411
for (String protocol : ssl.getSupportedProtocols()) {
412-
if ("SSLv2Hello".equals(protocol)) {
412+
if (protocol.equals("SSLv2Hello")) {
413413
// Should fail when SSLv2Hello is set by itself
414414
assertThrows(IllegalArgumentException.class,
415415
() -> ssl.setEnabledProtocols(new String[] {protocol}));
@@ -977,8 +977,12 @@ public void handshake_noNamedGroupsProperty_usesDefaultGroups() throws Exception
977977
c.get();
978978
// By default, BoringSSL uses X25519, P-256, and P-384, in this order.
979979
// So X25519 gets priority.
980-
assertEquals("X25519", getCurveName(client));
981-
assertEquals("X25519", getCurveName(server));
980+
String clientCurve = getCurveName(client);
981+
String serverCurve = getCurveName(server);
982+
assertTrue("Unexpected client curve: " + clientCurve,
983+
clientCurve.equals("X25519") || clientCurve.equals("X25519MLKEM768"));
984+
assertTrue("Unexpected server curve: " + serverCurve,
985+
serverCurve.equals("X25519") || serverCurve.equals("X25519MLKEM768"));
982986
client.close();
983987
server.close();
984988
context.close();

openjdk/src/test/java/org/conscrypt/ConscryptSocketTest.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -474,8 +474,12 @@ public void test_handshake() throws Exception {
474474

475475
// By default, BoringSSL supports curves "X25519", "P-256" and "P-384".
476476
// X25519 gets priority, so that curve will be used in the handshake here.
477-
assertEquals("X25519", connection.server.getCurveNameForTesting());
478-
assertEquals("X25519", connection.client.getCurveNameForTesting());
477+
String serverCurve = connection.server.getCurveNameForTesting();
478+
String clientCurve = connection.client.getCurveNameForTesting();
479+
assertTrue("Unexpected server curve: " + serverCurve,
480+
serverCurve.equals("X25519") || serverCurve.equals("X25519MLKEM768"));
481+
assertTrue("Unexpected client curve: " + clientCurve,
482+
clientCurve.equals("X25519") || clientCurve.equals("X25519MLKEM768"));
479483
}
480484

481485
@Test

openjdk/src/test/java/org/conscrypt/NativeCryptoTest.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4595,4 +4595,62 @@ public void test_slhdsa_sha2_128s_works() throws Exception {
45954595
RuntimeException.class,
45964596
() -> NativeCrypto.SLHDSA_SHA2_128S_generate_key(publicKeyTooLong, privateKey));
45974597
}
4598+
4599+
@Test
4600+
public void x25519_testVector1FromRfc7748_works() throws Exception {
4601+
// Test vector from RFC 7748, Section 6.1 (Alice's side)
4602+
byte[] privateKey =
4603+
decodeHex("77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a");
4604+
byte[] expectedOutput =
4605+
decodeHex("8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a");
4606+
byte[] base = new byte[32];
4607+
base[0] = 9;
4608+
4609+
byte[] out = new byte[32];
4610+
boolean success = NativeCrypto.X25519(out, privateKey, base);
4611+
4612+
assertTrue(success);
4613+
assertArrayEquals(expectedOutput, out);
4614+
}
4615+
4616+
@Test
4617+
public void x25519_testVector2FromRfc7748_works() throws Exception {
4618+
// Test vector from RFC 7748, Section 6.1 (Bob's side)
4619+
byte[] privateKey =
4620+
decodeHex("5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb");
4621+
byte[] expectedOutput =
4622+
decodeHex("de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f");
4623+
byte[] base = new byte[32];
4624+
base[0] = 9;
4625+
4626+
byte[] out = new byte[32];
4627+
boolean success = NativeCrypto.X25519(out, privateKey, base);
4628+
4629+
assertTrue(success);
4630+
assertArrayEquals(expectedOutput, out);
4631+
}
4632+
4633+
@Test
4634+
public void x25519_invalidInputSize_throwsIllegalArgumentException() throws Exception {
4635+
assertThrows(IllegalArgumentException.class,
4636+
() -> NativeCrypto.X25519(new byte[31], new byte[32], new byte[32]));
4637+
4638+
assertThrows(IllegalArgumentException.class,
4639+
() -> NativeCrypto.X25519(new byte[32], new byte[31], new byte[32]));
4640+
4641+
assertThrows(IllegalArgumentException.class,
4642+
() -> NativeCrypto.X25519(new byte[32], new byte[32], new byte[31]));
4643+
}
4644+
4645+
@Test
4646+
public void x25519_nullInput_throwsIllegalArgumentException() throws Exception {
4647+
assertThrows(NullPointerException.class,
4648+
() -> NativeCrypto.X25519(null, new byte[32], new byte[32]));
4649+
4650+
assertThrows(NullPointerException.class,
4651+
() -> NativeCrypto.X25519(new byte[32], null, new byte[32]));
4652+
4653+
assertThrows(NullPointerException.class,
4654+
() -> NativeCrypto.X25519(new byte[32], new byte[32], null));
4655+
}
45984656
}

platform/src/main/java/org/conscrypt/AndroidHpkeSpi.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,58 @@ public X25519_CHACHA20() {
104104
super(new HpkeImpl.X25519_CHACHA20());
105105
}
106106
}
107+
108+
public static class MlKem768HkdfSha256Aes128Gcm extends AndroidHpkeSpi {
109+
public MlKem768HkdfSha256Aes128Gcm() {
110+
super(new HpkeImpl.MlKem768HkdfSha256Aes128Gcm());
111+
}
112+
}
113+
114+
public static class MlKem768HkdfSha256Aes256Gcm extends AndroidHpkeSpi {
115+
public MlKem768HkdfSha256Aes256Gcm() {
116+
super(new HpkeImpl.MlKem768HkdfSha256Aes256Gcm());
117+
}
118+
}
119+
120+
public static class MlKem768HkdfSha256ChaCha20Poly1305 extends AndroidHpkeSpi {
121+
public MlKem768HkdfSha256ChaCha20Poly1305() {
122+
super(new HpkeImpl.MlKem768HkdfSha256ChaCha20Poly1305());
123+
}
124+
}
125+
126+
public static class MlKem1024HkdfSha256Aes128Gcm extends AndroidHpkeSpi {
127+
public MlKem1024HkdfSha256Aes128Gcm() {
128+
super(new HpkeImpl.MlKem1024HkdfSha256Aes128Gcm());
129+
}
130+
}
131+
132+
public static class MlKem1024HkdfSha256Aes256Gcm extends AndroidHpkeSpi {
133+
public MlKem1024HkdfSha256Aes256Gcm() {
134+
super(new HpkeImpl.MlKem1024HkdfSha256Aes256Gcm());
135+
}
136+
}
137+
138+
public static class MlKem1024HkdfSha256ChaCha20Poly1305 extends AndroidHpkeSpi {
139+
public MlKem1024HkdfSha256ChaCha20Poly1305() {
140+
super(new HpkeImpl.MlKem1024HkdfSha256ChaCha20Poly1305());
141+
}
142+
}
143+
144+
public static class XwingHkdfSha256Aes128Gcm extends AndroidHpkeSpi {
145+
public XwingHkdfSha256Aes128Gcm() {
146+
super(new HpkeImpl.XwingHkdfSha256Aes128Gcm());
147+
}
148+
}
149+
150+
public static class XwingHkdfSha256Aes256Gcm extends AndroidHpkeSpi {
151+
public XwingHkdfSha256Aes256Gcm() {
152+
super(new HpkeImpl.XwingHkdfSha256Aes256Gcm());
153+
}
154+
}
155+
156+
public static class XwingHkdfSha256Chacha20Poly1305 extends AndroidHpkeSpi {
157+
public XwingHkdfSha256Chacha20Poly1305() {
158+
super(new HpkeImpl.XwingHkdfSha256Chacha20Poly1305());
159+
}
160+
}
107161
}

platform/src/test/java/org/conscrypt/AndroidHpkeSpiTest.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,16 @@ public class AndroidHpkeSpiTest {
3030
private static final String[] HPKE_NAMES =
3131
new String[] {"DHKEM_X25519_HKDF_SHA256/HKDF_SHA256/AES_128_GCM",
3232
"DHKEM_X25519_HKDF_SHA256/HKDF_SHA256/AES_256_GCM",
33-
"DHKEM_X25519_HKDF_SHA256/HKDF_SHA256/CHACHA20POLY1305"};
33+
"DHKEM_X25519_HKDF_SHA256/HKDF_SHA256/CHACHA20POLY1305",
34+
"MLKEM_768/HKDF_SHA256/AES_128_GCM",
35+
"MLKEM_768/HKDF_SHA256/AES_256_GCM",
36+
"MLKEM_768/HKDF_SHA256/CHACHA20POLY1305",
37+
"MLKEM_1024/HKDF_SHA256/AES_128_GCM",
38+
"MLKEM_1024/HKDF_SHA256/AES_256_GCM",
39+
"MLKEM_1024/HKDF_SHA256/CHACHA20POLY1305",
40+
"XWING/HKDF_SHA256/AES_128_GCM",
41+
"XWING/HKDF_SHA256/AES_256_GCM",
42+
"XWING/HKDF_SHA256/CHACHA20POLY1305"};
3443

3544
// This only needs to test the wrapper functionality as the implementation and client
3645
// APIs are tested elsewhere. What we're looking for is that HPKE SPI instances returned

testing/src/main/java/org/conscrypt/java/security/StandardNames.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,8 @@ private static void addOpenSsl(String cipherSuite) {
333333
// https://boringssl.googlesource.com/boringssl/+/main/ssl/extensions.cc#215
334334
private static final List<String> ELLIPTIC_CURVES_DEFAULT =
335335
Arrays.asList("x25519 (29)", "secp256r1 (23)", "secp384r1 (24)");
336+
private static final List<String> ELLIPTIC_CURVES_DEFAULT_PQC = Arrays.asList(
337+
"x25519mlkem768 (4588)", "x25519 (29)", "secp256r1 (23)", "secp384r1 (24)");
336338

337339
/**
338340
* Asserts that the cipher suites array is non-null and that it
@@ -441,7 +443,10 @@ public static void assertDefaultCipherSuites(String[] cipherSuites) {
441443
}
442444

443445
public static void assertDefaultEllipticCurves(String[] curves) {
444-
assertEquals(ELLIPTIC_CURVES_DEFAULT, Arrays.asList(curves));
446+
List<String> actualList = Arrays.asList(curves);
447+
assertTrue("Unexpected default curves list: " + actualList,
448+
actualList.equals(ELLIPTIC_CURVES_DEFAULT)
449+
|| actualList.equals(ELLIPTIC_CURVES_DEFAULT_PQC));
445450
}
446451

447452
public static void assertSSLContextEnabledProtocols(String version, String[] protocols) {

testing/src/main/java/org/conscrypt/tlswire/handshake/EllipticCurve.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ public enum EllipticCurve {
5252
BRAINPOOLP521R1(28, "brainpoolP521r1"),
5353
X25519(29, "x25519"),
5454
X448(30, "x448"),
55+
MLKEM1024(514, "mlkem1024"),
56+
X25519MLKEM768(4588, "x25519mlkem768"),
57+
X25519KYBER768DRAFT00(25055, "x25519kyber768draft00"),
5558
ARBITRARY_PRIME(0xFF01, "arbitrary_explicit_prime_curves"),
5659
ARBITRARY_CHAR2(0xFF02, "arbitrary_explicit_char2_curves");
5760
public final int identifier;

0 commit comments

Comments
 (0)