summaryrefslogtreecommitdiffstats
path: root/openpgp/src/crypto/backend/cng/symmetric.rs
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp/src/crypto/backend/cng/symmetric.rs')
-rw-r--r--openpgp/src/crypto/backend/cng/symmetric.rs180
1 files changed, 0 insertions, 180 deletions
diff --git a/openpgp/src/crypto/backend/cng/symmetric.rs b/openpgp/src/crypto/backend/cng/symmetric.rs
index a4a140eb..7d8281e7 100644
--- a/openpgp/src/crypto/backend/cng/symmetric.rs
+++ b/openpgp/src/crypto/backend/cng/symmetric.rs
@@ -68,74 +68,6 @@ impl Mode for cng::SymmetricAlgorithmKey {
}
}
-/// CTR mode using a block cipher. CNG doesn't implement one so roll our own
-/// using CNG's ECB mode.
-pub struct Ctr {
- key: cng::SymmetricAlgorithmKey,
- ctr: Option<Box<[u8]>>,
-}
-
-impl Ctr {
- pub fn with_cipher_and_iv(algo: cng::SymmetricAlgorithmId, key: &[u8], iv: &[u8]) -> Result<Ctr> {
- let algo = cng::SymmetricAlgorithm::open(algo, cng::ChainingMode::Ecb)?;
- let key = algo.new_key(key)?;
- // TODO: Check iv len
- Ok(Ctr { key, ctr: Some(iv.into()) })
- }
-
- pub fn encrypt(&mut self, dst: &mut [u8], src: &[u8]) -> Result<()> {
- let mut ctr = self.ctr.take().unwrap();
- Mode::encrypt(self, &mut ctr, dst, src)?;
- self.ctr = Some(ctr);
- Ok(())
- }
-
- pub fn decrypt(&mut self, dst: &mut [u8], src: &[u8]) -> Result<()> {
- let mut ctr = self.ctr.take().unwrap();
- Mode::decrypt(self, &mut ctr, dst, src)?;
- self.ctr = Some(ctr);
- Ok(())
- }
-}
-
-impl Mode for Ctr {
- fn block_size(&self) -> usize {
- self.key.block_size().expect("CNG not to fail internally")
- }
-
- fn encrypt(&mut self, iv: &mut [u8], dst: &mut [u8], src: &[u8]) -> Result<()> {
- let block = self.block_size();
-
- // Ciphertext_i <- BlockCipher(Counter_i) ⊕ Plaintext_i
- for (dst, src) in dst.chunks_mut(block).zip(src.chunks(block)) {
- let res = cng::SymmetricAlgorithmKey::encrypt(&self.key, None, iv, None)?;
- wrapping_increment_be(iv.as_mut());
-
- for (dst, (res, src)) in dst.iter_mut().zip(res.as_slice().iter().zip(src.iter())) {
- *dst = res ^ src;
- }
- }
-
- Ok(())
- }
-
- fn decrypt(&mut self, iv: &mut [u8], dst: &mut [u8], src: &[u8]) -> Result<()> {
- let block = self.block_size();
-
- // Plaintext_i <- BlockCipher(Counter_i) ⊕ Ciphertext_i
- for (dst, src) in dst.chunks_mut(block).zip(src.chunks(block)) {
- let res = cng::SymmetricAlgorithmKey::encrypt(&self.key, None, iv, None)?;
- wrapping_increment_be(iv.as_mut());
-
- for (dst, (res, src)) in dst.iter_mut().zip(res.as_slice().iter().zip(src.iter())) {
- *dst = res ^ src;
- }
- }
-
- Ok(())
- }
-}
-
#[derive(Debug, thiserror::Error)]
#[error("Unsupported algorithm: {0}")]
pub struct UnsupportedAlgorithm(SymmetricAlgorithm);
@@ -253,115 +185,3 @@ impl SymmetricAlgorithm {
))
}
}
-
-fn wrapping_increment_be(value: &mut [u8]) -> &mut [u8] {
- for val in value.iter_mut().rev() {
- *val = val.wrapping_add(1);
- // Stop carryover
- if *val != 0x00 {
- break;
- }
- }
-
- value
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use std::borrow::Borrow;
-
- trait HexSlice: Borrow<str> {
- fn as_hex(&self) -> Vec<u8> {
- let res: Vec<u8> = self.borrow().as_bytes().rchunks(2)
- .map(|slice| std::str::from_utf8(slice).unwrap())
- .map(|chr| u8::from_str_radix(chr, 16).unwrap())
- .rev()
- .collect();
- res
- }
- }
- impl<'a> HexSlice for &'a str {}
-
- #[test]
- fn hex_slice() {
- assert_eq!("0a".as_hex(), &[0x0A]);
- assert_eq!("a".as_hex(), &[0x0A]);
- assert_eq!("FE0a".as_hex(), &[0xFE, 0x0A]);
- assert_eq!("E0a".as_hex(), &[0x0E, 0x0A]);
- }
-
- #[test]
- fn wrapping_increment_be() {
- assert_eq!(super::wrapping_increment_be(&mut [0x00]), [0x01]);
- assert_eq!(super::wrapping_increment_be(&mut [0xFF, 0xFF]), [0x00, 0x00]);
- assert_eq!(super::wrapping_increment_be(&mut [0xFD, 0xFF]), [0xFE, 0x00]);
-
- let input = &mut "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff".as_hex();
- let expected = &"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00".as_hex();
-
- assert_eq!(super::wrapping_increment_be(input).as_ref(), expected.as_slice());
- }
-
- #[test]
- fn ctr_aes_128() {
- // NIST SP800-38a test vectors
- // F.5.1 CTR-AES128.Encrypt
- let key = &"2b7e151628aed2a6abf7158809cf4f3c".as_hex();
- assert_eq!(key.len(), 16);
- let mut ctr = Ctr::with_cipher_and_iv(
- cng::SymmetricAlgorithmId::Aes,
- key,
- &"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff".as_hex(),
- ).unwrap();
-
- let plain = &"6bc1bee22e409f96e93d7e117393172a".as_hex();
- let mut cipher = vec![0u8; 16];
- ctr.encrypt(&mut cipher, plain).unwrap();
- assert_eq!(&cipher, &"874d6191b620e3261bef6864990db6ce".as_hex());
-
- let plain = &"ae2d8a571e03ac9c9eb76fac45af8e51".as_hex();
- let mut cipher = vec![0u8; 16];
- ctr.encrypt(&mut cipher, plain).unwrap();
- assert_eq!(&cipher, &"9806f66b7970fdff8617187bb9fffdff".as_hex());
-
- let plain = &"30c81c46a35ce411e5fbc1191a0a52ef".as_hex();
- let mut cipher = vec![0u8; 16];
- ctr.encrypt(&mut cipher, plain).unwrap();
- assert_eq!(&cipher, &"5ae4df3edbd5d35e5b4f09020db03eab".as_hex());
-
- let plain = &"f69f2445df4f9b17ad2b417be66c3710".as_hex();
- let mut cipher = vec![0u8; 16];
- ctr.encrypt(&mut cipher, plain).unwrap();
- assert_eq!(&cipher, &"1e031dda2fbe03d1792170a0f3009cee".as_hex());
-
- // F.5.2 CTR-AES128.Decrypt
- let key = &"2b7e151628aed2a6abf7158809cf4f3c".as_hex();
- assert_eq!(key.len(), 16);
- let mut ctr = Ctr::with_cipher_and_iv(
- cng::SymmetricAlgorithmId::Aes,
- key,
- &"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff".as_hex(),
- ).unwrap();
-
- let plain = &"874d6191b620e3261bef6864990db6ce".as_hex();
- let mut cipher = vec![0u8; 16];
- ctr.decrypt(&mut cipher, plain).unwrap();
- assert_eq!(&cipher, &"6bc1bee22e409f96e93d7e117393172a".as_hex());
-
- let plain = &"9806f66b7970fdff8617187bb9fffdff".as_hex();
- let mut cipher = vec![0u8; 16];
- ctr.decrypt(&mut cipher, plain).unwrap();
- assert_eq!(&cipher, &"ae2d8a571e03ac9c9eb76fac45af8e51".as_hex());
-
- let plain = &"5ae4df3edbd5d35e5b4f09020db03eab".as_hex();
- let mut cipher = vec![0u8; 16];
- ctr.decrypt(&mut cipher, plain).unwrap();
- assert_eq!(&cipher, &"30c81c46a35ce411e5fbc1191a0a52ef".as_hex());
-
- let plain = &"1e031dda2fbe03d1792170a0f3009cee".as_hex();
- let mut cipher = vec![0u8; 16];
- ctr.decrypt(&mut cipher, plain).unwrap();
- assert_eq!(&cipher, &"f69f2445df4f9b17ad2b417be66c3710".as_hex());
- }
-}