use core::str::FromStr;
use crate::{
error::InvalidAlgorithmError, keyring::KEY_ID_LEN, strings::to_upper_remove_seperators,
};
use super::{
size::{AES_128_GCM, AES_256_GCM, CHACHA20_POLY1305, XCHACHA20_POLY1305},
Method,
};
use alloc::string::ToString;
use serde::{Deserialize, Serialize};
use strum::{Display, EnumIter, IntoStaticStr};
use super::Size;
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
Hash,
Serialize,
Deserialize,
IntoStaticStr,
Display,
EnumIter,
)]
pub enum Algorithm {
#[serde(rename = "AES-128-GCM")]
#[strum(serialize = "AES-128-GCM")]
Aes128Gcm = 0,
#[serde(rename = "AES-256-GCM")]
#[strum(serialize = "AES-256-GCM")]
Aes256Gcm = 1,
#[serde(rename = "ChaCha20-Poly1305")]
#[strum(serialize = "ChaCha20-Poly1305")]
ChaCha20Poly1305 = 2,
#[serde(rename = "XChaCha20-Poly1305")]
#[strum(serialize = "XChaCha20-Poly1305")]
XChaCha20Poly1305 = 3,
}
impl Algorithm {
fn size(&self) -> Size {
match self {
Algorithm::Aes128Gcm => AES_128_GCM,
Algorithm::Aes256Gcm => AES_256_GCM,
Algorithm::ChaCha20Poly1305 => CHACHA20_POLY1305,
Algorithm::XChaCha20Poly1305 => XCHACHA20_POLY1305,
}
}
pub fn nonce_len(&self) -> usize {
self.size().nonce
}
pub fn key_len(&self) -> usize {
self.size().key
}
pub fn tag_len(&self) -> usize {
self.size().tag
}
pub fn nonce_prefix_len(&self) -> usize {
self.size().nonce - 4 - 1
}
pub fn online_header_len(&self) -> usize {
Method::LEN + KEY_ID_LEN + self.nonce_len()
}
pub fn streaming_header_len(&self) -> usize {
Method::LEN + KEY_ID_LEN + self.nonce_prefix_len() + self.key_len()
}
}
impl From<Algorithm> for u8 {
fn from(alg: Algorithm) -> Self {
alg as u8
}
}
impl FromStr for Algorithm {
type Err = InvalidAlgorithmError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match to_upper_remove_seperators(s).as_str() {
"AES128GCM" => Ok(Algorithm::Aes128Gcm),
"AES256GCM" => Ok(Algorithm::Aes256Gcm),
"CHACHA20POLY1305" => Ok(Algorithm::ChaCha20Poly1305),
"XCHACHA20POLY1305" => Ok(Algorithm::XChaCha20Poly1305),
_ => Err(InvalidAlgorithmError(s.to_string())),
}
}
}