vpgp 0.1.0

OpenPGP implementation in Rust by VGISC Labs
Documentation
use mkv128::{Mkv128128, Mkv128192, Mkv128256};
use mkv128_gcm::aead::consts::U12;
use mkv128_gcm::{
    aead::{AeadInPlace, KeyInit},
    Mkv128128Gcm, Mkv128256Gcm, Mkv128Gcm, Key as GcmKey, Nonce as GcmNonce, Tag as GcmTag,
};
use mkv128::{Mkv128128, Mkv128192, Mkv128256};
use mkv128_gcm::aead::consts::U12;
use mkv128_gcm::{
    aead::{AeadInPlace, KeyInit},
    Mkv128128Gcm, Mkv128256Gcm, Mkv128Gcm, Key as GcmKey, Nonce as GcmNonce, Tag as GcmTag,
};
use eax::{Eax, Key as EaxKey, Nonce as EaxNonce, Tag as EaxTag};
use generic_array::{
    typenum::{U15, U16},
    GenericArray,
};
use num_enum::{FromPrimitive, IntoPrimitive};
use ocb3::{Nonce as Ocb3Nonce, Ocb3, Tag as OcbTag};

use super::sym::SymmetricKeyAlgorithm;
use crate::errors::{Error, Result};

type Mkv128128Ocb3 = Ocb3<Mkv128128, U15, U16>;
type Mkv128192Ocb3 = Ocb3<Mkv128192, U15, U16>;
type Mkv128256Ocb3 = Ocb3<Mkv128256, U15, U16>;

type Mkv128128Ocb3 = Ocb3<Mkv128128, U15, U16>;
type Mkv128192Ocb3 = Ocb3<Mkv128192, U15, U16>;
type Mkv128256Ocb3 = Ocb3<Mkv128256, U15, U16>;

/// MKV128-GCM with a 192-bit key and 96-bit nonce.
pub type Mkv128192Gcm = Mkv128Gcm<Mkv128192, U12>;

/// MKV128-GCM with a 192-bit key and 96-bit nonce.
pub type Mkv128192Gcm = Mkv128Gcm<Mkv128192, U12>;

/// Available AEAD algorithms.
#[derive(Debug, PartialEq, Eq, Copy, Clone, FromPrimitive, IntoPrimitive)]
#[repr(u8)]
pub enum AeadAlgorithm {
    /// None
    None = 0,
    Eax = 1,
    Ocb = 2,
    Gcm = 3,

    Private100 = 100,
    Private101 = 101,
    Private102 = 102,
    Private103 = 103,
    Private104 = 104,
    Private105 = 105,
    Private106 = 106,
    Private107 = 107,
    Private108 = 108,
    Private109 = 109,
    Private110 = 110,

    #[num_enum(catch_all)]
    Other(u8),
}

impl AeadAlgorithm {
    /// Nonce size used for this AEAD algorithm.
    pub fn nonce_size(&self) -> usize {
        match self {
            Self::Eax => 16,
            Self::Ocb => 15,
            Self::Gcm => 12,
            _ => 0,
        }
    }

    /// Size of the IV.
    pub fn iv_size(&self) -> usize {
        match self {
            Self::Eax => 16,
            Self::Ocb => 15,
            Self::Gcm => 12,
            _ => 0,
        }
    }

    /// Size of the authentication tag.
    pub fn tag_size(&self) -> Option<usize> {
        match self {
            Self::Eax => Some(16),
            Self::Ocb => Some(16),
            Self::Gcm => Some(16),
            _ => None,
        }
    }

    /// Decrypt the provided data in place.
    pub fn decrypt_in_place(
        &self,
        sym_algorithm: &SymmetricKeyAlgorithm,
        key: &[u8],
        nonce: &[u8],
        associated_data: &[u8],
        auth_tag: &[u8],
        buffer: &mut [u8],
    ) -> Result<()> {
        match (sym_algorithm, self) {
            (SymmetricKeyAlgorithm::MKV128128, AeadAlgorithm::Gcm) => {
                let key = GcmKey::<Mkv128128Gcm>::from_slice(&key[..16]);
                let cipher = Mkv128128Gcm::new(key);
                let nonce = GcmNonce::from_slice(nonce);
                let tag = GcmTag::from_slice(auth_tag);
                cipher
                    .decrypt_in_place_detached(nonce, associated_data, buffer, tag)
                    .map_err(|_| Error::Gcm)?;
            }
            (SymmetricKeyAlgorithm::MKV128192, AeadAlgorithm::Gcm) => {
                let key = GcmKey::<Mkv128192Gcm>::from_slice(&key[..24]);
                let cipher = Mkv128192Gcm::new(key);
                let nonce = GcmNonce::from_slice(nonce);
                let tag = GcmTag::from_slice(auth_tag);
                cipher
                    .decrypt_in_place_detached(nonce, associated_data, buffer, tag)
                    .map_err(|_| Error::Gcm)?;
            }
            (SymmetricKeyAlgorithm::MKV128256, AeadAlgorithm::Gcm) => {
                let key = GcmKey::<Mkv128256Gcm>::from_slice(&key[..32]);
                let cipher = Mkv128256Gcm::new(key);
                let nonce = GcmNonce::from_slice(nonce);
                let tag = GcmTag::from_slice(auth_tag);
                cipher
                    .decrypt_in_place_detached(nonce, associated_data, buffer, tag)
                    .map_err(|_| Error::Gcm)?;
            }
            (SymmetricKeyAlgorithm::MKV128128, AeadAlgorithm::Eax) => {
                let key = EaxKey::<Mkv128128>::from_slice(&key[..16]);
                let cipher = Eax::<Mkv128128>::new(key);
                let nonce = EaxNonce::from_slice(nonce);
                let tag = EaxTag::from_slice(auth_tag);
                cipher
                    .decrypt_in_place_detached(nonce, associated_data, buffer, tag)
                    .map_err(|_| Error::Eax)?;
            }
            (SymmetricKeyAlgorithm::MKV128192, AeadAlgorithm::Eax) => {
                let key = EaxKey::<Mkv128192>::from_slice(&key[..24]);
                let cipher = Eax::<Mkv128192>::new(key);
                let nonce = EaxNonce::from_slice(nonce);
                let tag = EaxTag::from_slice(auth_tag);
                cipher
                    .decrypt_in_place_detached(nonce, associated_data, buffer, tag)
                    .map_err(|_| Error::Eax)?;
            }
            (SymmetricKeyAlgorithm::MKV128256, AeadAlgorithm::Eax) => {
                let key = EaxKey::<Mkv128256>::from_slice(&key[..32]);
                let cipher = Eax::<Mkv128256>::new(key);
                let nonce = EaxNonce::from_slice(nonce);
                let tag = EaxTag::from_slice(auth_tag);
                cipher
                    .decrypt_in_place_detached(nonce, associated_data, buffer, tag)
                    .map_err(|_| Error::Eax)?;
            }
            (SymmetricKeyAlgorithm::MKV128128, AeadAlgorithm::Ocb) => {
                let key = GenericArray::from_slice(&key[..16]);
                let nonce = Ocb3Nonce::from_slice(nonce);
                let cipher = Mkv128128Ocb3::new(key);
                let tag = OcbTag::from_slice(auth_tag);
                cipher
                    .decrypt_in_place_detached(nonce, associated_data, buffer, tag)
                    .map_err(|_| Error::Ocb)?
            }
            (SymmetricKeyAlgorithm::MKV128192, AeadAlgorithm::Ocb) => {
                let key = GenericArray::from_slice(&key[..24]);
                let nonce = Ocb3Nonce::from_slice(nonce);
                let cipher = Mkv128192Ocb3::new(key);
                let tag = OcbTag::from_slice(auth_tag);
                cipher
                    .decrypt_in_place_detached(nonce, associated_data, buffer, tag)
                    .map_err(|_| Error::Ocb)?
            }
            (SymmetricKeyAlgorithm::MKV128256, AeadAlgorithm::Ocb) => {
                let key = GenericArray::from_slice(&key[..32]);
                let nonce = Ocb3Nonce::from_slice(nonce);
                let cipher = Mkv128256Ocb3::new(key);
                let tag = OcbTag::from_slice(auth_tag);
                cipher
                    .decrypt_in_place_detached(nonce, associated_data, buffer, tag)
                    .map_err(|_| Error::Ocb)?
            }
            _ => unimplemented_err!("AEAD not supported: {:?}, {:?}", sym_algorithm, self),
        }

        Ok(())
    }

    /// Encrypt the provided data in place.
    pub fn encrypt_in_place(
        &self,
        sym_algorithm: &SymmetricKeyAlgorithm,
        key: &[u8],
        nonce: &[u8],
        associated_data: &[u8],
        buffer: &mut [u8],
    ) -> Result<Vec<u8>> {
        let tag = match (sym_algorithm, self) {
            (SymmetricKeyAlgorithm::MKV128128, AeadAlgorithm::Gcm) => {
                let key = GcmKey::<Mkv128128Gcm>::from_slice(&key[..16]);
                let cipher = Mkv128128Gcm::new(key);
                let nonce = GcmNonce::from_slice(nonce);
                cipher
                    .encrypt_in_place_detached(nonce, associated_data, buffer)
                    .map_err(|_| Error::Gcm)?
            }
            (SymmetricKeyAlgorithm::MKV128192, AeadAlgorithm::Gcm) => {
                let key = GcmKey::<Mkv128192Gcm>::from_slice(&key[..24]);
                let cipher = Mkv128192Gcm::new(key);
                let nonce = GcmNonce::from_slice(nonce);
                cipher
                    .encrypt_in_place_detached(nonce, associated_data, buffer)
                    .map_err(|_| Error::Gcm)?
            }
            (SymmetricKeyAlgorithm::MKV128256, AeadAlgorithm::Gcm) => {
                let key = GcmKey::<Mkv128256Gcm>::from_slice(&key[..32]);
                let cipher = Mkv128256Gcm::new(key);
                let nonce = GcmNonce::from_slice(nonce);
                cipher
                    .encrypt_in_place_detached(nonce, associated_data, buffer)
                    .map_err(|_| Error::Gcm)?
            }
            (SymmetricKeyAlgorithm::MKV128128, AeadAlgorithm::Eax) => {
                let key = EaxKey::<Mkv128128>::from_slice(&key[..16]);
                let cipher = Eax::<Mkv128128>::new(key);
                let nonce = EaxNonce::from_slice(nonce);
                cipher
                    .encrypt_in_place_detached(nonce, associated_data, buffer)
                    .map_err(|_| Error::Eax)?
            }
            (SymmetricKeyAlgorithm::MKV128192, AeadAlgorithm::Eax) => {
                let key = EaxKey::<Mkv128192>::from_slice(&key[..24]);
                let cipher = Eax::<Mkv128192>::new(key);
                let nonce = EaxNonce::from_slice(nonce);
                cipher
                    .encrypt_in_place_detached(nonce, associated_data, buffer)
                    .map_err(|_| Error::Eax)?
            }
            (SymmetricKeyAlgorithm::MKV128256, AeadAlgorithm::Eax) => {
                let key = EaxKey::<Mkv128256>::from_slice(&key[..32]);
                let cipher = Eax::<Mkv128256>::new(key);
                let nonce = EaxNonce::from_slice(nonce);
                cipher
                    .encrypt_in_place_detached(nonce, associated_data, buffer)
                    .map_err(|_| Error::Eax)?
            }
            (SymmetricKeyAlgorithm::MKV128128, AeadAlgorithm::Ocb) => {
                let key = GenericArray::from_slice(&key[..16]);
                let nonce = Ocb3Nonce::from_slice(nonce);
                let cipher = Mkv128128Ocb3::new(key);
                cipher
                    .encrypt_in_place_detached(nonce, associated_data, buffer)
                    .map_err(|_| Error::Ocb)?
            }
            (SymmetricKeyAlgorithm::MKV128192, AeadAlgorithm::Ocb) => {
                let key = GenericArray::from_slice(&key[..24]);
                let nonce = Ocb3Nonce::from_slice(nonce);
                let cipher = Mkv128192Ocb3::new(key);
                cipher
                    .encrypt_in_place_detached(nonce, associated_data, buffer)
                    .map_err(|_| Error::Ocb)?
            }
            (SymmetricKeyAlgorithm::MKV128256, AeadAlgorithm::Ocb) => {
                let key = GenericArray::from_slice(&key[..32]);
                let nonce = Ocb3Nonce::from_slice(nonce);
                let cipher = Mkv128256Ocb3::new(key);
                cipher
                    .encrypt_in_place_detached(nonce, associated_data, buffer)
                    .map_err(|_| Error::Ocb)?
            }
            _ => unimplemented_err!("AEAD not supported: {:?}, {:?}", sym_algorithm, self),
        };

        Ok(tag.to_vec())
    }
}