diff --git a/crypto/src/aes_fruity.rs b/crypto/src/aes_fruity.rs index 07172420e..4305df43f 100644 --- a/crypto/src/aes_fruity.rs +++ b/crypto/src/aes_fruity.rs @@ -1,373 +1,248 @@ // (c) 2020-2022 ZeroTier, Inc. -- currently proprietary pending actual release and licensing. See LICENSE.md. // MacOS implementation of AES primitives since CommonCrypto seems to be faster than OpenSSL, especially on ARM64. -#[cfg(target_os = "macos")] -mod fruit_flavored { - use std::os::raw::{c_int, c_void}; - use std::ptr::{null, null_mut}; +use std::os::raw::{c_int, c_void}; +use std::ptr::{null, null_mut}; - use crate::secure_eq; +use crate::secret::Secret; +use crate::secure_eq; - #[allow(non_upper_case_globals, unused)] - const kCCModeECB: i32 = 1; - #[allow(non_upper_case_globals, unused)] - const kCCModeCTR: i32 = 4; - #[allow(non_upper_case_globals, unused)] - const kCCModeGCM: i32 = 11; - #[allow(non_upper_case_globals, unused)] - const kCCEncrypt: i32 = 0; - #[allow(non_upper_case_globals, unused)] - const kCCDecrypt: i32 = 1; - #[allow(non_upper_case_globals, unused)] - const kCCAlgorithmAES: i32 = 0; - #[allow(non_upper_case_globals, unused)] - const kCCOptionECBMode: i32 = 2; +#[allow(non_upper_case_globals, unused)] +const kCCModeECB: i32 = 1; +#[allow(non_upper_case_globals, unused)] +const kCCModeCTR: i32 = 4; +#[allow(non_upper_case_globals, unused)] +const kCCModeGCM: i32 = 11; +#[allow(non_upper_case_globals, unused)] +const kCCEncrypt: i32 = 0; +#[allow(non_upper_case_globals, unused)] +const kCCDecrypt: i32 = 1; +#[allow(non_upper_case_globals, unused)] +const kCCAlgorithmAES: i32 = 0; +#[allow(non_upper_case_globals, unused)] +const kCCOptionECBMode: i32 = 2; - extern "C" { - fn CCCryptorCreateWithMode( - op: i32, - mode: i32, - alg: i32, - padding: i32, - iv: *const c_void, - key: *const c_void, - key_len: usize, - tweak: *const c_void, - tweak_len: usize, - num_rounds: c_int, - options: i32, - cryyptor_ref: *mut *mut c_void, - ) -> i32; - fn CCCryptorUpdate( - cryptor_ref: *mut c_void, - data_in: *const c_void, - data_in_len: usize, - data_out: *mut c_void, - data_out_len: usize, - data_out_written: *mut usize, - ) -> i32; - fn CCCryptorReset(cryptor_ref: *mut c_void, iv: *const c_void) -> i32; - fn CCCryptorRelease(cryptor_ref: *mut c_void) -> i32; - fn CCCryptorGCMSetIV(cryptor_ref: *mut c_void, iv: *const c_void, iv_len: usize) -> i32; - fn CCCryptorGCMAddAAD(cryptor_ref: *mut c_void, aad: *const c_void, len: usize) -> i32; - fn CCCryptorGCMEncrypt(cryptor_ref: *mut c_void, data_in: *const c_void, data_in_len: usize, data_out: *mut c_void) -> i32; - fn CCCryptorGCMDecrypt(cryptor_ref: *mut c_void, data_in: *const c_void, data_in_len: usize, data_out: *mut c_void) -> i32; - fn CCCryptorGCMFinal(cryptor_ref: *mut c_void, tag: *mut c_void, tag_len: *mut usize) -> i32; - fn CCCryptorGCMReset(cryptor_ref: *mut c_void) -> i32; +extern "C" { + fn CCCryptorCreateWithMode( + op: i32, + mode: i32, + alg: i32, + padding: i32, + iv: *const c_void, + key: *const c_void, + key_len: usize, + tweak: *const c_void, + tweak_len: usize, + num_rounds: c_int, + options: i32, + cryyptor_ref: *mut *mut c_void, + ) -> i32; + fn CCCryptorUpdate( + cryptor_ref: *mut c_void, + data_in: *const c_void, + data_in_len: usize, + data_out: *mut c_void, + data_out_len: usize, + data_out_written: *mut usize, + ) -> i32; + //fn CCCryptorReset(cryptor_ref: *mut c_void, iv: *const c_void) -> i32; + fn CCCryptorRelease(cryptor_ref: *mut c_void) -> i32; + fn CCCryptorGCMSetIV(cryptor_ref: *mut c_void, iv: *const c_void, iv_len: usize) -> i32; + fn CCCryptorGCMAddAAD(cryptor_ref: *mut c_void, aad: *const c_void, len: usize) -> i32; + fn CCCryptorGCMEncrypt(cryptor_ref: *mut c_void, data_in: *const c_void, data_in_len: usize, data_out: *mut c_void) -> i32; + fn CCCryptorGCMDecrypt(cryptor_ref: *mut c_void, data_in: *const c_void, data_in_len: usize, data_out: *mut c_void) -> i32; + fn CCCryptorGCMFinal(cryptor_ref: *mut c_void, tag: *mut c_void, tag_len: *mut usize) -> i32; + fn CCCryptorGCMReset(cryptor_ref: *mut c_void) -> i32; +} + + + +pub struct AesGcm (*mut c_void); + +impl Drop for AesGcm { + #[inline(always)] + fn drop(&mut self) { + unsafe { CCCryptorRelease(self.0) }; } +} - pub struct Aes(*mut c_void, *mut c_void); - - impl Drop for Aes { - #[inline(always)] - fn drop(&mut self) { - unsafe { - CCCryptorRelease(self.0); - CCCryptorRelease(self.1); - } - } - } - - impl Aes { - pub fn new(k: &[u8]) -> Self { - unsafe { - if k.len() != 32 && k.len() != 24 && k.len() != 16 { - panic!("AES supports 128, 192, or 256 bits keys"); - } - let mut aes: Self = std::mem::zeroed(); - assert_eq!( - CCCryptorCreateWithMode( - kCCEncrypt, - kCCModeECB, - kCCAlgorithmAES, - 0, - null(), - k.as_ptr().cast(), - k.len(), - null(), - 0, - 0, - kCCOptionECBMode, - &mut aes.0 - ), - 0 - ); - assert_eq!( - CCCryptorCreateWithMode( - kCCDecrypt, - kCCModeECB, - kCCAlgorithmAES, - 0, - null(), - k.as_ptr().cast(), - k.len(), - null(), - 0, - 0, - kCCOptionECBMode, - &mut aes.1 - ), - 0 - ); - aes - } - } - - #[inline(always)] - pub fn encrypt_block(&self, plaintext: &[u8], ciphertext: &mut [u8]) { - assert_eq!(plaintext.len(), 16); - assert_eq!(ciphertext.len(), 16); - unsafe { - let mut data_out_written = 0; - CCCryptorUpdate( - self.0, - plaintext.as_ptr().cast(), - 16, - ciphertext.as_mut_ptr().cast(), - 16, - &mut data_out_written, - ); - } - } - - #[inline(always)] - pub fn encrypt_block_in_place(&self, data: &mut [u8]) { - assert_eq!(data.len(), 16); - unsafe { - let mut data_out_written = 0; - CCCryptorUpdate(self.0, data.as_ptr().cast(), 16, data.as_mut_ptr().cast(), 16, &mut data_out_written); - } - } - - #[inline(always)] - pub fn decrypt_block(&self, ciphertext: &[u8], plaintext: &mut [u8]) { - assert_eq!(plaintext.len(), 16); - assert_eq!(ciphertext.len(), 16); - unsafe { - let mut data_out_written = 0; - CCCryptorUpdate( - self.1, - ciphertext.as_ptr().cast(), - 16, - plaintext.as_mut_ptr().cast(), - 16, - &mut data_out_written, - ); - } - } - - #[inline(always)] - pub fn decrypt_block_in_place(&self, data: &mut [u8]) { - assert_eq!(data.len(), 16); - unsafe { - let mut data_out_written = 0; - CCCryptorUpdate(self.1, data.as_ptr().cast(), 16, data.as_mut_ptr().cast(), 16, &mut data_out_written); - } - } - } - - unsafe impl Send for Aes {} - unsafe impl Sync for Aes {} - - pub struct AesCtr(*mut c_void); - - impl Drop for AesCtr { - #[inline(always)] - fn drop(&mut self) { - unsafe { CCCryptorRelease(self.0) }; - } - } - - impl AesCtr { - /// Construct a new AES-CTR cipher. - /// Key must be 16, 24, or 32 bytes in length or a panic will occur. - pub fn new(k: &[u8]) -> Self { - if k.len() != 32 && k.len() != 24 && k.len() != 16 { - panic!("AES supports 128, 192, or 256 bits keys"); - } - unsafe { - let mut ptr: *mut c_void = null_mut(); - let result = CCCryptorCreateWithMode( - kCCEncrypt, - kCCModeCTR, +impl AesGcm { + pub fn new(k: &Secret) -> Self { + debug_assert!(KEY_SIZE == 32 || KEY_SIZE == 24 || KEY_SIZE == 16, "AES supports 128, 192, or 256 bits keys"); + unsafe { + let mut ptr: *mut c_void = null_mut(); + assert_eq!( + CCCryptorCreateWithMode( + if ENCRYPT { + kCCEncrypt + } else { + kCCDecrypt + }, + kCCModeGCM, kCCAlgorithmAES, 0, - [0_u64; 2].as_ptr().cast(), + null(), k.as_ptr().cast(), - k.len(), + KEY_SIZE, null(), 0, 0, 0, &mut ptr, - ); - if result != 0 { - panic!("CCCryptorCreateWithMode for CTR mode returned {}", result); - } - AesCtr(ptr) - } - } - - /// Initialize AES-CTR for encryption or decryption with the given IV. - /// If it's already been used, this also resets the cipher. There is no separate reset. - pub fn reset_set_iv(&mut self, iv: &[u8]) { - unsafe { - if iv.len() == 16 { - if CCCryptorReset(self.0, iv.as_ptr().cast()) != 0 { - panic!("CCCryptorReset for CTR mode failed (old MacOS bug)"); - } - } else if iv.len() < 16 { - let mut iv2 = [0_u8; 16]; - iv2[0..iv.len()].copy_from_slice(iv); - if CCCryptorReset(self.0, iv2.as_ptr().cast()) != 0 { - panic!("CCCryptorReset for CTR mode failed (old MacOS bug)"); - } - } else { - panic!("CTR IV must be less than or equal to 16 bytes in length"); - } - } - } - - /// Encrypt or decrypt (same operation with CTR mode) - #[inline(always)] - pub fn crypt(&mut self, input: &[u8], output: &mut [u8]) { - unsafe { - assert!(output.len() >= input.len()); - let mut data_out_written: usize = 0; - CCCryptorUpdate( - self.0, - input.as_ptr().cast(), - input.len(), - output.as_mut_ptr().cast(), - output.len(), - &mut data_out_written, - ); - } - } - - /// Encrypt or decrypt in place (same operation with CTR mode) - #[inline(always)] - pub fn crypt_in_place(&mut self, data: &mut [u8]) { - unsafe { - let mut data_out_written: usize = 0; - CCCryptorUpdate( - self.0, - data.as_ptr().cast(), - data.len(), - data.as_mut_ptr().cast(), - data.len(), - &mut data_out_written, - ); - } + ), + 0 + ); + AesGcm(ptr) } } - unsafe impl Send for AesCtr {} - - pub struct AesGcm(*mut c_void, bool); - - impl Drop for AesGcm { - #[inline(always)] - fn drop(&mut self) { - unsafe { CCCryptorRelease(self.0) }; + #[inline(always)] + pub fn reset_init_gcm(&self, iv: &[u8]) { + assert_eq!(iv.len(), 12); + unsafe { + assert_eq!(CCCryptorGCMReset(self.0), 0); + assert_eq!(CCCryptorGCMSetIV(self.0, iv.as_ptr().cast(), 12), 0); } } - impl AesGcm { - pub fn new(k: &[u8], encrypt: bool) -> Self { - if k.len() != 32 && k.len() != 24 && k.len() != 16 { - panic!("AES supports 128, 192, or 256 bits keys"); - } - unsafe { - let mut ptr: *mut c_void = null_mut(); + #[inline(always)] + pub fn aad(&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]) { + unsafe { + assert_eq!(input.len(), output.len()); + if ENCRYPT { assert_eq!( - CCCryptorCreateWithMode( - if encrypt { - kCCEncrypt - } else { - kCCDecrypt - }, - kCCModeGCM, - kCCAlgorithmAES, - 0, - null(), - k.as_ptr().cast(), - k.len(), - null(), - 0, - 0, - 0, - &mut ptr, - ), + CCCryptorGCMEncrypt(self.0, input.as_ptr().cast(), input.len(), output.as_mut_ptr().cast()), + 0 + ); + } else { + assert_eq!( + CCCryptorGCMDecrypt(self.0, input.as_ptr().cast(), input.len(), output.as_mut_ptr().cast()), 0 ); - AesGcm(ptr, encrypt) } } - - #[inline(always)] - pub fn reset_init_gcm(&mut self, iv: &[u8]) { - assert_eq!(iv.len(), 12); - unsafe { - assert_eq!(CCCryptorGCMReset(self.0), 0); - assert_eq!(CCCryptorGCMSetIV(self.0, iv.as_ptr().cast(), 12), 0); - } - } - - #[inline(always)] - 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(&mut self, input: &[u8], output: &mut [u8]) { - unsafe { - assert_eq!(input.len(), output.len()); - if self.1 { - assert_eq!( - CCCryptorGCMEncrypt(self.0, input.as_ptr().cast(), input.len(), output.as_mut_ptr().cast()), - 0 - ); - } else { - assert_eq!( - CCCryptorGCMDecrypt(self.0, input.as_ptr().cast(), input.len(), output.as_mut_ptr().cast()), - 0 - ); - } - } - } - - #[inline(always)] - pub fn crypt_in_place(&mut self, data: &mut [u8]) { - unsafe { - if self.1 { - assert_eq!(CCCryptorGCMEncrypt(self.0, data.as_ptr().cast(), data.len(), data.as_mut_ptr().cast()), 0); - } else { - assert_eq!(CCCryptorGCMDecrypt(self.0, data.as_ptr().cast(), data.len(), data.as_mut_ptr().cast()), 0); - } - } - } - - #[inline(always)] - pub fn finish_encrypt(&mut self) -> [u8; 16] { - let mut tag = 0_u128.to_ne_bytes(); - unsafe { - let mut tag_len = 16; - if CCCryptorGCMFinal(self.0, tag.as_mut_ptr().cast(), &mut tag_len) != 0 { - debug_assert!(false); - tag.fill(0); - } - } - tag - } - - #[inline(always)] - pub fn finish_decrypt(&mut self, expected_tag: &[u8]) -> bool { - secure_eq(&self.finish_encrypt(), expected_tag) - } } - unsafe impl Send for AesGcm {} + #[inline(always)] + pub fn crypt_in_place(&self, data: &mut [u8]) { + unsafe { + if ENCRYPT { + assert_eq!(CCCryptorGCMEncrypt(self.0, data.as_ptr().cast(), data.len(), data.as_mut_ptr().cast()), 0); + } else { + assert_eq!(CCCryptorGCMDecrypt(self.0, data.as_ptr().cast(), data.len(), data.as_mut_ptr().cast()), 0); + } + } + } + + #[inline(always)] + fn finish(&self) -> [u8; 16] { + let mut tag = 0_u128.to_ne_bytes(); + unsafe { + let mut tag_len = 16; + if CCCryptorGCMFinal(self.0, tag.as_mut_ptr().cast(), &mut tag_len) != 0 { + debug_assert!(false); + tag.fill(0); + } + } + tag + } + +} + +impl AesGcm { + /// Produce the gcm authentication tag. + #[inline(always)] + pub fn finish_encrypt(&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 { + secure_eq(&self.finish(), expected_tag) + } +} + + + +pub struct Aes(*mut c_void, *mut c_void); + +impl Drop for Aes { + #[inline(always)] + fn drop(&mut self) { + unsafe { + CCCryptorRelease(self.0); + CCCryptorRelease(self.1); + } + } +} + +impl Aes { + pub fn new(k: &Secret) -> Self { + unsafe { + debug_assert!(KEY_SIZE == 32 || KEY_SIZE == 24 || KEY_SIZE == 16, "AES supports 128, 192, or 256 bits keys"); + let mut aes: Self = std::mem::zeroed(); + assert_eq!( + CCCryptorCreateWithMode( + kCCEncrypt, + kCCModeECB, + kCCAlgorithmAES, + 0, + null(), + k.as_ptr().cast(), + KEY_SIZE, + null(), + 0, + 0, + kCCOptionECBMode, + &mut aes.0 + ), + 0 + ); + assert_eq!( + CCCryptorCreateWithMode( + kCCDecrypt, + kCCModeECB, + kCCAlgorithmAES, + 0, + null(), + k.as_ptr().cast(), + KEY_SIZE, + null(), + 0, + 0, + kCCOptionECBMode, + &mut aes.1 + ), + 0 + ); + aes + } + } + + #[inline(always)] + pub fn encrypt_block_in_place(&self, data: &mut [u8]) { + assert_eq!(data.len(), 16); + unsafe { + let mut data_out_written = 0; + CCCryptorUpdate(self.0, data.as_ptr().cast(), 16, data.as_mut_ptr().cast(), 16, &mut data_out_written); + } + } + + #[inline(always)] + pub fn decrypt_block_in_place(&self, data: &mut [u8]) { + assert_eq!(data.len(), 16); + unsafe { + let mut data_out_written = 0; + CCCryptorUpdate(self.1, data.as_ptr().cast(), 16, data.as_mut_ptr().cast(), 16, &mut data_out_written); + } + } } diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index ebc32114f..8c222180a 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -15,14 +15,14 @@ pub mod salsa; pub mod typestate; pub mod x25519; -#[cfg(target_os = "macos")] +/// NOTE: we assume that each aes library is threadsafe pub mod aes_fruity; #[cfg(not(target_os = "macos"))] pub mod aes_openssl; -#[cfg(target_os = "macos")] +//#[cfg(target_os = "macos")] pub use aes_fruity as aes; -#[cfg(not(target_os = "macos"))] -pub use aes_openssl as aes; +//#[cfg(not(target_os = "macos"))] +//pub use aes_openssl as aes; mod aes_tests; diff --git a/zssp/src/zssp.rs b/zssp/src/zssp.rs index a9a9cef7d..0b0905a0c 100644 --- a/zssp/src/zssp.rs +++ b/zssp/src/zssp.rs @@ -357,7 +357,7 @@ impl Context { } // Encrypt and add authentication tag. - let mut gcm = AesGcm::new( + let gcm = AesGcm::new( &kbkdf::(noise_es.as_bytes()) ); gcm.reset_init_gcm(&create_message_nonce(PACKET_TYPE_ALICE_NOISE_XK_INIT, 1)); @@ -604,7 +604,7 @@ impl Context { if let Some(session) = session { let state = session.state.read().unwrap(); if let Some(key) = state.keys[key_index].as_ref() { - let mut c = key.get_receive_cipher(); + let c = key.get_receive_cipher(); c.reset_init_gcm(&incoming_message_nonce); let mut data_len = 0; @@ -730,7 +730,7 @@ impl Context { let noise_h_next = mix_hash(&noise_h, &pkt_assembled[HEADER_SIZE..]); // Decrypt and authenticate init packet, also proving that caller knows our static identity. - let mut gcm = AesGcm::new( + let gcm = AesGcm::new( &kbkdf::(noise_es.as_bytes()) ); gcm.reset_init_gcm(&incoming_message_nonce); @@ -780,7 +780,7 @@ impl Context { ack.bob_hk_ciphertext = bob_hk_ciphertext; // Encrypt main section of reply and attach tag. - let mut gcm = AesGcm::new( + let gcm = AesGcm::new( &kbkdf::(noise_es_ee.as_bytes()) ); gcm.reset_init_gcm(&create_message_nonce(PACKET_TYPE_BOB_NOISE_XK_ACK, 1)); @@ -882,7 +882,7 @@ impl Context { let noise_h_next = mix_hash(&mix_hash(&outgoing_offer.noise_h, bob_noise_e.as_bytes()), &pkt_assembled[HEADER_SIZE..]); // Decrypt and authenticate Bob's reply. - let mut gcm = AesGcm::new( + let gcm = AesGcm::new( &kbkdf::(noise_es_ee.as_bytes()) ); gcm.reset_init_gcm(&incoming_message_nonce); @@ -927,7 +927,7 @@ impl Context { let mut enc_start = reply_len; reply_len = append_to_slice(&mut reply_buffer, reply_len, alice_s_public_blob)?; - let mut gcm = AesGcm::new( + let gcm = AesGcm::new( &kbkdf::(&hmac_sha512( noise_es_ee.as_bytes(), hk.as_bytes(), @@ -948,7 +948,7 @@ impl Context { enc_start = reply_len; reply_len = append_to_slice(&mut reply_buffer, reply_len, metadata)?; - let mut gcm = AesGcm::new( + let gcm = AesGcm::new( &kbkdf::(noise_es_ee_se_hk_psk.as_bytes()) ); gcm.reset_init_gcm(&reply_message_nonce); @@ -1126,7 +1126,7 @@ impl Context { // Only the current "Alice" accepts rekeys initiated by the current "Bob." These roles // flip with each rekey event. if !key.bob { - let mut c = key.get_receive_cipher(); + let c = key.get_receive_cipher(); c.reset_init_gcm(&incoming_message_nonce); c.crypt_in_place(&mut pkt_assembled[RekeyInit::ENC_START..RekeyInit::AUTH_START]); let aead_authentication_ok = c.finish_decrypt(&pkt_assembled[RekeyInit::AUTH_START..]); @@ -1158,7 +1158,7 @@ impl Context { counter, ); - let mut c = key.get_send_cipher(counter)?; + let c = key.get_send_cipher(counter)?; c.reset_init_gcm(&create_message_nonce(PACKET_TYPE_REKEY_ACK, counter)); c.crypt_in_place(&mut reply_buf[RekeyAck::ENC_START..RekeyAck::AUTH_START]); reply_buf[RekeyAck::AUTH_START..].copy_from_slice(&c.finish_encrypt()); @@ -1213,7 +1213,7 @@ impl Context { if let Some(key) = state.keys[key_index].as_ref() { // Only the current "Bob" initiates rekeys and expects this ACK. if key.bob { - let mut c = key.get_receive_cipher(); + let c = key.get_receive_cipher(); c.reset_init_gcm(&incoming_message_nonce); c.crypt_in_place(&mut pkt_assembled[RekeyAck::ENC_START..RekeyAck::AUTH_START]); let aead_authentication_ok = c.finish_decrypt(&pkt_assembled[RekeyAck::AUTH_START..]); @@ -1283,7 +1283,7 @@ impl Session { if let Some(session_key) = state.keys[state.current_key].as_ref() { let counter = self.get_next_outgoing_counter().ok_or(Error::MaxKeyLifetimeExceeded)?.get(); - let mut c = session_key.get_send_cipher(counter)?; + let c = session_key.get_send_cipher(counter)?; c.reset_init_gcm(&create_message_nonce(PACKET_TYPE_DATA, counter)); let fragment_count = (((data.len() + AES_GCM_TAG_SIZE) as f32) / (mtu_sized_buffer.len() - HEADER_SIZE) as f32).ceil() as usize; @@ -1335,7 +1335,7 @@ impl Session { if let Some(session_key) = state.keys[state.current_key].as_ref() { let counter = self.get_next_outgoing_counter().ok_or(Error::MaxKeyLifetimeExceeded)?.get(); let mut nop = [0u8; HEADER_SIZE + AES_GCM_TAG_SIZE]; - let mut c = session_key.get_send_cipher(counter)?; + let c = session_key.get_send_cipher(counter)?; c.reset_init_gcm(&create_message_nonce(PACKET_TYPE_NOP, counter)); nop[HEADER_SIZE..].copy_from_slice(&c.finish_encrypt()); session_key.return_send_cipher(c); @@ -1381,7 +1381,7 @@ impl Session { if let Some(remote_session_id) = state.remote_session_id { if let Some(key) = state.keys[state.current_key].as_ref() { if let Some(counter) = self.get_next_outgoing_counter() { - if let Ok(mut gcm) = key.get_send_cipher(counter.get()) { + if let Ok(gcm) = key.get_send_cipher(counter.get()) { gcm.reset_init_gcm(&create_message_nonce(PACKET_TYPE_REKEY_INIT, counter.get())); gcm.crypt_in_place(&mut rekey_buf[RekeyInit::ENC_START..RekeyInit::AUTH_START]); rekey_buf[RekeyInit::AUTH_START..].copy_from_slice(&gcm.finish_encrypt()); @@ -1634,7 +1634,7 @@ impl<'a> PktReader<'a> { fn read_decrypt_auth<'b>(&'b mut self, l: usize, k: Secret, gcm_aad: &[u8], nonce: &[u8]) -> Result<&'b [u8], Error> { let mut tmp = self.1 + l; if (tmp + AES_GCM_TAG_SIZE) <= self.0.len() { - let mut gcm = AesGcm::new(&k); + let gcm = AesGcm::new(&k); gcm.reset_init_gcm(nonce); gcm.aad(gcm_aad); gcm.crypt_in_place(&mut self.0[self.1..tmp]);