diff --git a/src/modules/crypto/crypto_adaptors/tongsuo_adaptor.rs b/src/modules/crypto/crypto_adaptors/tongsuo_adaptor.rs index b70103f..f24af52 100644 --- a/src/modules/crypto/crypto_adaptors/tongsuo_adaptor.rs +++ b/src/modules/crypto/crypto_adaptors/tongsuo_adaptor.rs @@ -420,7 +420,48 @@ impl BlockCipher for SM4 { fn encrypt_update(&mut self, plaintext: Vec, ciphertext: &mut Vec ) -> Result { - Err(RvError::ErrCryptoCipherOPNotSupported) + let cipher; + + match self.mode { + CipherMode::CBC => { + cipher = Cipher::sm4_cbc(); + } + CipherMode::GCM => { + cipher = Cipher::sm4_gcm(); + } + _ => { return Err(RvError::ErrCryptoCipherOPNotSupported); } + } + + if let None = self.ctx { + // init adaptor ctx if it's not inited. + let encrypter = Crypter::new( + cipher, + Mode::Encrypt, + &self.key, + Some(&self.iv) + ).unwrap(); + let adaptor_ctx = AdaptorCTX { ctx: encrypter, tag_set: false, aad_set: false }; + + self.ctx = Some(adaptor_ctx); + } + + if self.mode == CipherMode::GCM || self.mode == CipherMode::CCM { + // set additional authenticated data before doing real jobs. + if self.ctx.as_mut().unwrap().aad_set == false { + if let Some(aad) = &self.aad { + self.ctx.as_mut().unwrap().ctx.aad_update(aad).unwrap(); + self.ctx.as_mut().unwrap().aad_set = true; + } + } + } + + // do real jobs. + // this Crypter::update returns a Result, we simply ignore the detailed + // error information by unwrapping it. + // we also can't use the question mark operatior since the error codes are differently + // defined in RustyVault and underlying adaptor, such as rust-openssl. + let count = self.ctx.as_mut().unwrap().ctx.update(&plaintext, &mut ciphertext[..]).unwrap(); + Ok(count) } fn encrypt_final(&mut self, ciphertext: &mut Vec ) -> Result {