wtx 0.43.0

A collection of different transport implementations and related tools focused primarily on web technologies.
Documentation
use crate::{
  crypto::{
    Aes128GcmAwsLcRs, Aes256GcmAwsLcRs, Chacha20Poly1305AwsLcRs, CryptoError,
    aead::{Aead, NONCE_LEN, TAG_LEN, generate_nonce, split_nonce_content, write_tag},
  },
  rng::CryptoRng,
};
use aws_lc_rs::aead::{
  AES_128_GCM, AES_256_GCM, Aad, CHACHA20_POLY1305, LessSafeKey, Nonce, UnboundKey,
};

impl Aead for Aes128GcmAwsLcRs {
  type Secret = [u8; 16];

  #[inline]
  fn decrypt_in_place<'encrypted>(
    associated_data: &[u8],
    encrypted_data: &'encrypted mut [u8],
    secret: &Self::Secret,
  ) -> crate::Result<&'encrypted mut [u8]> {
    local_decrypt(
      &AES_128_GCM,
      associated_data,
      encrypted_data,
      CryptoError::InvalidAes128GcmData,
      secret,
    )
  }

  #[inline]
  fn encrypt_parts<RNG>(
    associated_data: &[u8],
    nonce: [&mut u8; NONCE_LEN],
    plaintext: &mut [u8],
    rng: &mut RNG,
    secret: &Self::Secret,
    tag: [&mut u8; TAG_LEN],
  ) -> crate::Result<()>
  where
    RNG: CryptoRng,
  {
    local_encrypt_vectored_data(
      &AES_128_GCM,
      associated_data,
      CryptoError::InvalidAes128GcmData,
      nonce,
      plaintext,
      rng,
      secret,
      tag,
    )
  }
}

impl Aead for Aes256GcmAwsLcRs {
  type Secret = [u8; 32];

  #[inline]
  fn decrypt_in_place<'encrypted>(
    associated_data: &[u8],
    encrypted_data: &'encrypted mut [u8],
    secret: &Self::Secret,
  ) -> crate::Result<&'encrypted mut [u8]> {
    local_decrypt(
      &AES_256_GCM,
      associated_data,
      encrypted_data,
      CryptoError::InvalidAes256GcmData,
      secret,
    )
  }

  #[inline]
  fn encrypt_parts<RNG>(
    associated_data: &[u8],
    nonce: [&mut u8; NONCE_LEN],
    plaintext: &mut [u8],
    rng: &mut RNG,
    secret: &Self::Secret,
    tag: [&mut u8; TAG_LEN],
  ) -> crate::Result<()>
  where
    RNG: CryptoRng,
  {
    local_encrypt_vectored_data(
      &AES_256_GCM,
      associated_data,
      CryptoError::InvalidAes256GcmData,
      nonce,
      plaintext,
      rng,
      secret,
      tag,
    )
  }
}

impl Aead for Chacha20Poly1305AwsLcRs {
  type Secret = [u8; 32];

  #[inline]
  fn decrypt_in_place<'encrypted>(
    associated_data: &[u8],
    encrypted_data: &'encrypted mut [u8],
    secret: &Self::Secret,
  ) -> crate::Result<&'encrypted mut [u8]> {
    local_decrypt(
      &CHACHA20_POLY1305,
      associated_data,
      encrypted_data,
      CryptoError::InvalidChacha20Poly1305Data,
      secret,
    )
  }

  #[inline]
  fn encrypt_parts<RNG>(
    associated_data: &[u8],
    nonce: [&mut u8; NONCE_LEN],
    plaintext: &mut [u8],
    rng: &mut RNG,
    secret: &Self::Secret,
    tag: [&mut u8; TAG_LEN],
  ) -> crate::Result<()>
  where
    RNG: CryptoRng,
  {
    local_encrypt_vectored_data(
      &CHACHA20_POLY1305,
      associated_data,
      CryptoError::InvalidChacha20Poly1305Data,
      nonce,
      plaintext,
      rng,
      secret,
      tag,
    )
  }
}

#[inline]
fn local_decrypt<'encrypted, const S: usize>(
  algorithm: &'static aws_lc_rs::aead::Algorithm,
  associated_data: &[u8],
  encrypted_data: &'encrypted mut [u8],
  error: CryptoError,
  secret: &[u8; S],
) -> crate::Result<&'encrypted mut [u8]> {
  let (nonce, content) = split_nonce_content(encrypted_data, error)?;
  let bytes = LessSafeKey::new(UnboundKey::new(algorithm, secret).map_err(|_| error)?)
    .open_in_place(Nonce::assume_unique_for_key(nonce), Aad::from(associated_data), content)
    .map_err(|_| error)?;
  Ok(bytes)
}

#[inline]
fn local_encrypt_vectored_data<RNG, const S: usize>(
  algorithm: &'static aws_lc_rs::aead::Algorithm,
  associated_data: &[u8],
  error: CryptoError,
  nonce: [&mut u8; NONCE_LEN],
  plaintext: &mut [u8],
  rng: &mut RNG,
  secret: &[u8; S],
  tag: [&mut u8; TAG_LEN],
) -> crate::Result<()>
where
  RNG: CryptoRng,
{
  let local_tag = LessSafeKey::new(UnboundKey::new(algorithm, secret).map_err(|_| error)?)
    .seal_in_place_separate_tag(
      Nonce::assume_unique_for_key(generate_nonce(nonce, rng)),
      Aad::from(associated_data),
      plaintext,
    )
    .map_err(|_| error)?
    .as_ref()
    .try_into()?;
  write_tag(local_tag, tag);
  Ok(())
}