2020import static org .conscrypt .HpkeSuite .AEAD_CHACHA20POLY1305 ;
2121import static org .conscrypt .HpkeSuite .KDF_HKDF_SHA256 ;
2222import static org .conscrypt .HpkeSuite .KEM_DHKEM_X25519_HKDF_SHA256 ;
23+ import static org .conscrypt .HpkeSuite .KEM_XWING ;
2324
2425import java .security .GeneralSecurityException ;
2526import java .security .InvalidKeyException ;
3536 * of the subclasses of {@link HpkeContext}.
3637 */
3738@ Internal
38- public class HpkeImpl implements HpkeSpi {
39+ public abstract class HpkeImpl implements HpkeSpi {
3940 private final HpkeSuite hpkeSuite ;
4041
4142 private NativeRef .EVP_HPKE_CTX ctx ;
@@ -45,19 +46,17 @@ public HpkeImpl(HpkeSuite hpkeSuite) {
4546 this .hpkeSuite = hpkeSuite ;
4647 }
4748
49+ abstract byte [] getRecipientPublicKeyBytes (PublicKey recipientKey ) throws InvalidKeyException ;
50+
4851 @ Override
4952 public void engineInitSender (PublicKey recipientKey , byte [] info , PrivateKey senderKey ,
5053 byte [] psk , byte [] psk_id ) throws InvalidKeyException {
5154 checkNotInitialised ();
5255 checkArgumentsForBaseModeOnly (senderKey , psk , psk_id );
5356 if (recipientKey == null ) {
5457 throw new InvalidKeyException ("null recipient key" );
55- } else if (!(recipientKey instanceof OpenSSLX25519PublicKey )) {
56- throw new InvalidKeyException (
57- "Unsupported recipient key class: " + recipientKey .getClass ());
5858 }
59- final byte [] recipientKeyBytes = ((OpenSSLX25519PublicKey ) recipientKey ).getU ();
60-
59+ final byte [] recipientKeyBytes = getRecipientPublicKeyBytes (recipientKey );
6160 final Object [] result = NativeCrypto .EVP_HPKE_CTX_setup_base_mode_sender (
6261 hpkeSuite , recipientKeyBytes , info );
6362 ctx = (NativeRef .EVP_HPKE_CTX ) result [0 ];
@@ -73,19 +72,17 @@ public void engineInitSenderForTesting(PublicKey recipientKey, byte[] info,
7372 checkArgumentsForBaseModeOnly (senderKey , psk , psk_id );
7473 if (recipientKey == null ) {
7574 throw new InvalidKeyException ("null recipient key" );
76- } else if (!(recipientKey instanceof OpenSSLX25519PublicKey )) {
77- throw new InvalidKeyException (
78- "Unsupported recipient key class: " + recipientKey .getClass ());
7975 }
80- final byte [] recipientKeyBytes = ((OpenSSLX25519PublicKey ) recipientKey ).getU ();
81-
76+ final byte [] recipientKeyBytes = getRecipientPublicKeyBytes (recipientKey );
8277 final Object [] result =
8378 NativeCrypto .EVP_HPKE_CTX_setup_base_mode_sender_with_seed_for_testing (
8479 hpkeSuite , recipientKeyBytes , info , sKe );
8580 ctx = (NativeRef .EVP_HPKE_CTX ) result [0 ];
8681 encapsulated = (byte []) result [1 ];
8782 }
8883
84+ abstract byte [] getPrivateRecipientKeyBytes (PrivateKey recipientKey ) throws InvalidKeyException ;
85+
8986 @ Override
9087 public void engineInitRecipient (byte [] encapsulated , PrivateKey recipientKey , byte [] info ,
9188 PublicKey senderKey , byte [] psk , byte [] psk_id ) throws InvalidKeyException {
@@ -98,12 +95,8 @@ public void engineInitRecipient(byte[] encapsulated, PrivateKey recipientKey, by
9895
9996 if (recipientKey == null ) {
10097 throw new InvalidKeyException ("null recipient key" );
101- } else if (!(recipientKey instanceof OpenSSLX25519PrivateKey )) {
102- throw new InvalidKeyException (
103- "Unsupported recipient key class: " + recipientKey .getClass ());
10498 }
105- final byte [] recipientKeyBytes = ((OpenSSLX25519PrivateKey ) recipientKey ).getU ();
106-
99+ final byte [] recipientKeyBytes = getPrivateRecipientKeyBytes (recipientKey );
107100 ctx = (NativeRef .EVP_HPKE_CTX ) NativeCrypto .EVP_HPKE_CTX_setup_base_mode_recipient (
108101 hpkeSuite , recipientKeyBytes , encapsulated , info );
109102 }
@@ -181,22 +174,94 @@ public byte[] getEncapsulated() {
181174 return encapsulated ;
182175 }
183176
184- public static class X25519_AES_128 extends HpkeImpl {
177+ private static class HpkeX25519Impl extends HpkeImpl {
178+ private HpkeX25519Impl (HpkeSuite hpkeSuite ) {
179+ super (hpkeSuite );
180+ }
181+
182+ @ Override
183+ byte [] getRecipientPublicKeyBytes (PublicKey recipientKey ) throws InvalidKeyException {
184+ if (!(recipientKey instanceof OpenSSLX25519PublicKey )) {
185+ throw new InvalidKeyException (
186+ "Unsupported recipient key class: " + recipientKey .getClass ());
187+ }
188+ return ((OpenSSLX25519PublicKey ) recipientKey ).getU ();
189+ }
190+
191+ @ Override
192+ byte [] getPrivateRecipientKeyBytes (PrivateKey recipientKey ) throws InvalidKeyException {
193+ if (!(recipientKey instanceof OpenSSLX25519PrivateKey )) {
194+ throw new InvalidKeyException (
195+ "Unsupported recipient private key class: " + recipientKey .getClass ());
196+ }
197+ return ((OpenSSLX25519PrivateKey ) recipientKey ).getU ();
198+ }
199+ }
200+
201+ /** Implementation of X25519/HKDF_SHA256/AES_128_GCM. */
202+ public static class X25519_AES_128 extends HpkeX25519Impl {
185203 public X25519_AES_128 () {
186204 super (new HpkeSuite (KEM_DHKEM_X25519_HKDF_SHA256 , KDF_HKDF_SHA256 , AEAD_AES_128_GCM ));
187205 }
188206 }
189207
190- public static class X25519_AES_256 extends HpkeImpl {
208+ /** Implementation of X25519/HKDF_SHA256/AES_256_GCM. */
209+ public static class X25519_AES_256 extends HpkeX25519Impl {
191210 public X25519_AES_256 () {
192211 super (new HpkeSuite (KEM_DHKEM_X25519_HKDF_SHA256 , KDF_HKDF_SHA256 , AEAD_AES_256_GCM ));
193212 }
194213 }
195214
196- public static class X25519_CHACHA20 extends HpkeImpl {
215+ /** Implementation of X25519/HKDF_SHA256/CHACHA20_POLY1305. */
216+ public static class X25519_CHACHA20 extends HpkeX25519Impl {
197217 public X25519_CHACHA20 () {
198218 super (new HpkeSuite (
199219 KEM_DHKEM_X25519_HKDF_SHA256 , KDF_HKDF_SHA256 , AEAD_CHACHA20POLY1305 ));
200220 }
201221 }
222+
223+ private static class HpkeXwingImpl extends HpkeImpl {
224+ HpkeXwingImpl (HpkeSuite hpkeSuite ) {
225+ super (hpkeSuite );
226+ }
227+
228+ @ Override
229+ byte [] getRecipientPublicKeyBytes (PublicKey publicKey ) throws InvalidKeyException {
230+ if (!(publicKey instanceof OpenSslXwingPublicKey )) {
231+ throw new InvalidKeyException (
232+ "Unsupported recipient key class: " + publicKey .getClass ());
233+ }
234+ return ((OpenSslXwingPublicKey ) publicKey ).getRaw ();
235+ }
236+
237+ @ Override
238+ byte [] getPrivateRecipientKeyBytes (PrivateKey recipientKey ) throws InvalidKeyException {
239+ if (!(recipientKey instanceof OpenSslXwingPrivateKey )) {
240+ throw new InvalidKeyException (
241+ "Unsupported recipient private key class: " + recipientKey .getClass ());
242+ }
243+ return ((OpenSslXwingPrivateKey ) recipientKey ).getRaw ();
244+ }
245+ }
246+
247+ /** Implementation of XWING/HKDF_SHA256/AES_128_GCM. */
248+ public static class XwingHkdfSha256Aes128Gcm extends HpkeXwingImpl {
249+ public XwingHkdfSha256Aes128Gcm () {
250+ super (new HpkeSuite (KEM_XWING , KDF_HKDF_SHA256 , AEAD_AES_128_GCM ));
251+ }
252+ }
253+
254+ /** Implementation of XWING/HKDF_SHA256/AES_256_GCM. */
255+ public static class XwingHkdfSha256Aes256Gcm extends HpkeXwingImpl {
256+ public XwingHkdfSha256Aes256Gcm () {
257+ super (new HpkeSuite (KEM_XWING , KDF_HKDF_SHA256 , AEAD_AES_256_GCM ));
258+ }
259+ }
260+
261+ /** Implementation of XWING/HKDF_SHA256/CHACHA20_POLY1305. */
262+ public static class XwingHkdfSha256ChaCha20Poly1305 extends HpkeXwingImpl {
263+ public XwingHkdfSha256ChaCha20Poly1305 () {
264+ super (new HpkeSuite (KEM_XWING , KDF_HKDF_SHA256 , AEAD_CHACHA20POLY1305 ));
265+ }
266+ }
202267}
0 commit comments