diff --git a/mls/mls-rs-crypto-boringssl/src/aead.rs b/mls/mls-rs-crypto-boringssl/src/aead.rs
new file mode 100644
index 0000000..eaa33a9
--- /dev/null
+++ b/mls/mls-rs-crypto-boringssl/src/aead.rs
@@ -0,0 +1,334 @@
+// Copyright 2024, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Authenticated encryption with additional data.
+
+use bssl_crypto::aead::{Aead, Aes128Gcm, Aes256Gcm, Chacha20Poly1305};
+use mls_rs_core::crypto::CipherSuite;
+use mls_rs_core::error::IntoAnyError;
+use mls_rs_crypto_traits::{AeadId, AeadType, AES_TAG_LEN};
+
+use core::array::TryFromSliceError;
+use thiserror::Error;
+
+/// Errors returned from AEAD.
+#[derive(Debug, Error)]
+pub enum AeadError {
+    /// Error returned when conversion from slice to array fails.
+    #[error(transparent)]
+    TryFromSliceError(#[from] TryFromSliceError),
+    /// Error returned when the ciphertext is invalid.
+    #[error("AEAD ciphertext was invalid")]
+    InvalidCiphertext,
+    /// Error returned when the ciphertext length is too short.
+    #[error("AEAD ciphertext of length {len}, expected length at least {min_len}")]
+    TooShortCiphertext {
+        /// Invalid ciphertext length.
+        len: usize,
+        /// Minimum ciphertext length.
+        min_len: usize,
+    },
+    /// Error returned when the plaintext is empty.
+    #[error("message cannot be empty")]
+    EmptyPlaintext,
+    /// Error returned when the key length is invalid.
+    #[error("AEAD key of invalid length {len}, expected length {expected_len}")]
+    InvalidKeyLen {
+        /// Invalid key length.
+        len: usize,
+        /// Expected key length.
+        expected_len: usize,
+    },
+    /// Error returned when the nonce size is invalid.
+    #[error("AEAD nonce of invalid length {len}, expected length {expected_len}")]
+    InvalidNonceLen {
+        /// Invalid nonce length.
+        len: usize,
+        /// Expected nonce length.
+        expected_len: usize,
+    },
+    /// Error returned when unsupported cipher suite is requested.
+    #[error("unsupported cipher suite")]
+    UnsupportedCipherSuite,
+}
+
+impl IntoAnyError for AeadError {
+    fn into_dyn_error(self) -> Result<Box<dyn std::error::Error + Send + Sync>, Self> {
+        Ok(self.into())
+    }
+}
+
+/// AeadType implementation backed by BoringSSL.
+#[derive(Clone)]
+pub struct AeadWrapper(AeadId);
+
+impl AeadWrapper {
+    /// Creates a new AeadWrapper.
+    pub fn new(cipher_suite: CipherSuite) -> Option<Self> {
+        AeadId::new(cipher_suite).map(Self)
+    }
+}
+
+#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+#[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))]
+#[cfg_attr(all(not(target_arch = "wasm32"), mls_build_async), maybe_async::must_be_async)]
+impl AeadType for AeadWrapper {
+    type Error = AeadError;
+
+    async fn seal<'a>(
+        &self,
+        key: &[u8],
+        data: &[u8],
+        aad: Option<&'a [u8]>,
+        nonce: &[u8],
+    ) -> Result<Vec<u8>, AeadError> {
+        if data.is_empty() {
+            return Err(AeadError::EmptyPlaintext);
+        }
+        if key.len() != self.key_size() {
+            return Err(AeadError::InvalidKeyLen { len: key.len(), expected_len: self.key_size() });
+        }
+        if nonce.len() != self.nonce_size() {
+            return Err(AeadError::InvalidNonceLen {
+                len: nonce.len(),
+                expected_len: self.nonce_size(),
+            });
+        }
+
+        let nonce_array = nonce[..self.nonce_size()].try_into()?;
+
+        match self.0 {
+            AeadId::Aes128Gcm => {
+                let cipher = Aes128Gcm::new(key[..self.key_size()].try_into()?);
+                Ok(cipher.seal(nonce_array, data, aad.unwrap_or_default()))
+            }
+            AeadId::Aes256Gcm => {
+                let cipher = Aes256Gcm::new(key[..self.key_size()].try_into()?);
+                Ok(cipher.seal(nonce_array, data, aad.unwrap_or_default()))
+            }
+            AeadId::Chacha20Poly1305 => {
+                let cipher = Chacha20Poly1305::new(key[..self.key_size()].try_into()?);
+                Ok(cipher.seal(nonce_array, data, aad.unwrap_or_default()))
+            }
+            _ => Err(AeadError::UnsupportedCipherSuite),
+        }
+    }
+
+    async fn open<'a>(
+        &self,
+        key: &[u8],
+        ciphertext: &[u8],
+        aad: Option<&'a [u8]>,
+        nonce: &[u8],
+    ) -> Result<Vec<u8>, AeadError> {
+        if ciphertext.len() < AES_TAG_LEN {
+            return Err(AeadError::TooShortCiphertext {
+                len: ciphertext.len(),
+                min_len: AES_TAG_LEN,
+            });
+        }
+        if key.len() != self.key_size() {
+            return Err(AeadError::InvalidKeyLen { len: key.len(), expected_len: self.key_size() });
+        }
+        if nonce.len() != self.nonce_size() {
+            return Err(AeadError::InvalidNonceLen {
+                len: nonce.len(),
+                expected_len: self.nonce_size(),
+            });
+        }
+
+        let nonce_array = nonce[..self.nonce_size()].try_into()?;
+
+        match self.0 {
+            AeadId::Aes128Gcm => {
+                let cipher = Aes128Gcm::new(key[..self.key_size()].try_into()?);
+                cipher
+                    .open(nonce_array, ciphertext, aad.unwrap_or_default())
+                    .ok_or(AeadError::InvalidCiphertext)
+            }
+            AeadId::Aes256Gcm => {
+                let cipher = Aes256Gcm::new(key[..self.key_size()].try_into()?);
+                cipher
+                    .open(nonce_array, ciphertext, aad.unwrap_or_default())
+                    .ok_or(AeadError::InvalidCiphertext)
+            }
+            AeadId::Chacha20Poly1305 => {
+                let cipher = Chacha20Poly1305::new(key[..self.key_size()].try_into()?);
+                cipher
+                    .open(nonce_array, ciphertext, aad.unwrap_or_default())
+                    .ok_or(AeadError::InvalidCiphertext)
+            }
+            _ => Err(AeadError::UnsupportedCipherSuite),
+        }
+    }
+
+    #[inline(always)]
+    fn key_size(&self) -> usize {
+        self.0.key_size()
+    }
+
+    fn nonce_size(&self) -> usize {
+        self.0.nonce_size()
+    }
+
+    fn aead_id(&self) -> u16 {
+        self.0 as u16
+    }
+}
+
+#[cfg(all(not(mls_build_async), test))]
+mod test {
+    use super::{AeadError, AeadWrapper};
+    use assert_matches::assert_matches;
+    use mls_rs_core::crypto::CipherSuite;
+    use mls_rs_crypto_traits::{AeadType, AES_TAG_LEN};
+
+    fn get_aeads() -> Vec<AeadWrapper> {
+        [
+            CipherSuite::CURVE25519_AES128,
+            CipherSuite::CURVE25519_CHACHA,
+            CipherSuite::CURVE448_AES256,
+        ]
+        .into_iter()
+        .map(|suite| AeadWrapper::new(suite).unwrap())
+        .collect()
+    }
+
+    #[test]
+    fn seal_and_open() {
+        for aead in get_aeads() {
+            let key = vec![42u8; aead.key_size()];
+            let nonce = vec![42u8; aead.nonce_size()];
+            let plaintext = b"message";
+
+            let ciphertext = aead.seal(&key, plaintext, None, &nonce).unwrap();
+            assert_eq!(
+                plaintext,
+                aead.open(&key, ciphertext.as_slice(), None, &nonce).unwrap().as_slice(),
+                "open failed for AEAD with ID {}",
+                aead.aead_id(),
+            );
+        }
+    }
+
+    #[test]
+    fn seal_and_open_with_invalid_key() {
+        for aead in get_aeads() {
+            let data = b"top secret data that's long enough";
+            let nonce = vec![42u8; aead.nonce_size()];
+
+            let key_short = vec![42u8; aead.key_size() - 1];
+            assert_matches!(
+                aead.seal(&key_short, data, None, &nonce),
+                Err(AeadError::InvalidKeyLen { .. }),
+                "seal with short key should fail for AEAD with ID {}",
+                aead.aead_id(),
+            );
+            assert_matches!(
+                aead.open(&key_short, data, None, &nonce),
+                Err(AeadError::InvalidKeyLen { .. }),
+                "open with short key should fail for AEAD with ID {}",
+                aead.aead_id(),
+            );
+
+            let key_long = vec![42u8; aead.key_size() + 1];
+            assert_matches!(
+                aead.seal(&key_long, data, None, &nonce),
+                Err(AeadError::InvalidKeyLen { .. }),
+                "seal with long key should fail for AEAD with ID {}",
+                aead.aead_id(),
+            );
+            assert_matches!(
+                aead.open(&key_long, data, None, &nonce),
+                Err(AeadError::InvalidKeyLen { .. }),
+                "open with long key should fail for AEAD with ID {}",
+                aead.aead_id(),
+            );
+        }
+    }
+
+    #[test]
+    fn invalid_ciphertext() {
+        for aead in get_aeads() {
+            let key = vec![42u8; aead.key_size()];
+            let nonce = vec![42u8; aead.nonce_size()];
+
+            let ciphertext_short = [0u8; AES_TAG_LEN - 1];
+            assert_matches!(
+                aead.open(&key, &ciphertext_short, None, &nonce),
+                Err(AeadError::TooShortCiphertext { .. }),
+                "open with short ciphertext should fail for AEAD with ID {}",
+                aead.aead_id(),
+            );
+        }
+    }
+
+    #[test]
+    fn associated_data_mismatch() {
+        for aead in get_aeads() {
+            let key = vec![42u8; aead.key_size()];
+            let nonce = vec![42u8; aead.nonce_size()];
+
+            let ciphertext = aead.seal(&key, b"message", Some(b"foo"), &nonce).unwrap();
+            assert_matches!(
+                aead.open(&key, &ciphertext, Some(b"bar"), &nonce),
+                Err(AeadError::InvalidCiphertext),
+                "open with incorrect associated data should fail for AEAD with ID {}",
+                aead.aead_id(),
+            );
+            assert_matches!(
+                aead.open(&key, &ciphertext, None, &nonce),
+                Err(AeadError::InvalidCiphertext),
+                "open with incorrect associated data should fail for AEAD with ID {}",
+                aead.aead_id(),
+            );
+        }
+    }
+
+    #[test]
+    fn invalid_nonce() {
+        for aead in get_aeads() {
+            let key = vec![42u8; aead.key_size()];
+            let data = b"top secret data that's long enough";
+
+            let nonce_short = vec![42u8; aead.nonce_size() - 1];
+            assert_matches!(
+                aead.seal(&key, data, None, &nonce_short),
+                Err(AeadError::InvalidNonceLen { .. }),
+                "seal with short nonce should fail for AEAD with ID {}",
+                aead.aead_id(),
+            );
+            assert_matches!(
+                aead.open(&key, data, None, &nonce_short),
+                Err(AeadError::InvalidNonceLen { .. }),
+                "open with short nonce should fail for AEAD with ID {}",
+                aead.aead_id(),
+            );
+
+            let nonce_long = vec![42u8; aead.nonce_size() + 1];
+            assert_matches!(
+                aead.seal(&key, data, None, &nonce_long),
+                Err(AeadError::InvalidNonceLen { .. }),
+                "seal with long nonce should fail for AEAD with ID {}",
+                aead.aead_id(),
+            );
+            assert_matches!(
+                aead.open(&key, data, None, &nonce_long),
+                Err(AeadError::InvalidNonceLen { .. }),
+                "open with long nonce should fail for AEAD with ID {}",
+                aead.aead_id(),
+            );
+        }
+    }
+}
diff --git a/mls/mls-rs-crypto-boringssl/src/ecdh.rs b/mls/mls-rs-crypto-boringssl/src/ecdh.rs
new file mode 100644
index 0000000..74ba8df
--- /dev/null
+++ b/mls/mls-rs-crypto-boringssl/src/ecdh.rs
@@ -0,0 +1,280 @@
+// Copyright 2024, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Elliptic curve Diffie–Hellman.
+
+use bssl_crypto::x25519;
+use mls_rs_core::crypto::{CipherSuite, HpkePublicKey, HpkeSecretKey};
+use mls_rs_core::error::IntoAnyError;
+use mls_rs_crypto_traits::{Curve, DhType};
+
+use core::array::TryFromSliceError;
+use thiserror::Error;
+
+/// Errors returned from ECDH.
+#[derive(Debug, Error)]
+pub enum EcdhError {
+    /// Error returned when conversion from slice to array fails.
+    #[error(transparent)]
+    TryFromSliceError(#[from] TryFromSliceError),
+    /// Error returned when the public key is invalid.
+    #[error("ECDH public key was invalid")]
+    InvalidPubKey,
+    /// Error returned when the private key length is invalid.
+    #[error("ECDH private key of invalid length {len}, expected length {expected_len}")]
+    InvalidPrivKeyLen {
+        /// Invalid key length.
+        len: usize,
+        /// Expected key length.
+        expected_len: usize,
+    },
+    /// Error returned when the public key length is invalid.
+    #[error("ECDH public key of invalid length {len}, expected length {expected_len}")]
+    InvalidPubKeyLen {
+        /// Invalid key length.
+        len: usize,
+        /// Expected key length.
+        expected_len: usize,
+    },
+    /// Error returned when unsupported cipher suite is requested.
+    #[error("unsupported cipher suite")]
+    UnsupportedCipherSuite,
+}
+
+impl IntoAnyError for EcdhError {
+    fn into_dyn_error(self) -> Result<Box<dyn std::error::Error + Send + Sync>, Self> {
+        Ok(self.into())
+    }
+}
+
+/// DhType implementation backed by BoringSSL.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Ecdh(Curve);
+
+impl Ecdh {
+    /// Creates a new Ecdh.
+    pub fn new(cipher_suite: CipherSuite) -> Option<Self> {
+        Curve::from_ciphersuite(cipher_suite, /*for_sig=*/ false).map(Self)
+    }
+}
+
+#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+#[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))]
+#[cfg_attr(all(not(target_arch = "wasm32"), mls_build_async), maybe_async::must_be_async)]
+impl DhType for Ecdh {
+    type Error = EcdhError;
+
+    async fn dh(
+        &self,
+        secret_key: &HpkeSecretKey,
+        public_key: &HpkePublicKey,
+    ) -> Result<Vec<u8>, Self::Error> {
+        if self.0 != Curve::X25519 {
+            return Err(EcdhError::UnsupportedCipherSuite);
+        }
+        if secret_key.len() != x25519::PRIVATE_KEY_LEN {
+            return Err(EcdhError::InvalidPrivKeyLen {
+                len: secret_key.len(),
+                expected_len: x25519::PRIVATE_KEY_LEN,
+            });
+        }
+        if public_key.len() != x25519::PUBLIC_KEY_LEN {
+            return Err(EcdhError::InvalidPubKeyLen {
+                len: public_key.len(),
+                expected_len: x25519::PUBLIC_KEY_LEN,
+            });
+        }
+
+        let private_key = x25519::PrivateKey(secret_key[..x25519::PRIVATE_KEY_LEN].try_into()?);
+        match private_key.compute_shared_key(public_key[..x25519::PUBLIC_KEY_LEN].try_into()?) {
+            Some(x) => Ok(x.to_vec()),
+            None => Err(EcdhError::InvalidPubKey),
+        }
+    }
+
+    async fn to_public(&self, secret_key: &HpkeSecretKey) -> Result<HpkePublicKey, Self::Error> {
+        if self.0 != Curve::X25519 {
+            return Err(EcdhError::UnsupportedCipherSuite);
+        }
+        if secret_key.len() != x25519::PRIVATE_KEY_LEN {
+            return Err(EcdhError::InvalidPrivKeyLen {
+                len: secret_key.len(),
+                expected_len: x25519::PRIVATE_KEY_LEN,
+            });
+        }
+
+        let private_key = x25519::PrivateKey(secret_key[..x25519::PRIVATE_KEY_LEN].try_into()?);
+        Ok(private_key.to_public().to_vec().into())
+    }
+
+    async fn generate(&self) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error> {
+        if self.0 != Curve::X25519 {
+            return Err(EcdhError::UnsupportedCipherSuite);
+        }
+
+        let (public_key, private_key) = x25519::PrivateKey::generate();
+        Ok((private_key.0.to_vec().into(), public_key.to_vec().into()))
+    }
+
+    fn bitmask_for_rejection_sampling(&self) -> Option<u8> {
+        self.0.curve_bitmask()
+    }
+
+    fn public_key_validate(&self, key: &HpkePublicKey) -> Result<(), Self::Error> {
+        if self.0 != Curve::X25519 {
+            return Err(EcdhError::UnsupportedCipherSuite);
+        }
+
+        // bssl_crypto does not implement validation of curve25519 public keys.
+        // Note: Neither does x25519_dalek used by RustCrypto's implementation of this function.
+        if key.len() != x25519::PUBLIC_KEY_LEN {
+            return Err(EcdhError::InvalidPubKeyLen {
+                len: key.len(),
+                expected_len: x25519::PUBLIC_KEY_LEN,
+            });
+        }
+        Ok(())
+    }
+
+    fn secret_key_size(&self) -> usize {
+        self.0.secret_key_size()
+    }
+}
+
+#[cfg(all(not(mls_build_async), test))]
+mod test {
+    use super::{DhType, Ecdh, EcdhError};
+    use crate::test_helpers::decode_hex;
+    use assert_matches::assert_matches;
+    use mls_rs_core::crypto::{CipherSuite, HpkePublicKey, HpkeSecretKey};
+
+    #[test]
+    fn dh() {
+        // https://github.com/C2SP/wycheproof/blob/cd27d6419bedd83cbd24611ec54b6d4bfdb0cdca/testvectors/x25519_test.json#L23
+        let private_key = HpkeSecretKey::from(
+            decode_hex::<32>("c8a9d5a91091ad851c668b0736c1c9a02936c0d3ad62670858088047ba057475")
+                .to_vec(),
+        );
+        let public_key = HpkePublicKey::from(
+            decode_hex::<32>("504a36999f489cd2fdbc08baff3d88fa00569ba986cba22548ffde80f9806829")
+                .to_vec(),
+        );
+        let expected_shared_secret: [u8; 32] =
+            decode_hex("436a2c040cf45fea9b29a0cb81b1f41458f863d0d61b453d0a982720d6d61320");
+
+        let x25519 = Ecdh::new(CipherSuite::CURVE25519_AES128).unwrap();
+        assert_eq!(x25519.dh(&private_key, &public_key).unwrap(), expected_shared_secret);
+    }
+
+    #[test]
+    fn dh_invalid_key() {
+        let x25519 = Ecdh::new(CipherSuite::CURVE25519_AES128).unwrap();
+
+        let private_key_short =
+            HpkeSecretKey::from(decode_hex::<16>("c8a9d5a91091ad851c668b0736c1c9a0").to_vec());
+        let public_key = HpkePublicKey::from(
+            decode_hex::<32>("504a36999f489cd2fdbc08baff3d88fa00569ba986cba22548ffde80f9806829")
+                .to_vec(),
+        );
+        assert_matches!(
+            x25519.dh(&private_key_short, &public_key),
+            Err(EcdhError::InvalidPrivKeyLen { .. })
+        );
+
+        let private_key = HpkeSecretKey::from(
+            decode_hex::<32>("c8a9d5a91091ad851c668b0736c1c9a02936c0d3ad62670858088047ba057475")
+                .to_vec(),
+        );
+        let public_key_short =
+            HpkePublicKey::from(decode_hex::<16>("504a36999f489cd2fdbc08baff3d88fa").to_vec());
+        assert_matches!(
+            x25519.dh(&private_key, &public_key_short),
+            Err(EcdhError::InvalidPubKeyLen { .. })
+        );
+    }
+
+    #[test]
+    fn to_public() {
+        // https://www.rfc-editor.org/rfc/rfc7748.html#section-6.1
+        let private_key = HpkeSecretKey::from(
+            decode_hex::<32>("77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a")
+                .to_vec(),
+        );
+        let expected_public_key = HpkePublicKey::from(
+            decode_hex::<32>("8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a")
+                .to_vec(),
+        );
+
+        let x25519 = Ecdh::new(CipherSuite::CURVE25519_CHACHA).unwrap();
+        assert_eq!(x25519.to_public(&private_key).unwrap(), expected_public_key);
+    }
+
+    #[test]
+    fn to_public_invalid_key() {
+        let private_key_short =
+            HpkeSecretKey::from(decode_hex::<16>("c8a9d5a91091ad851c668b0736c1c9a0").to_vec());
+
+        let x25519 = Ecdh::new(CipherSuite::CURVE25519_CHACHA).unwrap();
+        assert_matches!(
+            x25519.to_public(&private_key_short),
+            Err(EcdhError::InvalidPrivKeyLen { .. })
+        );
+    }
+
+    #[test]
+    fn generate() {
+        let x25519 = Ecdh::new(CipherSuite::CURVE25519_AES128).unwrap();
+        assert!(x25519.generate().is_ok());
+    }
+
+    #[test]
+    fn public_key_validate() {
+        // https://www.rfc-editor.org/rfc/rfc7748.html#section-6.1
+        let public_key = HpkePublicKey::from(
+            decode_hex::<32>("8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a")
+                .to_vec(),
+        );
+
+        let x25519 = Ecdh::new(CipherSuite::CURVE25519_AES128).unwrap();
+        assert!(x25519.public_key_validate(&public_key).is_ok());
+    }
+
+    #[test]
+    fn public_key_validate_invalid_key() {
+        let public_key_short =
+            HpkePublicKey::from(decode_hex::<16>("504a36999f489cd2fdbc08baff3d88fa").to_vec());
+
+        let x25519 = Ecdh::new(CipherSuite::CURVE25519_AES128).unwrap();
+        assert_matches!(
+            x25519.public_key_validate(&public_key_short),
+            Err(EcdhError::InvalidPubKeyLen { .. })
+        );
+    }
+
+    #[test]
+    fn unsupported_cipher_suites() {
+        for suite in vec![
+            CipherSuite::P256_AES128,
+            CipherSuite::P384_AES256,
+            CipherSuite::P521_AES256,
+            CipherSuite::CURVE448_CHACHA,
+            CipherSuite::CURVE448_AES256,
+        ] {
+            assert_matches!(
+                Ecdh::new(suite).unwrap().generate(),
+                Err(EcdhError::UnsupportedCipherSuite)
+            );
+        }
+    }
+}
diff --git a/mls/mls-rs-crypto-boringssl/src/eddsa.rs b/mls/mls-rs-crypto-boringssl/src/eddsa.rs
new file mode 100644
index 0000000..473b756
--- /dev/null
+++ b/mls/mls-rs-crypto-boringssl/src/eddsa.rs
@@ -0,0 +1,284 @@
+// Copyright 2024, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Edwards-curve digital signature algorithm.
+
+use bssl_crypto::{ed25519, InvalidSignatureError};
+use mls_rs_core::crypto::{CipherSuite, SignaturePublicKey, SignatureSecretKey};
+use mls_rs_crypto_traits::Curve;
+
+use core::array::TryFromSliceError;
+use thiserror::Error;
+
+/// Errors returned from EdDSA.
+#[derive(Debug, Error)]
+pub enum EdDsaError {
+    /// Error returned when conversion from slice to array fails.
+    #[error(transparent)]
+    TryFromSliceError(#[from] TryFromSliceError),
+    /// Error returned on an invalid signature.
+    #[error("invalid signature")]
+    InvalidSig(InvalidSignatureError),
+    /// Error returned when the private key length is invalid.
+    #[error("EdDSA private key of invalid length {len}, expected length {expected_len}")]
+    InvalidPrivKeyLen {
+        /// Invalid key length.
+        len: usize,
+        /// Expected key length.
+        expected_len: usize,
+    },
+    /// Error returned when the public key length is invalid.
+    #[error("EdDSA public key of invalid length {len}, expected length {expected_len}")]
+    InvalidPubKeyLen {
+        /// Invalid key length.
+        len: usize,
+        /// Expected key length.
+        expected_len: usize,
+    },
+    /// Error returned when the signature length is invalid.
+    #[error("EdDSA signature of invalid length {len}, expected length {expected_len}")]
+    InvalidSigLen {
+        /// Invalid signature length.
+        len: usize,
+        /// Expected signature length.
+        expected_len: usize,
+    },
+    /// Error returned when unsupported cipher suite is requested.
+    #[error("unsupported cipher suite")]
+    UnsupportedCipherSuite,
+}
+
+// Explicitly implemented as InvalidSignatureError's as_dyn_error does not satisfy trait bounds.
+impl From<InvalidSignatureError> for EdDsaError {
+    fn from(e: InvalidSignatureError) -> Self {
+        EdDsaError::InvalidSig(e)
+    }
+}
+
+/// EdDSA implementation backed by BoringSSL.
+#[derive(Clone, Debug, Copy, PartialEq, Eq)]
+pub struct EdDsa(Curve);
+
+impl EdDsa {
+    /// Creates a new EdDsa.
+    pub fn new(cipher_suite: CipherSuite) -> Option<Self> {
+        Curve::from_ciphersuite(cipher_suite, /*for_sig=*/ true).map(Self)
+    }
+
+    /// Generates a key pair.
+    pub fn signature_key_generate(
+        &self,
+    ) -> Result<(SignatureSecretKey, SignaturePublicKey), EdDsaError> {
+        if self.0 != Curve::Ed25519 {
+            return Err(EdDsaError::UnsupportedCipherSuite);
+        }
+
+        let private_key = ed25519::PrivateKey::generate();
+        let public_key = private_key.to_public();
+        Ok((private_key.to_seed().to_vec().into(), public_key.as_bytes().to_vec().into()))
+    }
+
+    /// Derives the public key from the private key.
+    pub fn signature_key_derive_public(
+        &self,
+        secret_key: &SignatureSecretKey,
+    ) -> Result<SignaturePublicKey, EdDsaError> {
+        if self.0 != Curve::Ed25519 {
+            return Err(EdDsaError::UnsupportedCipherSuite);
+        }
+        if secret_key.len() != ed25519::SEED_LEN {
+            return Err(EdDsaError::InvalidPrivKeyLen {
+                len: secret_key.len(),
+                expected_len: ed25519::SEED_LEN,
+            });
+        }
+
+        let private_key =
+            ed25519::PrivateKey::from_seed(secret_key[..ed25519::SEED_LEN].try_into()?);
+        Ok(private_key.to_public().as_bytes().to_vec().into())
+    }
+
+    /// Signs `data` using `secret_key`.
+    pub fn sign(
+        &self,
+        secret_key: &SignatureSecretKey,
+        data: &[u8],
+    ) -> Result<Vec<u8>, EdDsaError> {
+        if self.0 != Curve::Ed25519 {
+            return Err(EdDsaError::UnsupportedCipherSuite);
+        }
+        if secret_key.len() != ed25519::SEED_LEN {
+            return Err(EdDsaError::InvalidPrivKeyLen {
+                len: secret_key.len(),
+                expected_len: ed25519::SEED_LEN,
+            });
+        }
+
+        let private_key =
+            ed25519::PrivateKey::from_seed(secret_key[..ed25519::SEED_LEN].try_into()?);
+        Ok(private_key.sign(data).to_vec())
+    }
+
+    /// Verifies `signature` is a valid signature of `data` using `public_key`.
+    pub fn verify(
+        &self,
+        public_key: &SignaturePublicKey,
+        signature: &[u8],
+        data: &[u8],
+    ) -> Result<(), EdDsaError> {
+        if self.0 != Curve::Ed25519 {
+            return Err(EdDsaError::UnsupportedCipherSuite);
+        }
+        if public_key.len() != ed25519::PUBLIC_KEY_LEN {
+            return Err(EdDsaError::InvalidPubKeyLen {
+                len: public_key.len(),
+                expected_len: ed25519::PUBLIC_KEY_LEN,
+            });
+        }
+        if signature.len() != ed25519::SIGNATURE_LEN {
+            return Err(EdDsaError::InvalidSigLen {
+                len: signature.len(),
+                expected_len: ed25519::SIGNATURE_LEN,
+            });
+        }
+
+        let public_key = ed25519::PublicKey::from_bytes(
+            public_key.as_bytes()[..ed25519::PUBLIC_KEY_LEN].try_into()?,
+        );
+        match public_key.verify(data, signature[..ed25519::SIGNATURE_LEN].try_into()?) {
+            Ok(_) => Ok(()),
+            Err(e) => Err(EdDsaError::InvalidSig(e)),
+        }
+    }
+}
+
+#[cfg(all(not(mls_build_async), test))]
+mod test {
+    use super::{EdDsa, EdDsaError};
+    use crate::test_helpers::decode_hex;
+    use assert_matches::assert_matches;
+    use mls_rs_core::crypto::{CipherSuite, SignaturePublicKey, SignatureSecretKey};
+
+    #[test]
+    fn signature_key_generate() {
+        let ed25519 = EdDsa::new(CipherSuite::CURVE25519_AES128).unwrap();
+        assert!(ed25519.signature_key_generate().is_ok());
+    }
+
+    #[test]
+    fn signature_key_derive_public() {
+        // Test 1 from https://www.rfc-editor.org/rfc/rfc8032#section-7.1
+        let private_key = SignatureSecretKey::from(
+            decode_hex::<32>("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60")
+                .to_vec(),
+        );
+        let expected_public_key = SignaturePublicKey::from(
+            decode_hex::<32>("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a")
+                .to_vec(),
+        );
+
+        let ed25519 = EdDsa::new(CipherSuite::CURVE25519_CHACHA).unwrap();
+        assert_eq!(ed25519.signature_key_derive_public(&private_key).unwrap(), expected_public_key);
+    }
+
+    #[test]
+    fn signature_key_derive_public_invalid_key() {
+        let private_key_short =
+            SignatureSecretKey::from(decode_hex::<16>("9d61b19deffd5a60ba844af492ec2cc4").to_vec());
+
+        let ed25519 = EdDsa::new(CipherSuite::CURVE25519_CHACHA).unwrap();
+        assert_matches!(
+            ed25519.signature_key_derive_public(&private_key_short),
+            Err(EdDsaError::InvalidPrivKeyLen { .. })
+        );
+    }
+
+    #[test]
+    fn sign_verify() {
+        // Test 3 from https://www.rfc-editor.org/rfc/rfc8032#section-7.1
+        let private_key = SignatureSecretKey::from(
+            decode_hex::<32>("c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7")
+                .to_vec(),
+        );
+        let data: [u8; 2] = decode_hex("af82");
+        let expected_sig = decode_hex::<64>("6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a").to_vec();
+
+        let ed25519 = EdDsa::new(CipherSuite::CURVE25519_AES128).unwrap();
+        let sig = ed25519.sign(&private_key, &data).unwrap();
+        assert_eq!(sig, expected_sig);
+
+        let public_key = ed25519.signature_key_derive_public(&private_key).unwrap();
+        assert!(ed25519.verify(&public_key, &sig, &data).is_ok());
+    }
+
+    #[test]
+    fn sign_invalid_key() {
+        let private_key_short =
+            SignatureSecretKey::from(decode_hex::<16>("c5aa8df43f9f837bedb7442f31dcb7b1").to_vec());
+
+        let ed25519 = EdDsa::new(CipherSuite::CURVE25519_AES128).unwrap();
+        assert_matches!(
+            ed25519.sign(&private_key_short, &decode_hex::<2>("af82")),
+            Err(EdDsaError::InvalidPrivKeyLen { .. })
+        );
+    }
+
+    #[test]
+    fn verify_invalid_key() {
+        let public_key_short =
+            SignaturePublicKey::from(decode_hex::<16>("fc51cd8e6218a1a38da47ed00230f058").to_vec());
+        let sig = decode_hex::<64>("6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a").to_vec();
+        let data: [u8; 2] = decode_hex("af82");
+
+        let ed25519 = EdDsa::new(CipherSuite::CURVE25519_AES128).unwrap();
+        assert_matches!(
+            ed25519.verify(&public_key_short, &sig, &data),
+            Err(EdDsaError::InvalidPubKeyLen { .. })
+        );
+    }
+
+    #[test]
+    fn verify_invalid_sig() {
+        let public_key = SignaturePublicKey::from(
+            decode_hex::<32>("fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025")
+                .to_vec(),
+        );
+        let sig_short =
+            decode_hex::<32>("6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac")
+                .to_vec();
+        let data: [u8; 2] = decode_hex("af82");
+
+        let ed25519 = EdDsa::new(CipherSuite::CURVE25519_AES128).unwrap();
+        assert_matches!(
+            ed25519.verify(&public_key, &sig_short, &data),
+            Err(EdDsaError::InvalidSigLen { .. })
+        );
+    }
+
+    #[test]
+    fn unsupported_cipher_suites() {
+        for suite in vec![
+            CipherSuite::P256_AES128,
+            CipherSuite::P384_AES256,
+            CipherSuite::P521_AES256,
+            CipherSuite::CURVE448_CHACHA,
+            CipherSuite::CURVE448_AES256,
+        ] {
+            assert_matches!(
+                EdDsa::new(suite).unwrap().signature_key_generate(),
+                Err(EdDsaError::UnsupportedCipherSuite)
+            );
+        }
+    }
+}
diff --git a/mls/mls-rs-crypto-boringssl/src/hash.rs b/mls/mls-rs-crypto-boringssl/src/hash.rs
new file mode 100644
index 0000000..397fb9d
--- /dev/null
+++ b/mls/mls-rs-crypto-boringssl/src/hash.rs
@@ -0,0 +1,152 @@
+// Copyright 2024, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Hash functions and hash-based message authentication codes.
+
+use bssl_crypto::digest;
+use bssl_crypto::hmac::{HmacSha256, HmacSha512};
+use mls_rs_core::crypto::CipherSuite;
+use thiserror::Error;
+
+/// Errors returned from hash functions and HMACs.
+#[derive(Debug, Error)]
+pub enum HashError {
+    /// Error returned when unsupported cipher suite is requested.
+    #[error("unsupported cipher suite")]
+    UnsupportedCipherSuite,
+}
+
+/// Hash function and HMAC implementations backed by BoringSSL.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+#[repr(u16)]
+pub enum Hash {
+    /// SHA-256.
+    Sha256,
+    /// SHA-384.
+    Sha384,
+    /// SHA-512.
+    Sha512,
+}
+
+impl Hash {
+    /// Creates a new Hash.
+    pub fn new(cipher_suite: CipherSuite) -> Result<Self, HashError> {
+        match cipher_suite {
+            CipherSuite::CURVE25519_AES128
+            | CipherSuite::P256_AES128
+            | CipherSuite::CURVE25519_CHACHA => Ok(Hash::Sha256),
+            CipherSuite::P384_AES256 => Ok(Hash::Sha384),
+            CipherSuite::CURVE448_AES256
+            | CipherSuite::CURVE448_CHACHA
+            | CipherSuite::P521_AES256 => Ok(Hash::Sha512),
+            _ => Err(HashError::UnsupportedCipherSuite),
+        }
+    }
+
+    /// Hashes `data`.
+    pub fn hash(&self, data: &[u8]) -> Vec<u8> {
+        match self {
+            Hash::Sha256 => digest::Sha256::hash(data).to_vec(),
+            Hash::Sha384 => digest::Sha384::hash(data).to_vec(),
+            Hash::Sha512 => digest::Sha512::hash(data).to_vec(),
+        }
+    }
+
+    /// Computes the HMAC of `data` using `key`.
+    pub fn mac(&self, key: &[u8], data: &[u8]) -> Result<Vec<u8>, HashError> {
+        match self {
+            Hash::Sha256 => Ok(HmacSha256::mac(key, data).to_vec()),
+            Hash::Sha384 => Err(HashError::UnsupportedCipherSuite),
+            Hash::Sha512 => Ok(HmacSha512::mac(key, data).to_vec()),
+        }
+    }
+}
+
+#[cfg(all(not(mls_build_async), test))]
+mod test {
+    use super::{Hash, HashError};
+    use crate::test_helpers::decode_hex;
+    use assert_matches::assert_matches;
+    use mls_rs_core::crypto::CipherSuite;
+
+    // bssl_crypto::hmac test vectors.
+
+    #[test]
+    fn sha256() {
+        let hash = Hash::new(CipherSuite::P256_AES128).unwrap();
+        assert_eq!(
+            hash.hash(&decode_hex::<4>("74ba2521")),
+            decode_hex::<32>("b16aa56be3880d18cd41e68384cf1ec8c17680c45a02b1575dc1518923ae8b0e")
+        );
+    }
+
+    #[test]
+    fn sha384() {
+        let hash = Hash::new(CipherSuite::P384_AES256).unwrap();
+        assert_eq!(
+            hash.hash(b"abc"),
+            decode_hex::<48>("cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7")
+        );
+    }
+
+    #[test]
+    fn sha512() {
+        let hash = Hash::new(CipherSuite::CURVE448_CHACHA).unwrap();
+        assert_eq!(
+            hash.hash(&decode_hex::<4>("23be86d5")),
+            decode_hex::<64>(concat!(
+                "76d42c8eadea35a69990c63a762f330614a4699977f058adb988f406fb0be8f2",
+                "ea3dce3a2bbd1d827b70b9b299ae6f9e5058ee97b50bd4922d6d37ddc761f8eb"
+            ))
+        );
+    }
+
+    #[test]
+    fn hmac_sha256() {
+        let expected = vec![
+            0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0xb,
+            0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x0, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c,
+            0x2e, 0x32, 0xcf, 0xf7,
+        ];
+        let key: [u8; 20] = [0x0b; 20];
+        let data = b"Hi There";
+
+        let hmac = Hash::new(CipherSuite::CURVE25519_AES128).unwrap();
+        assert_eq!(expected, hmac.mac(&key, data).unwrap());
+    }
+
+    #[test]
+    fn hmac_sha384() {
+        let key: [u8; 20] = [0x0b; 20];
+        let data = b"Hi There";
+
+        let hmac = Hash::new(CipherSuite::P384_AES256).unwrap();
+        assert_matches!(hmac.mac(&key, data), Err(HashError::UnsupportedCipherSuite));
+    }
+
+    #[test]
+    fn hmac_sha512() {
+        let expected = vec![
+            135, 170, 124, 222, 165, 239, 97, 157, 79, 240, 180, 36, 26, 29, 108, 176, 35, 121,
+            244, 226, 206, 78, 194, 120, 122, 208, 179, 5, 69, 225, 124, 222, 218, 168, 51, 183,
+            214, 184, 167, 2, 3, 139, 39, 78, 174, 163, 244, 228, 190, 157, 145, 78, 235, 97, 241,
+            112, 46, 105, 108, 32, 58, 18, 104, 84,
+        ];
+        let key: [u8; 20] = [0x0b; 20];
+        let data = b"Hi There";
+
+        let hmac = Hash::new(CipherSuite::CURVE448_CHACHA).unwrap();
+        assert_eq!(expected, hmac.mac(&key, data).unwrap());
+    }
+}
diff --git a/mls/mls-rs-crypto-boringssl/src/hpke.rs b/mls/mls-rs-crypto-boringssl/src/hpke.rs
new file mode 100644
index 0000000..4bb4aa2
--- /dev/null
+++ b/mls/mls-rs-crypto-boringssl/src/hpke.rs
@@ -0,0 +1,541 @@
+// Copyright 2024, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Hybrid public key encryption.
+
+use bssl_crypto::hpke;
+use mls_rs_core::crypto::{
+    CipherSuite, HpkeCiphertext, HpkeContextR, HpkeContextS, HpkePublicKey, HpkeSecretKey,
+};
+use mls_rs_core::error::{AnyError, IntoAnyError};
+use mls_rs_crypto_traits::{DhType, KdfType, KemId, KemResult, KemType};
+use std::sync::Mutex;
+use thiserror::Error;
+
+/// Errors returned from HPKE.
+#[derive(Debug, Error)]
+pub enum HpkeError {
+    /// Error returned from BoringSSL.
+    #[error("BoringSSL error")]
+    BoringsslError,
+    /// Error returned from Diffie-Hellman operations.
+    #[error(transparent)]
+    DhError(AnyError),
+    /// Error returned from KDF operations.
+    #[error(transparent)]
+    KdfError(AnyError),
+    /// Error returned when unsupported cipher suite is requested.
+    #[error("unsupported cipher suite")]
+    UnsupportedCipherSuite,
+}
+
+impl IntoAnyError for HpkeError {
+    fn into_dyn_error(self) -> Result<Box<dyn std::error::Error + Send + Sync>, Self> {
+        Ok(self.into())
+    }
+}
+
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub(crate) struct KdfWrapper<KDF: KdfType> {
+    suite_id: Vec<u8>,
+    kdf: KDF,
+}
+
+impl<KDF: KdfType> KdfWrapper<KDF> {
+    pub fn new(suite_id: Vec<u8>, kdf: KDF) -> Self {
+        Self { suite_id, kdf }
+    }
+
+    // https://www.rfc-editor.org/rfc/rfc9180.html#section-4-9
+    #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+    pub async fn labeled_extract(
+        &self,
+        salt: &[u8],
+        label: &[u8],
+        ikm: &[u8],
+    ) -> Result<Vec<u8>, <KDF as KdfType>::Error> {
+        self.kdf.extract(salt, &[b"HPKE-v1" as &[u8], &self.suite_id, label, ikm].concat()).await
+    }
+
+    // https://www.rfc-editor.org/rfc/rfc9180.html#section-4-9
+    #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+    pub async fn labeled_expand(
+        &self,
+        key: &[u8],
+        label: &[u8],
+        info: &[u8],
+        len: usize,
+    ) -> Result<Vec<u8>, <KDF as KdfType>::Error> {
+        let labeled_info =
+            [&(len as u16).to_be_bytes() as &[u8], b"HPKE-v1", &self.suite_id, label, info]
+                .concat();
+        self.kdf.expand(key, &labeled_info, len).await
+    }
+}
+
+/// KemType implementation backed by BoringSSL.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct DhKem<DH: DhType, KDF: KdfType> {
+    dh: DH,
+    kdf: KdfWrapper<KDF>,
+    kem_id: KemId,
+    n_secret: usize,
+}
+
+impl<DH: DhType, KDF: KdfType> DhKem<DH, KDF> {
+    /// Creates a new DhKem.
+    pub fn new(cipher_suite: CipherSuite, dh: DH, kdf: KDF) -> Option<Self> {
+        // https://www.rfc-editor.org/rfc/rfc9180.html#section-4.1-5
+        let kem_id = KemId::new(cipher_suite)?;
+        let suite_id = [b"KEM", &(kem_id as u16).to_be_bytes() as &[u8]].concat();
+
+        let kdf = KdfWrapper::new(suite_id, kdf);
+
+        Some(Self { dh, kdf, kem_id, n_secret: kem_id.n_secret() })
+    }
+}
+
+#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+#[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))]
+#[cfg_attr(all(not(target_arch = "wasm32"), mls_build_async), maybe_async::must_be_async)]
+impl<DH: DhType, KDF: KdfType> KemType for DhKem<DH, KDF> {
+    type Error = HpkeError;
+
+    fn kem_id(&self) -> u16 {
+        self.kem_id as u16
+    }
+
+    async fn generate(&self) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error> {
+        if self.kem_id != KemId::DhKemX25519Sha256 {
+            return Err(HpkeError::UnsupportedCipherSuite);
+        }
+
+        let kem = hpke::Kem::X25519HkdfSha256;
+        let (public_key, private_key) = kem.generate_keypair();
+        Ok((private_key.to_vec().into(), public_key.to_vec().into()))
+    }
+
+    // https://www.rfc-editor.org/rfc/rfc9180.html#section-7.1.3-8
+    async fn derive(&self, ikm: &[u8]) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error> {
+        let dkp_prk = match self.kdf.labeled_extract(&[], b"dkp_prk", ikm).await {
+            Ok(p) => p,
+            Err(e) => return Err(HpkeError::KdfError(e.into_any_error())),
+        };
+        let sk =
+            match self.kdf.labeled_expand(&dkp_prk, b"sk", &[], self.dh.secret_key_size()).await {
+                Ok(s) => s.into(),
+                Err(e) => return Err(HpkeError::KdfError(e.into_any_error())),
+            };
+        let pk = match self.dh.to_public(&sk).await {
+            Ok(p) => p,
+            Err(e) => return Err(HpkeError::KdfError(e.into_any_error())),
+        };
+        Ok((sk, pk))
+    }
+
+    fn public_key_validate(&self, key: &HpkePublicKey) -> Result<(), Self::Error> {
+        match self.dh.public_key_validate(key) {
+            Ok(_) => Ok(()),
+            Err(e) => Err(HpkeError::DhError(e.into_any_error())),
+        }
+    }
+
+    // Using BoringSSL's HPKE implementation so this is not needed.
+    async fn encap(&self, _remote_pk: &HpkePublicKey) -> Result<KemResult, Self::Error> {
+        unimplemented!();
+    }
+
+    // Using BoringSSL's HPKE implementation so this is not needed.
+    async fn decap(
+        &self,
+        _enc: &[u8],
+        _secret_key: &HpkeSecretKey,
+        _public_key: &HpkePublicKey,
+    ) -> Result<Vec<u8>, Self::Error> {
+        unimplemented!();
+    }
+}
+
+/// HpkeContextS implementation backed by BoringSSL.
+pub struct ContextS(pub Mutex<hpke::SenderContext>);
+
+#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+#[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))]
+#[cfg_attr(all(not(target_arch = "wasm32"), mls_build_async), maybe_async::must_be_async)]
+impl HpkeContextS for ContextS {
+    type Error = HpkeError;
+
+    #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+    async fn seal(&mut self, aad: Option<&[u8]>, data: &[u8]) -> Result<Vec<u8>, Self::Error> {
+        Ok(self.0.lock().unwrap().seal(data, aad.unwrap_or_default()))
+    }
+
+    #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+    async fn export(&self, exporter_context: &[u8], len: usize) -> Result<Vec<u8>, Self::Error> {
+        Ok(self.0.lock().unwrap().export(exporter_context, len).to_vec())
+    }
+}
+
+/// HpkeContextR implementation backed by BoringSSL.
+pub struct ContextR(pub Mutex<hpke::RecipientContext>);
+
+#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+#[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))]
+#[cfg_attr(all(not(target_arch = "wasm32"), mls_build_async), maybe_async::must_be_async)]
+impl HpkeContextR for ContextR {
+    type Error = HpkeError;
+
+    #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+    async fn open(
+        &mut self,
+        aad: Option<&[u8]>,
+        ciphertext: &[u8],
+    ) -> Result<Vec<u8>, Self::Error> {
+        self.0
+            .lock()
+            .unwrap()
+            .open(ciphertext, aad.unwrap_or_default())
+            .ok_or(HpkeError::BoringsslError)
+    }
+
+    #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+    async fn export(&self, exporter_context: &[u8], len: usize) -> Result<Vec<u8>, Self::Error> {
+        Ok(self.0.lock().unwrap().export(exporter_context, len).to_vec())
+    }
+}
+
+/// HPKE implementation backed by BoringSSL.
+#[derive(Clone)]
+pub struct Hpke(pub CipherSuite);
+
+impl Hpke {
+    /// Creates a new Hpke.
+    pub fn new(cipher_suite: CipherSuite) -> Self {
+        Self(cipher_suite)
+    }
+
+    /// Sets up HPKE sender context.
+    #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+    pub async fn setup_sender(
+        &self,
+        remote_key: &HpkePublicKey,
+        info: &[u8],
+    ) -> Result<(Vec<u8>, ContextS), HpkeError> {
+        let params = Self::cipher_suite_to_params(self.0)?;
+        match hpke::SenderContext::new(&params, remote_key, info) {
+            Some((ctx, encapsulated_key)) => Ok((encapsulated_key, ContextS(ctx.into()))),
+            None => Err(HpkeError::BoringsslError),
+        }
+    }
+
+    /// Sets up HPKE sender context and encrypts `pt` with optional associated data `aad`.
+    #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+    pub async fn seal(
+        &self,
+        remote_key: &HpkePublicKey,
+        info: &[u8],
+        aad: Option<&[u8]>,
+        pt: &[u8],
+    ) -> Result<HpkeCiphertext, HpkeError> {
+        let (kem_output, mut ctx) = self.setup_sender(remote_key, info).await?;
+        Ok(HpkeCiphertext { kem_output, ciphertext: ctx.seal(aad, pt).await? })
+    }
+
+    /// Sets up HPKE receiver context.
+    #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+    pub async fn setup_receiver(
+        &self,
+        enc: &[u8],
+        local_secret: &HpkeSecretKey,
+        info: &[u8],
+    ) -> Result<ContextR, HpkeError> {
+        let params = Self::cipher_suite_to_params(self.0)?;
+        match hpke::RecipientContext::new(&params, local_secret, enc, info) {
+            Some(ctx) => Ok(ContextR(ctx.into())),
+            None => Err(HpkeError::BoringsslError),
+        }
+    }
+
+    /// Sets up HPKE receiver context and decrypts `ciphertext` with optional associated data `aad`.
+    #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+    pub async fn open(
+        &self,
+        ciphertext: &HpkeCiphertext,
+        local_secret: &HpkeSecretKey,
+        info: &[u8],
+        aad: Option<&[u8]>,
+    ) -> Result<Vec<u8>, HpkeError> {
+        let mut ctx = self.setup_receiver(&ciphertext.kem_output, local_secret, info).await?;
+        ctx.open(aad, &ciphertext.ciphertext).await
+    }
+
+    fn cipher_suite_to_params(cipher_suite: CipherSuite) -> Result<hpke::Params, HpkeError> {
+        match cipher_suite {
+            CipherSuite::CURVE25519_AES128 => Ok(hpke::Params::new(
+                hpke::Kem::X25519HkdfSha256,
+                hpke::Kdf::HkdfSha256,
+                hpke::Aead::Aes128Gcm,
+            )),
+            CipherSuite::CURVE25519_CHACHA => Ok(hpke::Params::new(
+                hpke::Kem::X25519HkdfSha256,
+                hpke::Kdf::HkdfSha256,
+                hpke::Aead::Chacha20Poly1305,
+            )),
+            _ => Err(HpkeError::UnsupportedCipherSuite),
+        }
+    }
+}
+
+#[cfg(all(not(mls_build_async), test))]
+mod test {
+    use super::{DhKem, Hpke, KdfWrapper};
+    use crate::ecdh::Ecdh;
+    use crate::kdf::Kdf;
+    use crate::test_helpers::decode_hex;
+    use mls_rs_core::crypto::{
+        CipherSuite, HpkeContextR, HpkeContextS, HpkePublicKey, HpkeSecretKey,
+    };
+    use mls_rs_crypto_traits::{AeadId, KdfId, KemId, KemType};
+    use std::thread;
+
+    // https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1-8
+    fn hpke_suite_id(cipher_suite: CipherSuite) -> Vec<u8> {
+        [
+            b"HPKE",
+            &(KemId::new(cipher_suite).unwrap() as u16).to_be_bytes() as &[u8],
+            &(KdfId::new(cipher_suite).unwrap() as u16).to_be_bytes() as &[u8],
+            &(AeadId::new(cipher_suite).unwrap() as u16).to_be_bytes() as &[u8],
+        ]
+        .concat()
+    }
+
+    #[test]
+    fn kdf_labeled_extract() {
+        let cipher_suite = CipherSuite::CURVE25519_AES128;
+        let suite_id = hpke_suite_id(cipher_suite);
+        let kdf = KdfWrapper::new(suite_id, Kdf::new(cipher_suite).unwrap());
+
+        // https://www.rfc-editor.org/rfc/rfc9180.html#appendix-A.1.1
+        let shared_secret: [u8; 32] =
+            decode_hex("fe0e18c9f024ce43799ae393c7e8fe8fce9d218875e8227b0187c04e7d2ea1fc");
+        let expected_secret: [u8; 32] =
+            decode_hex("12fff91991e93b48de37e7daddb52981084bd8aa64289c3788471d9a9712f397");
+        let label = b"secret";
+
+        let secret = kdf.labeled_extract(&shared_secret, label, &[]).unwrap();
+        assert_eq!(secret, expected_secret);
+    }
+
+    #[test]
+    fn kdf_labeled_expand() {
+        let cipher_suite = CipherSuite::CURVE25519_AES128;
+        let suite_id = hpke_suite_id(cipher_suite);
+        let kdf = KdfWrapper::new(suite_id, Kdf::new(cipher_suite).unwrap());
+
+        // https://www.rfc-editor.org/rfc/rfc9180.html#appendix-A.1.1
+        let secret: [u8; 32] =
+            decode_hex("12fff91991e93b48de37e7daddb52981084bd8aa64289c3788471d9a9712f397");
+        let key_schedule_ctx : [u8; 65] = decode_hex("00725611c9d98c07c03f60095cd32d400d8347d45ed67097bbad50fc56da742d07cb6cffde367bb0565ba28bb02c90744a20f5ef37f30523526106f637abb05449");
+        let expected_key: [u8; 16] = decode_hex("4531685d41d65f03dc48f6b8302c05b0");
+        let label = b"key";
+
+        let key = kdf.labeled_expand(&secret, label, &key_schedule_ctx, 16).unwrap();
+        assert_eq!(key, expected_key);
+    }
+
+    #[test]
+    fn dh_kem_kem_id() {
+        let cipher_suite = CipherSuite::CURVE25519_CHACHA;
+        let dh = Ecdh::new(cipher_suite).unwrap();
+        let kdf = Kdf::new(cipher_suite).unwrap();
+        let kem = DhKem::new(cipher_suite, dh, kdf).unwrap();
+
+        assert_eq!(kem.kem_id(), 32);
+    }
+
+    #[test]
+    fn dh_kem_generate() {
+        let cipher_suite = CipherSuite::CURVE25519_AES128;
+        let dh = Ecdh::new(cipher_suite).unwrap();
+        let kdf = Kdf::new(cipher_suite).unwrap();
+        let kem = DhKem::new(cipher_suite, dh, kdf).unwrap();
+
+        assert!(kem.generate().is_ok());
+    }
+
+    #[test]
+    fn dh_kem_derive() {
+        let cipher_suite = CipherSuite::CURVE25519_CHACHA;
+        let dh = Ecdh::new(cipher_suite).unwrap();
+        let kdf = Kdf::new(cipher_suite).unwrap();
+        let kem = DhKem::new(cipher_suite, dh, kdf).unwrap();
+
+        // https://www.rfc-editor.org/rfc/rfc9180.html#appendix-A.2.1
+        let ikm: [u8; 32] =
+            decode_hex("909a9b35d3dc4713a5e72a4da274b55d3d3821a37e5d099e74a647db583a904b"); // ikmE
+        let expected_sk = HpkeSecretKey::from(
+            decode_hex::<32>("f4ec9b33b792c372c1d2c2063507b684ef925b8c75a42dbcbf57d63ccd381600")
+                .to_vec(),
+        ); // skEm
+        let expected_pk = HpkePublicKey::from(
+            decode_hex::<32>("1afa08d3dec047a643885163f1180476fa7ddb54c6a8029ea33f95796bf2ac4a")
+                .to_vec(),
+        ); // pkEm
+
+        let (sk, pk) = kem.derive(&ikm).unwrap();
+        assert_eq!(sk, expected_sk);
+        assert_eq!(pk, expected_pk);
+    }
+
+    #[test]
+    fn dh_kem_public_key_validate() {
+        let cipher_suite = CipherSuite::CURVE25519_AES128;
+        let dh = Ecdh::new(cipher_suite).unwrap();
+        let kdf = Kdf::new(cipher_suite).unwrap();
+        let kem = DhKem::new(cipher_suite, dh, kdf).unwrap();
+
+        // https://www.rfc-editor.org/rfc/rfc7748.html#section-6.1
+        let public_key = HpkePublicKey::from(
+            decode_hex::<32>("8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a")
+                .to_vec(),
+        );
+        assert!(kem.public_key_validate(&public_key).is_ok());
+    }
+
+    #[test]
+    fn hpke_seal_open() {
+        let hpke = Hpke::new(CipherSuite::CURVE25519_AES128);
+
+        // https://www.rfc-editor.org/rfc/rfc9180.html#appendix-A.1.1
+        let receiver_pub_key = HpkePublicKey::from(
+            decode_hex::<32>("3948cfe0ad1ddb695d780e59077195da6c56506b027329794ab02bca80815c4d")
+                .to_vec(),
+        );
+        let receiver_priv_key = HpkeSecretKey::from(
+            decode_hex::<32>("4612c550263fc8ad58375df3f557aac531d26850903e55a9f23f21d8534e8ac8")
+                .to_vec(),
+        );
+
+        let info = b"some_info";
+        let plaintext = b"plaintext";
+        let associated_data = b"some_ad";
+
+        let ct = hpke.seal(&receiver_pub_key, info, Some(associated_data), plaintext).unwrap();
+        assert_eq!(
+            plaintext.as_ref(),
+            hpke.open(&ct, &receiver_priv_key, info, Some(associated_data)).unwrap(),
+        );
+    }
+
+    #[test]
+    fn hpke_context_seal_open() {
+        let hpke = Hpke::new(CipherSuite::CURVE25519_AES128);
+
+        // https://www.rfc-editor.org/rfc/rfc9180.html#appendix-A.1.1
+        let receiver_pub_key = HpkePublicKey::from(
+            decode_hex::<32>("3948cfe0ad1ddb695d780e59077195da6c56506b027329794ab02bca80815c4d")
+                .to_vec(),
+        );
+        let receiver_priv_key = HpkeSecretKey::from(
+            decode_hex::<32>("4612c550263fc8ad58375df3f557aac531d26850903e55a9f23f21d8534e8ac8")
+                .to_vec(),
+        );
+
+        let info = b"some_info";
+        let plaintext = b"plaintext";
+        let associated_data = b"some_ad";
+
+        let (enc, mut sender_ctx) = hpke.setup_sender(&receiver_pub_key, info).unwrap();
+        let mut receiver_ctx = hpke.setup_receiver(&enc, &receiver_priv_key, info).unwrap();
+        let ct = sender_ctx.seal(Some(associated_data), plaintext).unwrap();
+        assert_eq!(plaintext.as_ref(), receiver_ctx.open(Some(associated_data), &ct).unwrap(),);
+    }
+
+    #[test]
+    fn hpke_context_seal_open_multithreaded() {
+        let hpke = Hpke::new(CipherSuite::CURVE25519_AES128);
+
+        // https://www.rfc-editor.org/rfc/rfc9180.html#appendix-A.1.1
+        let receiver_pub_key = HpkePublicKey::from(
+            decode_hex::<32>("3948cfe0ad1ddb695d780e59077195da6c56506b027329794ab02bca80815c4d")
+                .to_vec(),
+        );
+        let receiver_priv_key = HpkeSecretKey::from(
+            decode_hex::<32>("4612c550263fc8ad58375df3f557aac531d26850903e55a9f23f21d8534e8ac8")
+                .to_vec(),
+        );
+
+        let info = b"some_info";
+        let plaintext = b"plaintext";
+        let associated_data = b"some_ad";
+
+        let (enc, mut sender_ctx) = hpke.setup_sender(&receiver_pub_key, info).unwrap();
+        let mut receiver_ctx = hpke.setup_receiver(&enc, &receiver_priv_key, info).unwrap();
+
+        let pool = thread::spawn(move || {
+            for _ in 1..100 {
+                let ct = sender_ctx.seal(Some(associated_data), plaintext).unwrap();
+                assert_eq!(
+                    plaintext.as_ref(),
+                    receiver_ctx.open(Some(associated_data), &ct).unwrap(),
+                );
+            }
+        });
+        pool.join().unwrap();
+    }
+
+    #[test]
+    fn hpke_context_export() {
+        let hpke = Hpke::new(CipherSuite::CURVE25519_AES128);
+
+        // https://www.rfc-editor.org/rfc/rfc9180.html#appendix-A.1.1
+        let receiver_pub_key = HpkePublicKey::from(
+            decode_hex::<32>("3948cfe0ad1ddb695d780e59077195da6c56506b027329794ab02bca80815c4d")
+                .to_vec(),
+        );
+        let receiver_priv_key = HpkeSecretKey::from(
+            decode_hex::<32>("4612c550263fc8ad58375df3f557aac531d26850903e55a9f23f21d8534e8ac8")
+                .to_vec(),
+        );
+
+        let info = b"some_info";
+        let exporter_ctx = b"export_ctx";
+
+        let (enc, sender_ctx) = hpke.setup_sender(&receiver_pub_key, info).unwrap();
+        let receiver_ctx = hpke.setup_receiver(&enc, &receiver_priv_key, info).unwrap();
+        assert_eq!(
+            sender_ctx.export(exporter_ctx, 32).unwrap(),
+            receiver_ctx.export(exporter_ctx, 32).unwrap(),
+        );
+    }
+
+    #[test]
+    fn hpke_unsupported_cipher_suites() {
+        // https://www.rfc-editor.org/rfc/rfc9180.html#appendix-A.1.1
+        let receiver_pub_key = HpkePublicKey::from(
+            decode_hex::<32>("3948cfe0ad1ddb695d780e59077195da6c56506b027329794ab02bca80815c4d")
+                .to_vec(),
+        );
+
+        for suite in vec![
+            CipherSuite::P256_AES128,
+            CipherSuite::P384_AES256,
+            CipherSuite::P521_AES256,
+            CipherSuite::CURVE448_CHACHA,
+            CipherSuite::CURVE448_AES256,
+        ] {
+            assert!(Hpke::new(suite).setup_sender(&receiver_pub_key, b"some_info").is_err());
+        }
+    }
+}
diff --git a/mls/mls-rs-crypto-boringssl/src/kdf.rs b/mls/mls-rs-crypto-boringssl/src/kdf.rs
new file mode 100644
index 0000000..6b88d37
--- /dev/null
+++ b/mls/mls-rs-crypto-boringssl/src/kdf.rs
@@ -0,0 +1,250 @@
+// Copyright 2024, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Key derivation function.
+
+use bssl_crypto::digest;
+use bssl_crypto::hkdf::{HkdfSha256, HkdfSha512, Prk, Salt};
+use mls_rs_core::crypto::CipherSuite;
+use mls_rs_core::error::IntoAnyError;
+use mls_rs_crypto_traits::{KdfId, KdfType};
+use thiserror::Error;
+
+/// Errors returned from KDF.
+#[derive(Debug, Error)]
+pub enum KdfError {
+    /// Error returned when the input key material (IKM) is too short.
+    #[error("KDF IKM of length {len}, expected length at least {min_len}")]
+    TooShortIkm {
+        /// Invalid IKM length.
+        len: usize,
+        /// Minimum IKM length.
+        min_len: usize,
+    },
+    /// Error returned when the pseudorandom key (PRK) is too short.
+    #[error("KDF PRK of length {len}, expected length at least {min_len}")]
+    TooShortPrk {
+        /// Invalid PRK length.
+        len: usize,
+        /// Minimum PRK length.
+        min_len: usize,
+    },
+    /// Error returned when the output key material (OKM) requested it too long.
+    #[error("KDF OKM of length {len} requested, expected length at most {max_len}")]
+    TooLongOkm {
+        /// Invalid OKM length.
+        len: usize,
+        /// Maximum OKM length.
+        max_len: usize,
+    },
+    /// Error returned when unsupported cipher suite is requested.
+    #[error("unsupported cipher suite")]
+    UnsupportedCipherSuite,
+}
+
+impl IntoAnyError for KdfError {
+    fn into_dyn_error(self) -> Result<Box<dyn std::error::Error + Send + Sync>, Self> {
+        Ok(self.into())
+    }
+}
+
+/// KdfType implementation backed by BoringSSL.
+#[derive(Clone)]
+pub struct Kdf(KdfId);
+
+impl Kdf {
+    /// Creates a new Kdf.
+    pub fn new(cipher_suite: CipherSuite) -> Option<Self> {
+        KdfId::new(cipher_suite).map(Self)
+    }
+}
+
+#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+#[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))]
+#[cfg_attr(all(not(target_arch = "wasm32"), mls_build_async), maybe_async::must_be_async)]
+impl KdfType for Kdf {
+    type Error = KdfError;
+
+    async fn extract(&self, salt: &[u8], ikm: &[u8]) -> Result<Vec<u8>, KdfError> {
+        if ikm.is_empty() {
+            return Err(KdfError::TooShortIkm { len: 0, min_len: 1 });
+        }
+
+        let salt = if salt.is_empty() { Salt::None } else { Salt::NonEmpty(salt) };
+
+        match self.0 {
+            KdfId::HkdfSha256 => {
+                Ok(HkdfSha256::extract(ikm, salt).as_bytes()[..self.extract_size()].to_vec())
+            }
+            KdfId::HkdfSha512 => {
+                Ok(HkdfSha512::extract(ikm, salt).as_bytes()[..self.extract_size()].to_vec())
+            }
+            _ => Err(KdfError::UnsupportedCipherSuite),
+        }
+    }
+
+    async fn expand(&self, prk: &[u8], info: &[u8], len: usize) -> Result<Vec<u8>, KdfError> {
+        if prk.len() < self.extract_size() {
+            return Err(KdfError::TooShortPrk { len: prk.len(), min_len: self.extract_size() });
+        }
+
+        match self.0 {
+            KdfId::HkdfSha256 => match Prk::new::<digest::Sha256>(prk) {
+                Some(hkdf) => {
+                    let mut out = vec![0; len];
+                    match hkdf.expand_into(info, &mut out) {
+                        Ok(_) => Ok(out),
+                        Err(_) => {
+                            Err(KdfError::TooLongOkm { len, max_len: HkdfSha256::MAX_OUTPUT_LEN })
+                        }
+                    }
+                }
+                None => Err(KdfError::TooShortPrk { len: prk.len(), min_len: self.extract_size() }),
+            },
+            KdfId::HkdfSha512 => match Prk::new::<digest::Sha512>(prk) {
+                Some(hkdf) => {
+                    let mut out = vec![0; len];
+                    match hkdf.expand_into(info, &mut out) {
+                        Ok(_) => Ok(out),
+                        Err(_) => {
+                            Err(KdfError::TooLongOkm { len, max_len: HkdfSha512::MAX_OUTPUT_LEN })
+                        }
+                    }
+                }
+                None => Err(KdfError::TooShortPrk { len: prk.len(), min_len: self.extract_size() }),
+            },
+            _ => Err(KdfError::UnsupportedCipherSuite),
+        }
+    }
+
+    fn extract_size(&self) -> usize {
+        self.0.extract_size()
+    }
+
+    fn kdf_id(&self) -> u16 {
+        self.0 as u16
+    }
+}
+
+#[cfg(all(not(mls_build_async), test))]
+mod test {
+    use super::{Kdf, KdfError, KdfType};
+    use crate::test_helpers::decode_hex;
+    use assert_matches::assert_matches;
+    use bssl_crypto::hkdf::{HkdfSha256, HkdfSha512};
+    use mls_rs_core::crypto::CipherSuite;
+
+    #[test]
+    fn sha256() {
+        // https://www.rfc-editor.org/rfc/rfc5869.html#appendix-A.1
+        let salt: [u8; 13] = decode_hex("000102030405060708090a0b0c");
+        let ikm: [u8; 22] = decode_hex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
+        let info: [u8; 10] = decode_hex("f0f1f2f3f4f5f6f7f8f9");
+        let expected_prk: [u8; 32] =
+            decode_hex("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5");
+        let expected_okm: [u8; 42] = decode_hex(
+            "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865",
+        );
+
+        let kdf = Kdf::new(CipherSuite::CURVE25519_AES128).unwrap();
+        let prk = kdf.extract(&salt, &ikm).unwrap();
+        assert_eq!(prk, expected_prk);
+        assert_eq!(kdf.expand(&prk, &info, 42).unwrap(), expected_okm);
+    }
+
+    #[test]
+    fn sha512() {
+        // https://github.com/C2SP/wycheproof/blob/cd27d6419bedd83cbd24611ec54b6d4bfdb0cdca/testvectors/hkdf_sha512_test.json#L141
+        let salt: [u8; 16] = decode_hex("1d6f3b38a1e607b5e6bcd4af1800a9d3");
+        let ikm: [u8; 16] = decode_hex("5d3db20e8238a90b62a600fa57fdb318");
+        let info: [u8; 20] = decode_hex("2bc5f39032b6fc87da69ba8711ce735b169646fd");
+        let expected_okm: [u8; 42] = decode_hex(
+            "8c3cf7122dcb5eb7efaf02718f1faf70bca20dcb75070e9d0871a413a6c05fc195a75aa9ffc349d70aae",
+        );
+
+        let kdf = Kdf::new(CipherSuite::CURVE448_CHACHA).unwrap();
+        let prk = kdf.extract(&salt, &ikm).unwrap();
+        assert_eq!(kdf.expand(&prk, &info, 42).unwrap(), expected_okm);
+    }
+
+    #[test]
+    fn sha256_extract_short_ikm() {
+        let kdf = Kdf::new(CipherSuite::CURVE25519_AES128).unwrap();
+        assert_matches!(kdf.extract(b"salty", b""), Err(KdfError::TooShortIkm { .. }));
+    }
+
+    #[test]
+    fn sha256_expand_short_prk() {
+        let prk_short: [u8; 16] = decode_hex("077709362c2e32df0ddc3f0dc47bba63");
+        let info: [u8; 10] = decode_hex("f0f1f2f3f4f5f6f7f8f9");
+
+        let kdf = Kdf::new(CipherSuite::CURVE25519_AES128).unwrap();
+        assert_matches!(kdf.expand(&prk_short, &info, 42), Err(KdfError::TooShortPrk { .. }));
+    }
+
+    #[test]
+    fn sha256_expand_long_okm() {
+        // https://www.rfc-editor.org/rfc/rfc5869.html#appendix-A.1
+        let prk: [u8; 32] =
+            decode_hex("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5");
+        let info: [u8; 10] = decode_hex("f0f1f2f3f4f5f6f7f8f9");
+
+        let kdf = Kdf::new(CipherSuite::CURVE25519_AES128).unwrap();
+        assert_matches!(
+            kdf.expand(&prk, &info, HkdfSha256::MAX_OUTPUT_LEN + 1),
+            Err(KdfError::TooLongOkm { .. })
+        );
+    }
+
+    #[test]
+    fn sha512_extract_short_ikm() {
+        let kdf = Kdf::new(CipherSuite::CURVE448_CHACHA).unwrap();
+        assert_matches!(kdf.extract(b"salty", b""), Err(KdfError::TooShortIkm { .. }));
+    }
+
+    #[test]
+    fn sha512_expand_short_prk() {
+        let prk_short: [u8; 16] = decode_hex("077709362c2e32df0ddc3f0dc47bba63");
+        let info: [u8; 10] = decode_hex("f0f1f2f3f4f5f6f7f8f9");
+
+        let kdf = Kdf::new(CipherSuite::CURVE448_CHACHA).unwrap();
+        assert_matches!(kdf.expand(&prk_short, &info, 42), Err(KdfError::TooShortPrk { .. }));
+    }
+
+    #[test]
+    fn sha512_expand_long_okm() {
+        // https://github.com/C2SP/wycheproof/blob/cd27d6419bedd83cbd24611ec54b6d4bfdb0cdca/testvectors/hkdf_sha512_test.json#L141
+        let salt: [u8; 16] = decode_hex("1d6f3b38a1e607b5e6bcd4af1800a9d3");
+        let ikm: [u8; 16] = decode_hex("5d3db20e8238a90b62a600fa57fdb318");
+        let info: [u8; 20] = decode_hex("2bc5f39032b6fc87da69ba8711ce735b169646fd");
+
+        let kdf_sha512 = Kdf::new(CipherSuite::CURVE448_CHACHA).unwrap();
+        let prk = kdf_sha512.extract(&salt, &ikm).unwrap();
+        assert_matches!(
+            kdf_sha512.expand(&prk, &info, HkdfSha512::MAX_OUTPUT_LEN + 1),
+            Err(KdfError::TooLongOkm { .. })
+        );
+    }
+
+    #[test]
+    fn unsupported_cipher_suites() {
+        let ikm: [u8; 22] = decode_hex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
+        let salt: [u8; 13] = decode_hex("000102030405060708090a0b0c");
+
+        assert_matches!(
+            Kdf::new(CipherSuite::P384_AES256).unwrap().extract(&salt, &ikm),
+            Err(KdfError::UnsupportedCipherSuite)
+        );
+    }
+}
diff --git a/mls/mls-rs-crypto-boringssl/src/lib.rs b/mls/mls-rs-crypto-boringssl/src/lib.rs
new file mode 100644
index 0000000..806bd87
--- /dev/null
+++ b/mls/mls-rs-crypto-boringssl/src/lib.rs
@@ -0,0 +1,676 @@
+// Copyright 2024, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Implements mls_rs_core's CryptoProvider and CipherSuiteProvider backed by BoringSSL.
+
+pub mod aead;
+pub mod ecdh;
+pub mod eddsa;
+pub mod hash;
+pub mod hpke;
+pub mod kdf;
+
+#[cfg(test)]
+mod test_helpers;
+
+use mls_rs_core::crypto::{
+    CipherSuite, CipherSuiteProvider, CryptoProvider, HpkeCiphertext, HpkePublicKey, HpkeSecretKey,
+    SignaturePublicKey, SignatureSecretKey,
+};
+use mls_rs_core::error::{AnyError, IntoAnyError};
+use mls_rs_crypto_traits::{AeadType, KdfType, KemType};
+use thiserror::Error;
+use zeroize::Zeroizing;
+
+use aead::AeadWrapper;
+use ecdh::Ecdh;
+use eddsa::{EdDsa, EdDsaError};
+use hash::{Hash, HashError};
+use hpke::{ContextR, ContextS, DhKem, Hpke, HpkeError};
+use kdf::Kdf;
+
+/// Errors returned from BoringsslCryptoProvider.
+#[derive(Debug, Error)]
+pub enum BoringsslCryptoError {
+    /// Error returned from hash functions and HMACs.
+    #[error(transparent)]
+    HashError(#[from] HashError),
+    /// Error returned from KEMs.
+    #[error(transparent)]
+    KemError(AnyError),
+    /// Error returned from KDFs.
+    #[error(transparent)]
+    KdfError(AnyError),
+    /// Error returned from AEADs.
+    #[error(transparent)]
+    AeadError(AnyError),
+    /// Error returned from HPKE.
+    #[error(transparent)]
+    HpkeError(#[from] HpkeError),
+    /// Error returned from EdDSA.
+    #[error(transparent)]
+    EdDsaError(#[from] EdDsaError),
+}
+
+impl IntoAnyError for BoringsslCryptoError {
+    fn into_dyn_error(self) -> Result<Box<dyn std::error::Error + Send + Sync>, Self> {
+        Ok(self.into())
+    }
+}
+
+/// CryptoProvider trait implementation backed by BoringSSL.
+#[derive(Debug, Clone)]
+#[non_exhaustive]
+pub struct BoringsslCryptoProvider {
+    /// Available cipher suites.
+    pub enabled_cipher_suites: Vec<CipherSuite>,
+}
+
+impl BoringsslCryptoProvider {
+    /// Creates a new BoringsslCryptoProvider.
+    pub fn new() -> Self {
+        Default::default()
+    }
+
+    /// Sets the enabled cipher suites.
+    pub fn with_enabled_cipher_suites(enabled_cipher_suites: Vec<CipherSuite>) -> Self {
+        Self { enabled_cipher_suites }
+    }
+
+    /// Returns all available cipher suites.
+    pub fn all_supported_cipher_suites() -> Vec<CipherSuite> {
+        vec![CipherSuite::CURVE25519_AES128, CipherSuite::CURVE25519_CHACHA]
+    }
+}
+
+impl Default for BoringsslCryptoProvider {
+    fn default() -> Self {
+        Self { enabled_cipher_suites: Self::all_supported_cipher_suites() }
+    }
+}
+
+impl CryptoProvider for BoringsslCryptoProvider {
+    type CipherSuiteProvider = BoringsslCipherSuite<DhKem<Ecdh, Kdf>, Kdf, AeadWrapper>;
+
+    fn supported_cipher_suites(&self) -> Vec<CipherSuite> {
+        self.enabled_cipher_suites.clone()
+    }
+
+    fn cipher_suite_provider(
+        &self,
+        cipher_suite: CipherSuite,
+    ) -> Option<Self::CipherSuiteProvider> {
+        if !self.enabled_cipher_suites.contains(&cipher_suite) {
+            return None;
+        }
+
+        let ecdh = Ecdh::new(cipher_suite)?;
+        let kdf = Kdf::new(cipher_suite)?;
+        let kem = DhKem::new(cipher_suite, ecdh, kdf.clone())?;
+        let aead = AeadWrapper::new(cipher_suite)?;
+
+        BoringsslCipherSuite::new(cipher_suite, kem, kdf, aead)
+    }
+}
+
+/// CipherSuiteProvider trait implementation backed by BoringSSL.
+#[derive(Clone)]
+pub struct BoringsslCipherSuite<KEM, KDF, AEAD>
+where
+    KEM: KemType + Clone,
+    KDF: KdfType + Clone,
+    AEAD: AeadType + Clone,
+{
+    cipher_suite: CipherSuite,
+    hash: Hash,
+    kem: KEM,
+    kdf: KDF,
+    aead: AEAD,
+    hpke: Hpke,
+    eddsa: EdDsa,
+}
+
+impl<KEM, KDF, AEAD> BoringsslCipherSuite<KEM, KDF, AEAD>
+where
+    KEM: KemType + Clone,
+    KDF: KdfType + Clone,
+    AEAD: AeadType + Clone,
+{
+    /// Creates a new BoringsslCipherSuite.
+    pub fn new(cipher_suite: CipherSuite, kem: KEM, kdf: KDF, aead: AEAD) -> Option<Self> {
+        Some(Self {
+            cipher_suite,
+            hash: Hash::new(cipher_suite).ok()?,
+            kem,
+            kdf,
+            aead,
+            hpke: Hpke::new(cipher_suite),
+            eddsa: EdDsa::new(cipher_suite)?,
+        })
+    }
+
+    /// Returns random bytes generated via BoringSSL.
+    pub fn random_bytes(&self, out: &mut [u8]) -> Result<(), BoringsslCryptoError> {
+        bssl_crypto::rand_bytes(out);
+        Ok(())
+    }
+}
+
+#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
+#[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))]
+#[cfg_attr(all(not(target_arch = "wasm32"), mls_build_async), maybe_async::must_be_async)]
+impl<KEM, KDF, AEAD> CipherSuiteProvider for BoringsslCipherSuite<KEM, KDF, AEAD>
+where
+    KEM: KemType + Clone + Send + Sync,
+    KDF: KdfType + Clone + Send + Sync,
+    AEAD: AeadType + Clone + Send + Sync,
+{
+    type Error = BoringsslCryptoError;
+    type HpkeContextS = ContextS;
+    type HpkeContextR = ContextR;
+
+    fn cipher_suite(&self) -> CipherSuite {
+        self.cipher_suite
+    }
+
+    fn random_bytes(&self, out: &mut [u8]) -> Result<(), Self::Error> {
+        self.random_bytes(out)
+    }
+
+    async fn hash(&self, data: &[u8]) -> Result<Vec<u8>, Self::Error> {
+        Ok(self.hash.hash(data))
+    }
+
+    async fn mac(&self, key: &[u8], data: &[u8]) -> Result<Vec<u8>, Self::Error> {
+        Ok(self.hash.mac(key, data)?)
+    }
+
+    async fn kem_generate(&self) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error> {
+        self.kem.generate().await.map_err(|e| BoringsslCryptoError::KemError(e.into_any_error()))
+    }
+
+    async fn kem_derive(&self, ikm: &[u8]) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error> {
+        self.kem.derive(ikm).await.map_err(|e| BoringsslCryptoError::KemError(e.into_any_error()))
+    }
+
+    fn kem_public_key_validate(&self, key: &HpkePublicKey) -> Result<(), Self::Error> {
+        self.kem
+            .public_key_validate(key)
+            .map_err(|e| BoringsslCryptoError::KemError(e.into_any_error()))
+    }
+
+    async fn kdf_extract(
+        &self,
+        salt: &[u8],
+        ikm: &[u8],
+    ) -> Result<Zeroizing<Vec<u8>>, Self::Error> {
+        self.kdf
+            .extract(salt, ikm)
+            .await
+            .map_err(|e| BoringsslCryptoError::KdfError(e.into_any_error()))
+            .map(Zeroizing::new)
+    }
+
+    async fn kdf_expand(
+        &self,
+        prk: &[u8],
+        info: &[u8],
+        len: usize,
+    ) -> Result<Zeroizing<Vec<u8>>, Self::Error> {
+        self.kdf
+            .expand(prk, info, len)
+            .await
+            .map_err(|e| BoringsslCryptoError::KdfError(e.into_any_error()))
+            .map(Zeroizing::new)
+    }
+
+    fn kdf_extract_size(&self) -> usize {
+        self.kdf.extract_size()
+    }
+
+    async fn aead_seal(
+        &self,
+        key: &[u8],
+        data: &[u8],
+        aad: Option<&[u8]>,
+        nonce: &[u8],
+    ) -> Result<Vec<u8>, Self::Error> {
+        self.aead
+            .seal(key, data, aad, nonce)
+            .await
+            .map_err(|e| BoringsslCryptoError::AeadError(e.into_any_error()))
+    }
+
+    async fn aead_open(
+        &self,
+        key: &[u8],
+        cipher_text: &[u8],
+        aad: Option<&[u8]>,
+        nonce: &[u8],
+    ) -> Result<Zeroizing<Vec<u8>>, Self::Error> {
+        self.aead
+            .open(key, cipher_text, aad, nonce)
+            .await
+            .map_err(|e| BoringsslCryptoError::AeadError(e.into_any_error()))
+            .map(Zeroizing::new)
+    }
+
+    fn aead_key_size(&self) -> usize {
+        self.aead.key_size()
+    }
+
+    fn aead_nonce_size(&self) -> usize {
+        self.aead.nonce_size()
+    }
+
+    async fn hpke_setup_s(
+        &self,
+        remote_key: &HpkePublicKey,
+        info: &[u8],
+    ) -> Result<(Vec<u8>, Self::HpkeContextS), Self::Error> {
+        Ok(self.hpke.setup_sender(remote_key, info).await?)
+    }
+
+    async fn hpke_seal(
+        &self,
+        remote_key: &HpkePublicKey,
+        info: &[u8],
+        aad: Option<&[u8]>,
+        pt: &[u8],
+    ) -> Result<HpkeCiphertext, Self::Error> {
+        Ok(self.hpke.seal(remote_key, info, aad, pt).await?)
+    }
+
+    async fn hpke_setup_r(
+        &self,
+        enc: &[u8],
+        local_secret: &HpkeSecretKey,
+        // Other implementations use `_local_public` to skip derivation of the public from the
+        // private key for the KEM decapsulation step, but BoringSSL's API does not accept a public
+        // key and instead derives it under the hood.
+        _local_public: &HpkePublicKey,
+        info: &[u8],
+    ) -> Result<Self::HpkeContextR, Self::Error> {
+        Ok(self.hpke.setup_receiver(enc, local_secret, info).await?)
+    }
+
+    async fn hpke_open(
+        &self,
+        ciphertext: &HpkeCiphertext,
+        local_secret: &HpkeSecretKey,
+        // Other implementations use `_local_public` to skip derivation of the public from the
+        // private key for hpke_setup_r()'s KEM decapsulation step, but BoringSSL's API does not
+        // accept a public key and instead derives it under the hood.
+        _local_public: &HpkePublicKey,
+        info: &[u8],
+        aad: Option<&[u8]>,
+    ) -> Result<Vec<u8>, Self::Error> {
+        Ok(self.hpke.open(ciphertext, local_secret, info, aad).await?)
+    }
+
+    async fn signature_key_generate(
+        &self,
+    ) -> Result<(SignatureSecretKey, SignaturePublicKey), Self::Error> {
+        Ok(self.eddsa.signature_key_generate()?)
+    }
+
+    async fn signature_key_derive_public(
+        &self,
+        secret_key: &SignatureSecretKey,
+    ) -> Result<SignaturePublicKey, Self::Error> {
+        Ok(self.eddsa.signature_key_derive_public(secret_key)?)
+    }
+
+    async fn sign(
+        &self,
+        secret_key: &SignatureSecretKey,
+        data: &[u8],
+    ) -> Result<Vec<u8>, Self::Error> {
+        Ok(self.eddsa.sign(secret_key, data)?)
+    }
+
+    async fn verify(
+        &self,
+        public_key: &SignaturePublicKey,
+        signature: &[u8],
+        data: &[u8],
+    ) -> Result<(), Self::Error> {
+        Ok(self.eddsa.verify(public_key, signature, data)?)
+    }
+}
+
+#[cfg(all(not(mls_build_async), test))]
+mod test {
+    use super::BoringsslCryptoProvider;
+    use crate::test_helpers::decode_hex;
+    use mls_rs_core::crypto::{
+        CipherSuite, CipherSuiteProvider, CryptoProvider, HpkeContextR, HpkeContextS,
+        HpkePublicKey, HpkeSecretKey, SignaturePublicKey, SignatureSecretKey,
+    };
+
+    fn get_cipher_suites() -> Vec<CipherSuite> {
+        vec![CipherSuite::CURVE25519_AES128, CipherSuite::CURVE25519_CHACHA]
+    }
+
+    #[test]
+    fn supported_cipher_suites() {
+        let bssl = BoringsslCryptoProvider::new();
+        assert_eq!(bssl.supported_cipher_suites().len(), 2);
+    }
+
+    #[test]
+    fn unsupported_cipher_suites() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in vec![
+            CipherSuite::P256_AES128,
+            CipherSuite::CURVE448_AES256,
+            CipherSuite::P521_AES256,
+            CipherSuite::CURVE448_CHACHA,
+            CipherSuite::P384_AES256,
+        ] {
+            assert!(bssl.cipher_suite_provider(suite).is_none());
+        }
+    }
+
+    #[test]
+    fn cipher_suite() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in get_cipher_suites() {
+            let crypto = bssl.cipher_suite_provider(suite).unwrap();
+            assert_eq!(crypto.cipher_suite(), suite);
+        }
+    }
+
+    #[test]
+    fn random_bytes() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in get_cipher_suites() {
+            let crypto = bssl.cipher_suite_provider(suite).unwrap();
+            let mut buf = [0; 32];
+            let _ = crypto.random_bytes(&mut buf);
+        }
+    }
+
+    #[test]
+    fn hash() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in get_cipher_suites() {
+            let crypto = bssl.cipher_suite_provider(suite).unwrap();
+            assert_eq!(
+                crypto.hash(&decode_hex::<4>("74ba2521")).unwrap(),
+                // bssl_crypto::hmac test vector.
+                decode_hex::<32>(
+                    "b16aa56be3880d18cd41e68384cf1ec8c17680c45a02b1575dc1518923ae8b0e"
+                )
+            );
+        }
+    }
+
+    #[test]
+    fn mac() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in get_cipher_suites() {
+            let crypto = bssl.cipher_suite_provider(suite).unwrap();
+            // bssl_crypto::hmac test vector.
+            let expected = vec![
+                0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0xb,
+                0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x0, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c,
+                0x2e, 0x32, 0xcf, 0xf7,
+            ];
+            let key: [u8; 20] = [0x0b; 20];
+            let data = b"Hi There";
+
+            assert_eq!(crypto.mac(&key, data).unwrap(), expected);
+        }
+    }
+
+    #[test]
+    fn kem_generate() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in get_cipher_suites() {
+            let crypto = bssl.cipher_suite_provider(suite).unwrap();
+            assert!(crypto.kem_generate().is_ok());
+        }
+    }
+
+    #[test]
+    fn kem_derive() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in get_cipher_suites() {
+            let crypto = bssl.cipher_suite_provider(suite).unwrap();
+            // https://www.rfc-editor.org/rfc/rfc9180.html#appendix-A.1.1
+            let ikm: [u8; 32] =
+                decode_hex("7268600d403fce431561aef583ee1613527cff655c1343f29812e66706df3234");
+            let expected_sk = HpkeSecretKey::from(
+                decode_hex::<32>(
+                    "52c4a758a802cd8b936eceea314432798d5baf2d7e9235dc084ab1b9cfa2f736",
+                )
+                .to_vec(),
+            );
+            let expected_pk = HpkePublicKey::from(
+                decode_hex::<32>(
+                    "37fda3567bdbd628e88668c3c8d7e97d1d1253b6d4ea6d44c150f741f1bf4431",
+                )
+                .to_vec(),
+            );
+
+            let (sk, pk) = crypto.kem_derive(&ikm).unwrap();
+            assert_eq!(sk, expected_sk);
+            assert_eq!(pk, expected_pk);
+        }
+    }
+
+    #[test]
+    fn kem_public_key_validate() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in get_cipher_suites() {
+            let crypto = bssl.cipher_suite_provider(suite).unwrap();
+            // https://www.rfc-editor.org/rfc/rfc7748.html#section-6.1
+            let public_key = HpkePublicKey::from(
+                decode_hex::<32>(
+                    "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a",
+                )
+                .to_vec(),
+            );
+            assert!(crypto.kem_public_key_validate(&public_key).is_ok());
+        }
+    }
+
+    #[test]
+    fn kdf_extract_and_expand() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in get_cipher_suites() {
+            let crypto = bssl.cipher_suite_provider(suite).unwrap();
+            // https://www.rfc-editor.org/rfc/rfc5869.html#appendix-A.1
+            let ikm: [u8; 22] = decode_hex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
+            let salt: [u8; 13] = decode_hex("000102030405060708090a0b0c");
+            let info: [u8; 10] = decode_hex("f0f1f2f3f4f5f6f7f8f9");
+            let expected_prk: [u8; 32] =
+                decode_hex("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5");
+            let expected_okm : [u8; 42] = decode_hex(
+                    "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
+                );
+
+            let prk = crypto.kdf_extract(&salt, &ikm).unwrap();
+            assert_eq!(prk.as_ref(), expected_prk);
+            assert_eq!(crypto.kdf_expand(&prk.as_ref(), &info, 42).unwrap().as_ref(), expected_okm);
+        }
+    }
+
+    #[test]
+    fn kdf_extract_size() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in get_cipher_suites() {
+            let crypto = bssl.cipher_suite_provider(suite).unwrap();
+            assert_eq!(crypto.kdf_extract_size(), 32);
+        }
+    }
+
+    #[test]
+    fn aead() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in get_cipher_suites() {
+            let crypto = bssl.cipher_suite_provider(suite).unwrap();
+            let key = vec![42u8; crypto.aead_key_size()];
+            let associated_data = vec![42u8, 12];
+            let nonce = vec![42u8; crypto.aead_nonce_size()];
+            let plaintext = b"message";
+
+            let ciphertext =
+                crypto.aead_seal(&key, plaintext, Some(&associated_data), &nonce).unwrap();
+            assert_eq!(
+                plaintext,
+                crypto
+                    .aead_open(&key, ciphertext.as_slice(), Some(&associated_data), &nonce)
+                    .unwrap()
+                    .as_slice()
+            );
+        }
+    }
+
+    #[test]
+    fn hpke_setup_seal_open_export() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in get_cipher_suites() {
+            let crypto = bssl.cipher_suite_provider(suite).unwrap();
+            // https://www.rfc-editor.org/rfc/rfc9180.html#appendix-A.1.1
+            let receiver_pub_key = HpkePublicKey::from(
+                decode_hex::<32>(
+                    "3948cfe0ad1ddb695d780e59077195da6c56506b027329794ab02bca80815c4d",
+                )
+                .to_vec(),
+            );
+            let receiver_priv_key = HpkeSecretKey::from(
+                decode_hex::<32>(
+                    "4612c550263fc8ad58375df3f557aac531d26850903e55a9f23f21d8534e8ac8",
+                )
+                .to_vec(),
+            );
+
+            let info = b"some_info";
+            let plaintext = b"plaintext";
+            let associated_data = b"some_ad";
+            let exporter_ctx = b"export_ctx";
+
+            let (enc, mut sender_ctx) = crypto.hpke_setup_s(&receiver_pub_key, info).unwrap();
+            let mut receiver_ctx =
+                crypto.hpke_setup_r(&enc, &receiver_priv_key, &receiver_pub_key, info).unwrap();
+            let ct = sender_ctx.seal(Some(associated_data), plaintext).unwrap();
+            assert_eq!(plaintext.as_ref(), receiver_ctx.open(Some(associated_data), &ct).unwrap(),);
+            assert_eq!(
+                sender_ctx.export(exporter_ctx, 32).unwrap(),
+                receiver_ctx.export(exporter_ctx, 32).unwrap(),
+            );
+        }
+    }
+
+    #[test]
+    fn hpke_seal_open() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in get_cipher_suites() {
+            let crypto = bssl.cipher_suite_provider(suite).unwrap();
+            // https://www.rfc-editor.org/rfc/rfc9180.html#appendix-A.1.1
+            let receiver_pub_key = HpkePublicKey::from(
+                decode_hex::<32>(
+                    "3948cfe0ad1ddb695d780e59077195da6c56506b027329794ab02bca80815c4d",
+                )
+                .to_vec(),
+            );
+            let receiver_priv_key = HpkeSecretKey::from(
+                decode_hex::<32>(
+                    "4612c550263fc8ad58375df3f557aac531d26850903e55a9f23f21d8534e8ac8",
+                )
+                .to_vec(),
+            );
+
+            let info = b"some_info";
+            let plaintext = b"plaintext";
+            let associated_data = b"some_ad";
+
+            let ct = crypto
+                .hpke_seal(&receiver_pub_key, info, Some(associated_data), plaintext)
+                .unwrap();
+            assert_eq!(
+                plaintext.as_ref(),
+                crypto
+                    .hpke_open(
+                        &ct,
+                        &receiver_priv_key,
+                        &receiver_pub_key,
+                        info,
+                        Some(associated_data)
+                    )
+                    .unwrap(),
+            );
+        }
+    }
+
+    #[test]
+    fn signature_key_generate() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in get_cipher_suites() {
+            let crypto = bssl.cipher_suite_provider(suite).unwrap();
+            assert!(crypto.signature_key_generate().is_ok());
+        }
+    }
+
+    #[test]
+    fn signature_key_derive_public() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in get_cipher_suites() {
+            let crypto = bssl.cipher_suite_provider(suite).unwrap();
+            // Test 1 from https://www.rfc-editor.org/rfc/rfc8032#section-7.1
+            let private_key = SignatureSecretKey::from(
+                decode_hex::<32>(
+                    "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60",
+                )
+                .to_vec(),
+            );
+            let expected_public_key = SignaturePublicKey::from(
+                decode_hex::<32>(
+                    "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a",
+                )
+                .to_vec(),
+            );
+
+            assert_eq!(
+                crypto.signature_key_derive_public(&private_key).unwrap(),
+                expected_public_key
+            );
+        }
+    }
+
+    #[test]
+    fn sign_verify() {
+        let bssl = BoringsslCryptoProvider::new();
+        for suite in get_cipher_suites() {
+            let crypto = bssl.cipher_suite_provider(suite).unwrap();
+            // Test 3 from https://www.rfc-editor.org/rfc/rfc8032#section-7.1
+            let private_key = SignatureSecretKey::from(
+                decode_hex::<32>(
+                    "c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7",
+                )
+                .to_vec(),
+            );
+            let data: [u8; 2] = decode_hex("af82");
+            let expected_sig = decode_hex::<64>("6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a").to_vec();
+
+            let sig = crypto.sign(&private_key, &data).unwrap();
+            assert_eq!(sig, expected_sig);
+
+            let public_key = crypto.signature_key_derive_public(&private_key).unwrap();
+            assert!(crypto.verify(&public_key, &sig, &data).is_ok());
+        }
+    }
+}
diff --git a/mls/mls-rs-crypto-boringssl/src/test_helpers.rs b/mls/mls-rs-crypto-boringssl/src/test_helpers.rs
new file mode 100644
index 0000000..0b07fac
--- /dev/null
+++ b/mls/mls-rs-crypto-boringssl/src/test_helpers.rs
@@ -0,0 +1,23 @@
+// Copyright 2024, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+pub(crate) fn decode_hex<const N: usize>(s: &str) -> [u8; N] {
+    (0..s.len())
+        .step_by(2)
+        .map(|i| u8::from_str_radix(&s[i..i + 2], 16).expect("Invalid hex string"))
+        .collect::<Vec<u8>>()
+        .as_slice()
+        .try_into()
+        .unwrap()
+}
