fixed macos aes

This commit is contained in:
mamoniot 2023-03-09 12:29:28 -05:00
parent a507212276
commit e02eeb0636
No known key found for this signature in database
GPG key ID: ADCCDBBE0E3D3B3B
3 changed files with 236 additions and 361 deletions

View file

@ -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<const ENCRYPT: bool> (*mut c_void);
impl<const ENCRYPT: bool> Drop for AesGcm<ENCRYPT> {
#[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<const ENCRYPT: bool> AesGcm<ENCRYPT> {
pub fn new<const KEY_SIZE: usize>(k: &Secret<KEY_SIZE>) -> 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<true> {
/// Produce the gcm authentication tag.
#[inline(always)]
pub fn finish_encrypt(&self) -> [u8; 16] {
self.finish()
}
}
impl AesGcm<false> {
/// 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<const KEY_SIZE: usize>(k: &Secret<KEY_SIZE>) -> 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);
}
}
}

View file

@ -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;

View file

@ -357,7 +357,7 @@ impl<Application: ApplicationLayer> Context<Application> {
}
// Encrypt and add authentication tag.
let mut gcm = AesGcm::new(
let gcm = AesGcm::new(
&kbkdf::<AES_256_KEY_SIZE, KBKDF_KEY_USAGE_LABEL_KEX_ES>(noise_es.as_bytes())
);
gcm.reset_init_gcm(&create_message_nonce(PACKET_TYPE_ALICE_NOISE_XK_INIT, 1));
@ -604,7 +604,7 @@ impl<Application: ApplicationLayer> Context<Application> {
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<Application: ApplicationLayer> Context<Application> {
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::<AES_256_KEY_SIZE, KBKDF_KEY_USAGE_LABEL_KEX_ES>(noise_es.as_bytes())
);
gcm.reset_init_gcm(&incoming_message_nonce);
@ -780,7 +780,7 @@ impl<Application: ApplicationLayer> Context<Application> {
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::<AES_256_KEY_SIZE, KBKDF_KEY_USAGE_LABEL_KEX_ES_EE>(noise_es_ee.as_bytes())
);
gcm.reset_init_gcm(&create_message_nonce(PACKET_TYPE_BOB_NOISE_XK_ACK, 1));
@ -882,7 +882,7 @@ impl<Application: ApplicationLayer> Context<Application> {
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::<AES_256_KEY_SIZE, KBKDF_KEY_USAGE_LABEL_KEX_ES_EE>(noise_es_ee.as_bytes())
);
gcm.reset_init_gcm(&incoming_message_nonce);
@ -927,7 +927,7 @@ impl<Application: ApplicationLayer> Context<Application> {
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::<AES_256_KEY_SIZE, KBKDF_KEY_USAGE_LABEL_KEX_ES_EE_HK>(&hmac_sha512(
noise_es_ee.as_bytes(),
hk.as_bytes(),
@ -948,7 +948,7 @@ impl<Application: ApplicationLayer> Context<Application> {
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::<AES_256_KEY_SIZE, KBKDF_KEY_USAGE_LABEL_KEX_ES_EE_SE_HK_PSK>(noise_es_ee_se_hk_psk.as_bytes())
);
gcm.reset_init_gcm(&reply_message_nonce);
@ -1126,7 +1126,7 @@ impl<Application: ApplicationLayer> Context<Application> {
// 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<Application: ApplicationLayer> Context<Application> {
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<Application: ApplicationLayer> Context<Application> {
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<Application: ApplicationLayer> Session<Application> {
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<Application: ApplicationLayer> Session<Application> {
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<Application: ApplicationLayer> Session<Application> {
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<AES_256_KEY_SIZE>, 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]);