Skip to content

Commit 031b5f9

Browse files
miguelaranda0juergw
authored andcommitted
Project import generated by Copybara.
PiperOrigin-RevId: 913600876
1 parent 4b9f688 commit 031b5f9

4 files changed

Lines changed: 142 additions & 4 deletions

File tree

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3174,18 +3174,33 @@ static jboolean NativeCrypto_X25519(JNIEnv* env, jclass, jbyteArray outArray,
31743174
pubkeyArray);
31753175
return JNI_FALSE;
31763176
}
3177+
if (out.size() != 32) {
3178+
conscrypt::jniutil::throwException(env, "java/lang/IllegalArgumentException",
3179+
"Output array length != 32");
3180+
return JNI_FALSE;
3181+
}
31773182

31783183
ScopedByteArrayRO privkey(env, privkeyArray);
31793184
if (privkey.get() == nullptr) {
31803185
JNI_TRACE("X25519(%p) => privkey == null", outArray);
31813186
return JNI_FALSE;
31823187
}
3188+
if (privkey.size() != 32) {
3189+
conscrypt::jniutil::throwException(env, "java/lang/IllegalArgumentException",
3190+
"Private key array length != 32");
3191+
return JNI_FALSE;
3192+
}
31833193

31843194
ScopedByteArrayRO pubkey(env, pubkeyArray);
31853195
if (pubkey.get() == nullptr) {
31863196
JNI_TRACE("X25519(%p) => pubkey == null", outArray);
31873197
return JNI_FALSE;
31883198
}
3199+
if (pubkey.size() != 32) {
3200+
conscrypt::jniutil::throwException(env, "java/lang/IllegalArgumentException",
3201+
"Public key array length != 32");
3202+
return JNI_FALSE;
3203+
}
31893204

31903205
if (X25519(reinterpret_cast<uint8_t*>(out.get()),
31913206
reinterpret_cast<const uint8_t*>(privkey.get()),

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: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,21 @@
2727

2828
@RunWith(JUnit4.class)
2929
public class AndroidHpkeSpiTest {
30-
private static final String[] HPKE_NAMES =
31-
new String[] {"DHKEM_X25519_HKDF_SHA256/HKDF_SHA256/AES_128_GCM",
32-
"DHKEM_X25519_HKDF_SHA256/HKDF_SHA256/AES_256_GCM",
33-
"DHKEM_X25519_HKDF_SHA256/HKDF_SHA256/CHACHA20POLY1305"};
30+
private static final String[] HPKE_NAMES =
31+
new String[] {
32+
"DHKEM_X25519_HKDF_SHA256/HKDF_SHA256/AES_128_GCM",
33+
"DHKEM_X25519_HKDF_SHA256/HKDF_SHA256/AES_256_GCM",
34+
"DHKEM_X25519_HKDF_SHA256/HKDF_SHA256/CHACHA20POLY1305",
35+
"MLKEM_768/HKDF_SHA256/AES_128_GCM",
36+
"MLKEM_768/HKDF_SHA256/AES_256_GCM",
37+
"MLKEM_768/HKDF_SHA256/CHACHA20POLY1305",
38+
"MLKEM_1024/HKDF_SHA256/AES_128_GCM",
39+
"MLKEM_1024/HKDF_SHA256/AES_256_GCM",
40+
"MLKEM_1024/HKDF_SHA256/CHACHA20POLY1305",
41+
"XWING/HKDF_SHA256/AES_128_GCM",
42+
"XWING/HKDF_SHA256/AES_256_GCM",
43+
"XWING/HKDF_SHA256/CHACHA20POLY1305"
44+
};
3445

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

0 commit comments

Comments
 (0)