1 use crate::{openssl_err, ossl}; 2 use alloc::boxed::Box; 3 use alloc::vec::Vec; 4 use kmr_common::{crypto, crypto::OpaqueOr, explicit, vec_try, Error}; 5 use openssl::symm::{Cipher, Crypter}; 6 7 /// [`crypto::Des`] implementation based on BoringSSL. 8 pub struct BoringDes; 9 10 impl crypto::Des for BoringDes { begin( &self, key: OpaqueOr<crypto::des::Key>, mode: crypto::des::Mode, dir: crypto::SymmetricOperation, ) -> Result<Box<dyn crypto::EmittingOperation>, Error>11 fn begin( 12 &self, 13 key: OpaqueOr<crypto::des::Key>, 14 mode: crypto::des::Mode, 15 dir: crypto::SymmetricOperation, 16 ) -> Result<Box<dyn crypto::EmittingOperation>, Error> { 17 let key = explicit!(key)?; 18 let dir_mode = match dir { 19 crypto::SymmetricOperation::Encrypt => openssl::symm::Mode::Encrypt, 20 crypto::SymmetricOperation::Decrypt => openssl::symm::Mode::Decrypt, 21 }; 22 let crypter = match mode { 23 crypto::des::Mode::EcbNoPadding | crypto::des::Mode::EcbPkcs7Padding => { 24 let cipher = Cipher::des_ede3(); 25 let mut crypter = Crypter::new(cipher, dir_mode, &key.0, None) 26 .map_err(openssl_err!("failed to create ECB Crypter"))?; 27 if let crypto::des::Mode::EcbPkcs7Padding = mode { 28 crypter.pad(true); 29 } else { 30 crypter.pad(false); 31 } 32 crypter 33 } 34 35 crypto::des::Mode::CbcNoPadding { nonce: n } 36 | crypto::des::Mode::CbcPkcs7Padding { nonce: n } => { 37 let cipher = Cipher::des_ede3_cbc(); 38 let mut crypter = Crypter::new(cipher, dir_mode, &key.0, Some(&n[..])) 39 .map_err(openssl_err!("failed to create CBC Crypter"))?; 40 if let crypto::des::Mode::CbcPkcs7Padding { nonce: _ } = mode { 41 crypter.pad(true); 42 } else { 43 crypter.pad(false); 44 } 45 crypter 46 } 47 }; 48 49 Ok(Box::new(BoringDesOperation { crypter })) 50 } 51 } 52 53 /// [`crypto::DesOperation`] implementation based on BoringSSL. 54 pub struct BoringDesOperation { 55 crypter: openssl::symm::Crypter, 56 } 57 58 impl crypto::EmittingOperation for BoringDesOperation { update(&mut self, data: &[u8]) -> Result<Vec<u8>, Error>59 fn update(&mut self, data: &[u8]) -> Result<Vec<u8>, Error> { 60 let mut output = vec_try![0; data.len() + crypto::des::BLOCK_SIZE]?; 61 let out_len = self 62 .crypter 63 .update(data, &mut output[..]) 64 .map_err(openssl_err!("update with {} bytes of data failed", data.len()))?; 65 output.truncate(out_len); 66 Ok(output) 67 } 68 finish(mut self: Box<Self>) -> Result<Vec<u8>, Error>69 fn finish(mut self: Box<Self>) -> Result<Vec<u8>, Error> { 70 let mut output = vec_try![0; crypto::des::BLOCK_SIZE]?; 71 let out_len = ossl!(self.crypter.finalize(&mut output))?; 72 output.truncate(out_len); 73 Ok(output) 74 } 75 } 76