mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-19 21:46:54 +02:00
fixed macos aes
This commit is contained in:
parent
a507212276
commit
e02eeb0636
3 changed files with 236 additions and 361 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
|
Loading…
Add table
Reference in a new issue