gcm_aes_decrypt_async

Function gcm_aes_decrypt_async 

Source
pub async fn gcm_aes_decrypt_async<R, W>(
    key: &[u8],
    iv: &[u8],
    reader: R,
    writer: W,
    aad: &[u8],
    mul_fn: &GcmBlockMulFn,
) -> Result<[u8; 16], AesGcmAsyncError>
where R: AsyncRead + Unpin, W: AsyncWrite + Unpin,
Expand description

Async version of gcm_aes_decrypt that reads from an AsyncRead source and writes to an AsyncWrite destination.

This function provides authenticated decryption using AES-GCM mode with optimized performance for large data streams. It includes comprehensive error handling and input validation.

§Parameters

  • key - AES cipher key (16, 24, or 32 bytes for AES-128, AES-192, or AES-256)
  • iv - Initialization Vector (at least 1 byte, longer IVs are hashed to 12 bytes)
  • reader - AsyncRead source for cipher text to decrypt and authenticate
  • writer - AsyncWrite destination for plain text
  • aad - Additional authenticated data (can be empty)
  • mul_fn - Block multiplication function from GcmBlockMulEnhancement::to_mul_fn()

§Returns

  • Result<[u8; 16], AesGcmAsyncError> - Authentication tag on success, error on failure

§Errors

  • InvalidKeySize - Key size is not 16, 24, or 32 bytes
  • InvalidIvSize - IV size is 0 bytes
  • IoError - I/O error during reading or writing
  • CryptoError - Internal cryptographic error
  • AuthenticationFailed - Authentication tag verification failed

§Security Note

The returned authentication tag should be compared with the expected tag using constant-time comparison. If the tags don’t match, the message has been tampered with or corrupted.

§Examples

§Basic decryption

use crypto_async_rs::aes_gcm::{GcmBlockMulEnhancement};
use crypto_async_rs::aes_gcm_async::{gcm_aes_decrypt_async, AesGcmAsyncError};
use futures::io::Cursor;

async fn example() -> Result<(), AesGcmAsyncError> {
    let cipher_key = [0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08];
    let iv = [0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88];
    let cipher_text = [0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c];
    let aad = [];
    let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
     
    let reader = Cursor::new(&cipher_text);
    let mut writer = Cursor::new(Vec::new());
     
    let tag = gcm_aes_decrypt_async(&cipher_key, &iv, reader, &mut writer, &aad, &mul_fn).await?;
    println!("Authentication tag: {:?}", tag);
    Ok(())
}

§Authentication verification

use crypto_async_rs::aes_gcm_async::{gcm_aes_decrypt_async, AesGcmAsyncError};
use crypto_async_rs::aes_gcm::GcmBlockMulEnhancement;
use futures::io::Cursor;

async fn verify_authentication() -> Result<(), AesGcmAsyncError> {
    let key = [0u8; 16];
    let iv = [0u8; 12];
    let expected_tag = [0u8; 16];
    let cipher_text = b"encrypted data";
    let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&key);
     
    let reader = Cursor::new(cipher_text);
    let mut writer = Cursor::new(Vec::new());
     
    let computed_tag = gcm_aes_decrypt_async(&key, &iv, reader, &mut writer, &[], &mul_fn).await?;
     
    // Constant-time comparison
    if computed_tag == expected_tag {
        println!("Authentication successful");
    } else {
        return Err(AesGcmAsyncError::AuthenticationFailed);
    }
    Ok(())
}