diff --git a/crypto/src/aes_fruity.rs b/crypto/src/aes_fruity.rs index 4305df43f..2a5e1e542 100644 --- a/crypto/src/aes_fruity.rs +++ b/crypto/src/aes_fruity.rs @@ -97,7 +97,7 @@ impl AesGcm { } #[inline(always)] - pub fn reset_init_gcm(&self, iv: &[u8]) { + pub fn reset_init_gcm(&mut self, iv: &[u8]) { assert_eq!(iv.len(), 12); unsafe { assert_eq!(CCCryptorGCMReset(self.0), 0); @@ -106,14 +106,14 @@ impl AesGcm { } #[inline(always)] - pub fn aad(&self, aad: &[u8]) { + pub fn aad(&mut self, aad: &[u8]) { unsafe { assert_eq!(CCCryptorGCMAddAAD(self.0, aad.as_ptr().cast(), aad.len()), 0); } } #[inline(always)] - pub fn crypt(&self, input: &[u8], output: &mut [u8]) { + pub fn crypt(&mut self, input: &[u8], output: &mut [u8]) { unsafe { assert_eq!(input.len(), output.len()); if ENCRYPT { @@ -131,7 +131,7 @@ impl AesGcm { } #[inline(always)] - pub fn crypt_in_place(&self, data: &mut [u8]) { + pub fn crypt_in_place(&mut self, data: &mut [u8]) { unsafe { if ENCRYPT { assert_eq!(CCCryptorGCMEncrypt(self.0, data.as_ptr().cast(), data.len(), data.as_mut_ptr().cast()), 0); @@ -142,7 +142,7 @@ impl AesGcm { } #[inline(always)] - fn finish(&self) -> [u8; 16] { + fn finish(&mut self) -> [u8; 16] { let mut tag = 0_u128.to_ne_bytes(); unsafe { let mut tag_len = 16; @@ -159,14 +159,14 @@ impl AesGcm { impl AesGcm { /// Produce the gcm authentication tag. #[inline(always)] - pub fn finish_encrypt(&self) -> [u8; 16] { + pub fn finish_encrypt(&mut self) -> [u8; 16] { self.finish() } } impl AesGcm { /// Check the gcm authentication tag. Outputs true if it matches the just decrypted message, outputs false otherwise. #[inline(always)] - pub fn finish_decrypt(&self, expected_tag: &[u8]) -> bool { + pub fn finish_decrypt(&mut self, expected_tag: &[u8]) -> bool { secure_eq(&self.finish(), expected_tag) } } @@ -229,7 +229,7 @@ impl Aes { } #[inline(always)] - pub fn encrypt_block_in_place(&self, data: &mut [u8]) { + pub fn encrypt_block_in_place(&mut self, data: &mut [u8]) { assert_eq!(data.len(), 16); unsafe { let mut data_out_written = 0; @@ -238,7 +238,7 @@ impl Aes { } #[inline(always)] - pub fn decrypt_block_in_place(&self, data: &mut [u8]) { + pub fn decrypt_block_in_place(&mut self, data: &mut [u8]) { assert_eq!(data.len(), 16); unsafe { let mut data_out_written = 0; diff --git a/crypto/src/aes_openssl.rs b/crypto/src/aes_openssl.rs index 14c5835c6..7b46ddd9e 100644 --- a/crypto/src/aes_openssl.rs +++ b/crypto/src/aes_openssl.rs @@ -34,7 +34,7 @@ impl AesGcm { /// Set the IV of this AesGcm context. This call resets the IV but leaves the key and encryption algorithm alone. /// This method must be called before any other method on AesGcm. /// `iv` must be exactly 12 bytes in length, because that is what Aes supports. - pub fn reset_init_gcm(&self, iv: &[u8]) { + pub fn reset_init_gcm(&mut self, iv: &[u8]) { debug_assert_eq!(iv.len(), 12, "Aes IV must be 12 bytes long"); unsafe { self.0.cipher_init::(ptr::null(), ptr::null(), iv.as_ptr()).unwrap(); @@ -43,20 +43,20 @@ impl AesGcm { /// Add additional authentication data to AesGcm (same operation with CTR mode). #[inline(always)] - pub fn aad(&self, aad: &[u8]) { + pub fn aad(&mut self, aad: &[u8]) { unsafe { self.0.update::(aad, ptr::null_mut()).unwrap() }; } /// Encrypt or decrypt (same operation with CTR mode) #[inline(always)] - pub fn crypt(&self, input: &[u8], output: &mut [u8]) { + pub fn crypt(&mut self, input: &[u8], output: &mut [u8]) { debug_assert!(output.len() >= input.len(), "output buffer must fit the size of the input buffer"); unsafe { self.0.update::(input, output.as_mut_ptr()).unwrap() }; } /// Encrypt or decrypt in place (same operation with CTR mode). #[inline(always)] - pub fn crypt_in_place(&self, data: &mut [u8]) { + pub fn crypt_in_place(&mut self, data: &mut [u8]) { let ptr = data.as_mut_ptr(); unsafe { self.0.update::(data, ptr).unwrap() } } @@ -64,7 +64,7 @@ impl AesGcm { impl AesGcm { /// Produce the gcm authentication tag. #[inline(always)] - pub fn finish_encrypt(&self) -> [u8; 16] { + pub fn finish_encrypt(&mut self) -> [u8; 16] { unsafe { let mut tag = MaybeUninit::<[u8; 16]>::uninit(); self.0.finalize::(tag.as_mut_ptr().cast()).unwrap(); @@ -76,7 +76,7 @@ impl AesGcm { impl AesGcm { /// Check the gcm authentication tag. Outputs true if it matches the just decrypted message, outputs false otherwise. #[inline(always)] - pub fn finish_decrypt(&self, expected_tag: &[u8]) -> bool { + pub fn finish_decrypt(&mut self, expected_tag: &[u8]) -> bool { debug_assert_eq!(expected_tag.len(), 16); if self.0.set_tag(expected_tag).is_ok() { unsafe { self.0.finalize::(ptr::null_mut()).is_ok() } @@ -116,14 +116,14 @@ impl Aes { /// Do not ever encrypt the same plaintext twice. Make sure data is always different between calls. #[inline(always)] - pub fn encrypt_block_in_place(&self, data: &mut [u8]) { + pub fn encrypt_block_in_place(&mut self, data: &mut [u8]) { debug_assert_eq!(data.len(), AES_BLOCK_SIZE, "AesEcb should not be used to encrypt more than one block at a time unless you really know what you are doing."); let ptr = data.as_mut_ptr(); unsafe { self.0.update::(data, ptr).unwrap() } } /// Do not ever encrypt the same plaintext twice. Make sure data is always different between calls. #[inline(always)] - pub fn decrypt_block_in_place(&self, data: &mut [u8]) { + pub fn decrypt_block_in_place(&mut self, data: &mut [u8]) { debug_assert_eq!(data.len(), AES_BLOCK_SIZE, "AesEcb should not be used to encrypt more than one block at a time unless you really know what you are doing."); let ptr = data.as_mut_ptr(); unsafe { self.1.update::(data, ptr).unwrap() } diff --git a/crypto/src/aes_tests.rs b/crypto/src/aes_tests.rs index 7b3e1992e..868093d0b 100644 --- a/crypto/src/aes_tests.rs +++ b/crypto/src/aes_tests.rs @@ -12,8 +12,8 @@ mod test { fn aes_256_gcm() { init(); let key = Secret::move_bytes([1u8; 32]); - let enc = AesGcm::::new(&key); - let dec = AesGcm::::new(&key); + let mut enc = AesGcm::::new(&key); + let mut dec = AesGcm::::new(&key); let plain = [2u8; 127]; let iv0 = [3u8; 12]; @@ -59,7 +59,7 @@ mod test { } let iv = [1_u8; 12]; - let c = AesGcm::::new(&Secret::move_bytes([1_u8; 32])); + let mut c = AesGcm::::new(&Secret::move_bytes([1_u8; 32])); let benchmark_iterations: usize = 80000; let start = SystemTime::now(); @@ -73,7 +73,7 @@ mod test { (((benchmark_iterations * buf.len()) as f64) / 1048576.0) / duration.as_secs_f64() ); - let c = AesGcm::::new(&Secret::move_bytes([1_u8; 32])); + let mut c = AesGcm::::new(&Secret::move_bytes([1_u8; 32])); let start = SystemTime::now(); for _ in 0..benchmark_iterations { @@ -91,7 +91,7 @@ mod test { fn aes_gcm_test_vectors() { // Even though we are just wrapping other implementations, it's still good to test thoroughly! for tv in NIST_AES_GCM_TEST_VECTORS.iter() { - let gcm = AesGcm::new(unsafe { &Secret::<32>::from_bytes(tv.key) }); + let mut gcm = AesGcm::new(unsafe { &Secret::<32>::from_bytes(tv.key) }); gcm.reset_init_gcm(tv.nonce); gcm.aad(tv.aad); let mut ciphertext = Vec::new(); @@ -101,7 +101,7 @@ mod test { assert!(tag.eq(tv.tag)); assert!(ciphertext.as_slice().eq(tv.ciphertext)); - let gcm = AesGcm::new(unsafe { &Secret::<32>::from_bytes(tv.key) }); + let mut gcm = AesGcm::new(unsafe { &Secret::<32>::from_bytes(tv.key) }); gcm.reset_init_gcm(tv.nonce); gcm.aad(tv.aad); let mut ct_copy = ciphertext.clone(); diff --git a/crypto/src/hash.rs b/crypto/src/hash.rs index 4113a7352..e71472b9c 100644 --- a/crypto/src/hash.rs +++ b/crypto/src/hash.rs @@ -281,7 +281,7 @@ pub fn hmac_sha512_secret(key: &[u8], msg: &[u8]) -> Secret { let mut hm = HMACSHA512::new(key); hm.update(msg); let buff = hm.finish(); - unsafe { Secret::from_bytes(&buff) } + unsafe { Secret::from_bytes(&buff[..C]) } } #[inline(always)] diff --git a/crypto/src/secret.rs b/crypto/src/secret.rs index fb946ff38..79c3727b2 100644 --- a/crypto/src/secret.rs +++ b/crypto/src/secret.rs @@ -35,12 +35,9 @@ impl Secret { /// Copy bytes into secret, then nuke the previous value, will panic if the slice does not match the size of this secret. #[inline(always)] pub fn from_bytes_then_nuke(b: &mut [u8]) -> Self { - let mut k = [0u8; L]; - k.copy_from_slice(b); - unsafe { - OPENSSL_cleanse(b.as_mut_ptr().cast(), L) - }; - Self (k) + let ret = Self (b.try_into().unwrap()); + unsafe { OPENSSL_cleanse(b.as_mut_ptr().cast(), L) }; + ret } #[inline(always)] pub unsafe fn from_bytes(b: &[u8]) -> Self {