~kf5jwc/cryptopals-challenges

6093e1ec8710f4a441e48cc6af4bcb734f170590 — Kyle Jones 1 year, 6 months ago 1d69748
Implement CTR mode oracle
3 files changed, 51 insertions(+), 0 deletions(-)

M aes/src/oracles.rs
A aes/src/oracles/mode_ctr.rs
M aes/src/oracles/traits.rs
M aes/src/oracles.rs => aes/src/oracles.rs +3 -0
@@ 2,16 2,19 @@ mod mode_random;
mod mode_ecb;
mod mode_ecb_random_prefix;
mod mode_cbc;
mod mode_ctr;
mod traits;

pub use self::mode_random::RandomModeOracle;
pub use self::mode_ecb::ECBOracle;
pub use self::mode_ecb_random_prefix:: ECBRandomPrefixOracle;
pub use self::mode_cbc::CBCOracle;
pub use self::mode_ctr::CTROracle;
pub use self::traits::{
    EncryptionOracle,
    DecryptionOracle,
    MaskedDecryptionOracle,
    CTRRound,
    BlockSizeDetector,
    PrefixDetector,
    KeyProvider,

A aes/src/oracles/mode_ctr.rs => aes/src/oracles/mode_ctr.rs +44 -0
@@ 0,0 1,44 @@
use crate::ctr;
use crate::BLOCK_SIZE;
use crypto::symmetriccipher::SymmetricCipherError;
use super::traits::{
    CTRRound,
};

pub struct CTROracle {
    key: Vec<u8>,
    nonce: u64,
    count: u64,
}

impl CTROracle {
    pub fn new(key: &[u8], nonce: &u64, count: &u64) -> Self {
        Self {
            key: key.to_vec(),
            nonce: *nonce,
            count: *count,
        }
    }
}

impl CTRRound for CTROracle {
    // I'm not sure how to handle an error in this function.
    //
    // Reusing nonces or counter values is bad, but does this
    // matter when an error happens which prevents data return?
    // Should I always rotate the count, or should I break the
    // oracle entirely to prevent misuse/confusion if you manage
    // to create a ciphertext with counts which aren't in line?
    fn round(&mut self, data: &[u8]) -> Result<Vec<u8>, SymmetricCipherError> {
        // CTR format, per this challenge, is 128 bits, 16 bytes
        assert!(data.len() <= BLOCK_SIZE);
        eprintln!("data:      {:?}", data);
        let block = ctr::round(&self.key,
                                      &self.nonce,
                                      &self.count,
                                      data,
                                      );
        self.count += 1;
        block
    }
}

M aes/src/oracles/traits.rs => aes/src/oracles/traits.rs +4 -0
@@ 13,6 13,10 @@ pub trait MaskedDecryptionOracle {
    fn decrypt(&self, ciphertext: &[u8], iv: &[u8], mask: &[u8]) -> Result<Vec<u8>, SymmetricCipherError>;
}

pub trait CTRRound {
    fn round(&mut self, data: &[u8]) -> Result<Vec<u8>, SymmetricCipherError>;
}

pub trait BlockSizeDetector {
    fn block_size(&self) -> Result<usize, SymmetricCipherError>;
}