diff --git a/aes/src/block/block128.rs b/aes/src/block/block128.rs index 814c416..eee3c9f 100644 --- a/aes/src/block/block128.rs +++ b/aes/src/block/block128.rs @@ -107,7 +107,7 @@ fn parse_radix(s: &str, radix: u32) -> Result { } fn ascii_string_to_u128(s: &str) -> Result { - if s.len() > 8 { + if s.len() > 16 { return Err(BlockError::InvalidByteStringLength(s.len())); } diff --git a/cipher-core/src/traits/block_cipher.rs b/cipher-core/src/traits/block_cipher.rs index dd91a45..7a79773 100644 --- a/cipher-core/src/traits/block_cipher.rs +++ b/cipher-core/src/traits/block_cipher.rs @@ -5,7 +5,7 @@ use crate::{CipherAction, CipherError, CipherResult, Output}; /// Implements the standard encrypt/decrypt interface for block ciphers. /// Implementers define `transform_impl` to handle the core algorithm, /// while `transform` provides validation and convenience wrappers. -pub trait BlockCipher: Sized { +pub trait BlockCipher { const BLOCK_SIZE: usize; fn from_key(key: &[u8]) -> Self; diff --git a/cipher-factory/src/algorithm.rs b/cipher-factory/src/algorithm.rs index 9f7ddf6..1dbb7a1 100644 --- a/cipher-factory/src/algorithm.rs +++ b/cipher-factory/src/algorithm.rs @@ -1,5 +1,3 @@ -use cipher_core::{BlockCipher, InputBlock}; -use des::Des; use std::fmt::Display; #[cfg_attr(feature = "clap", derive(clap::ValueEnum))] @@ -9,16 +7,6 @@ pub enum Algorithm { Aes, } -impl Algorithm { - #[must_use] - pub fn get_cipher(&self, key: &impl InputBlock) -> impl BlockCipher { - match self { - Self::Des => Des::from_key(key.as_bytes()), - Self::Aes => todo!("Must implement AES first"), - } - } -} - impl Display for Algorithm { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let s = match self { diff --git a/cipher-factory/src/output.rs b/cipher-factory/src/output.rs index 6d66a95..1ee6b98 100644 --- a/cipher-factory/src/output.rs +++ b/cipher-factory/src/output.rs @@ -18,9 +18,9 @@ impl OutputFormat { #[must_use] pub fn to_string(&self, value: &Output) -> String { match self { - Self::Binary => format!("{value:064b}"), - Self::Octal => format!("{value:022o}"), - Self::Hex => format!("{value:016X}"), + Self::Binary => format!("{value:b}"), + Self::Octal => format!("{value:o}"), + Self::Hex => format!("{value:X}"), Self::Text => format!("{value}"), } } diff --git a/cli/src/args.rs b/cli/src/args.rs index 40d94d6..6abd58b 100644 --- a/cli/src/args.rs +++ b/cli/src/args.rs @@ -1,7 +1,5 @@ use cipher_factory::{Algorithm, OperationChoice, OutputFormat}; use clap::Parser; -use des::Block64; -use std::str::FromStr; #[derive(Debug, Clone, Parser)] #[command(version, about, long_about = None)] @@ -15,12 +13,12 @@ pub struct Args { pub algorithm: Algorithm, /// Key used for encryption/decryption. Can be a string or a path to a file - #[arg(short, long, value_parser = Block64::from_str, required = true)] - pub key: Block64, + #[arg(short, long, required = true)] + pub key: String, /// The text to encrypt/decrypt. Can be a string or a path to a file - #[arg(value_name = "TEXT", value_parser = Block64::from_str, required = true)] - pub text: Block64, + #[arg(value_name = "TEXT", required = true)] + pub text: String, /// Output format for decrypted data #[arg(short = 'f', long)] diff --git a/cli/src/main.rs b/cli/src/main.rs index 8548557..bc01a55 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,11 +1,15 @@ mod args; use crate::args::Args; +use aes::{Aes, Block128}; use cipher_core::BlockCipher; -use cipher_factory::OperationChoice; +use cipher_factory::{Algorithm, OperationChoice, OutputFormat}; use clap::Parser; +use color_eyre::eyre::{Ok, Result}; +use des::{Block64, Des}; +use std::str::FromStr; -fn main() -> color_eyre::Result<()> { +fn main() -> Result<()> { color_eyre::install()?; let Args { operation, @@ -15,18 +19,40 @@ fn main() -> color_eyre::Result<()> { output_format, } = Args::parse(); - match operation { - OperationChoice::Encrypt => { - let cipher = algorithm.get_cipher(&key); - let ciphertext = cipher.encrypt(&text.to_be_bytes())?; - println!("{ciphertext:016X}"); + match algorithm { + Algorithm::Des => { + let key = Block64::from_str(&key)?; + let text = Block64::from_str(&text)?; + let cipher = Des::from_key(&key.to_be_bytes()); + execute_cipher(operation, &cipher, &text.to_be_bytes(), output_format)?; } - OperationChoice::Decrypt => { - let cipher = algorithm.get_cipher(&key); - let plaintext = cipher.decrypt(&text.to_be_bytes())?; - let output = output_format.unwrap_or_default().to_string(&plaintext); - println!("{output}"); + Algorithm::Aes => { + let key = Block128::from_str(&key)?; + let text = Block128::from_str(&text)?; + let cipher = Aes::from_key(&key.to_be_bytes()); + execute_cipher(operation, &cipher, &text.to_be_bytes(), output_format)?; } } Ok(()) } + +fn execute_cipher( + operation: OperationChoice, + cipher: &impl BlockCipher, + text_bytes: &[u8], + output_format: Option, +) -> Result<()> { + match operation { + OperationChoice::Encrypt => { + let ciphertext = cipher.encrypt(text_bytes)?; + println!("{ciphertext:X}"); + } + OperationChoice::Decrypt => { + let plaintext = cipher.decrypt(text_bytes)?; + let output = output_format.unwrap_or_default().to_string(&plaintext); + println!("{output}"); + } + } + + Ok(()) +}