cargo fmt

This commit is contained in:
Monica Moniot
2023-08-07 15:08:29 -04:00
parent 3395f7b7cf
commit 1cbc455876
14 changed files with 402 additions and 144 deletions
+28 -5
View File
@@ -21,7 +21,9 @@ use rand_core::OsRng;
use rand_core::RngCore;
use sha2::Sha512;
use zssp_proto::applicationlayer::{AcceptAction, ApplicationLayer, RatchetState, RatchetUpdate, Settings, RATCHET_SIZE};
use zssp_proto::applicationlayer::{
AcceptAction, ApplicationLayer, RatchetState, RatchetUpdate, Settings, RATCHET_SIZE,
};
use zssp_proto::crypto_impl::PqcKyberSecretKey;
use zssp_proto::Session;
@@ -81,7 +83,10 @@ impl ApplicationLayer for &TestApplication {
}
}
fn restore_by_fingerprint(&self, ratchet_fingerprint: &[u8; RATCHET_SIZE]) -> Result<Option<RatchetState>, Self::StorageError> {
fn restore_by_fingerprint(
&self,
ratchet_fingerprint: &[u8; RATCHET_SIZE],
) -> Result<Option<RatchetState>, Self::StorageError> {
let ratchets = self.ratchets.lock().unwrap();
Ok(ratchets.rf_map.get(ratchet_fingerprint).cloned())
}
@@ -156,7 +161,14 @@ fn alice_main(
up = false;
alice_session = Some(
context
.open(alice_app, |b| alice_out.send(b).is_ok(), TEST_MTU, bob_pubkey.clone(), 0, Vec::new())
.open(
alice_app,
|b| alice_out.send(b).is_ok(),
TEST_MTU,
bob_pubkey.clone(),
0,
Vec::new(),
)
.unwrap(),
);
println!("[alice] opening session");
@@ -225,7 +237,8 @@ fn alice_main(
}
if current_time >= next_service {
next_service = current_time + context.service(alice_app, |_| Some((|b| alice_out.send(b).is_ok(), TEST_MTU)));
next_service =
current_time + context.service(alice_app, |_| Some((|b| alice_out.send(b).is_ok(), TEST_MTU)));
}
}
}
@@ -345,7 +358,17 @@ fn core(time: u64, packet_success_rate: u32) {
)
});
}
ts.spawn(move || bob_main(run, packet_success_rate, &bob_app, bob_out, bob_in, alice_out, bob_keypair));
ts.spawn(move || {
bob_main(
run,
packet_success_rate,
&bob_app,
bob_out,
bob_in,
alice_out,
bob_keypair,
)
});
thread::sleep(Duration::from_secs(time));
+1 -1
View File
@@ -1,4 +1,4 @@
max_width = 150
max_width = 120
edition = "2021"
newline_style = "Unix"
struct_lit_width = 60
+4 -1
View File
@@ -189,7 +189,10 @@ pub trait ApplicationLayer: Sized {
/// If `RatchetAction::DowngradeRatchet` is returned we will attempt to convince Alice to downgrade
/// to the empty ratchet key, restarting the ratchet chain.
/// If `RatchetAction::FailAuthentication` is returned Alice's connection will be silently dropped.
fn restore_by_fingerprint(&self, ratchet_fingerprint: &[u8; RATCHET_SIZE]) -> Result<Option<RatchetState>, Self::StorageError>;
fn restore_by_fingerprint(
&self,
ratchet_fingerprint: &[u8; RATCHET_SIZE],
) -> Result<Option<RatchetState>, Self::StorageError>;
/// Lookup the specific ratchet states based on the identity of the peer being communicated with.
/// This function will be called whenever Alice attempts to open a session, or Bob attempts
/// to verify Alice's identity.
+4 -1
View File
@@ -58,7 +58,10 @@ impl ChallengeContext {
return Ok(false);
}
let c = u64::from_be_bytes(response[..COUNTER_SIZE].try_into().unwrap());
if self.check_window(c) && secure_eq(&response[COUNTER_SIZE..POW_START], &self.create_mac::<Hash>(c, addr)) && verify_pow::<Hash>(response) {
if self.check_window(c)
&& secure_eq(&response[COUNTER_SIZE..POW_START], &self.create_mac::<Hash>(c, addr))
&& verify_pow::<Hash>(response)
{
self.update_window(c);
Ok(true)
} else {
+154 -85
View File
@@ -149,43 +149,53 @@ impl<App: ApplicationLayer> Context<App> {
if let Some(Some(session)) = session {
// Process recv fragmentation layer.
let mut zeta = session.0.lock().unwrap();
let result = zeta.defrag.received_fragment::<App>(raw_fragment, app.time(), |n, frag_no, frag_count| {
let (p, c) = from_nonce(n);
if p != PACKET_TYPE_DATA {
log!(app, ReceivedRawFragment(p, c, frag_no, frag_count));
}
if p == PACKET_TYPE_HANDSHAKE_RESPONSE {
if !matches!(&zeta.beta, ZetaAutomata::A1(_)) {
// A resent handshake response from Bob may have arrived out of order,
// after we already received one.
return Err(byzantine_fault!(OutOfSequence, false));
}
if c >= COUNTER_WINDOW_MAX_SKIP_AHEAD {
return Err(byzantine_fault!(ExpiredCounter, true));
}
Ok(())
} else if PACKET_TYPE_USES_COUNTER_RANGE.contains(&p) {
if !zeta.check_counter_window(c) {
// The counter window has finite memory and so will occasionally give
// false positives on very out-of-order packets.
return Err(byzantine_fault!(ExpiredCounter, false));
}
Ok(())
} else if p == PACKET_TYPE_HANDSHAKE_COMPLETION {
// The handshake completion packet could have been resent.
return Err(byzantine_fault!(InvalidPacket, false));
} else {
return Err(byzantine_fault!(InvalidPacket, true));
}
})?;
let result =
zeta.defrag
.received_fragment::<App>(raw_fragment, app.time(), |n, frag_no, frag_count| {
let (p, c) = from_nonce(n);
if p != PACKET_TYPE_DATA {
log!(app, ReceivedRawFragment(p, c, frag_no, frag_count));
}
if p == PACKET_TYPE_HANDSHAKE_RESPONSE {
if !matches!(&zeta.beta, ZetaAutomata::A1(_)) {
// A resent handshake response from Bob may have arrived out of order,
// after we already received one.
return Err(byzantine_fault!(OutOfSequence, false));
}
if c >= COUNTER_WINDOW_MAX_SKIP_AHEAD {
return Err(byzantine_fault!(ExpiredCounter, true));
}
Ok(())
} else if PACKET_TYPE_USES_COUNTER_RANGE.contains(&p) {
if !zeta.check_counter_window(c) {
// The counter window has finite memory and so will occasionally give
// false positives on very out-of-order packets.
return Err(byzantine_fault!(ExpiredCounter, false));
}
Ok(())
} else if p == PACKET_TYPE_HANDSHAKE_COMPLETION {
// The handshake completion packet could have been resent.
return Err(byzantine_fault!(InvalidPacket, false));
} else {
return Err(byzantine_fault!(InvalidPacket, true));
}
})?;
if let Some((pn, mut assembled_packet)) = result {
// Process recv zeta layer.
let send_associated = |Packet(kid, nonce, payload): &Packet, hk: Option<&[u8; AES_256_KEY_SIZE]>| {
if let Some((send_fragment, mut mtu)) = send_to(&session) {
mtu = mtu.max(MIN_TRANSPORT_MTU);
send_with_fragmentation::<App>(send_fragment, mtu, *kid, to_packet_nonce(&nonce), payload, hk);
}
};
let send_associated =
|Packet(kid, nonce, payload): &Packet, hk: Option<&[u8; AES_256_KEY_SIZE]>| {
if let Some((send_fragment, mut mtu)) = send_to(&session) {
mtu = mtu.max(MIN_TRANSPORT_MTU);
send_with_fragmentation::<App>(
send_fragment,
mtu,
*kid,
to_packet_nonce(&nonce),
payload,
hk,
);
}
};
let (p, _) = from_nonce(&pn);
let ret = match p {
@@ -210,8 +220,15 @@ impl<App: ApplicationLayer> Context<App> {
}
PACKET_TYPE_KEY_CONFIRM => {
log!(app, ReceivedRawKeyConfirm);
let result =
received_c1_trans(&mut zeta, &app, &ctx.rng, kid_recv, to_aes_nonce(&pn), assembled_packet, send_associated)?;
let result = received_c1_trans(
&mut zeta,
&app,
&ctx.rng,
kid_recv,
to_aes_nonce(&pn),
assembled_packet,
send_associated,
)?;
log!(app, KeyConfirmIsAuthSentAck(&session));
if result {
SessionEvent::Established
@@ -221,7 +238,14 @@ impl<App: ApplicationLayer> Context<App> {
}
PACKET_TYPE_ACK => {
log!(app, ReceivedRawAck);
received_c2_trans(&mut zeta, &app, &ctx.rng, kid_recv, to_aes_nonce(&pn), assembled_packet)?;
received_c2_trans(
&mut zeta,
&app,
&ctx.rng,
kid_recv,
to_aes_nonce(&pn),
assembled_packet,
)?;
log!(app, AckIsAuth(&session));
SessionEvent::Control
}
@@ -244,7 +268,14 @@ impl<App: ApplicationLayer> Context<App> {
}
PACKET_TYPE_REKEY_COMPLETE => {
log!(app, ReceivedRawK2);
received_k2_trans(&mut zeta, &app, kid_recv, to_aes_nonce(&pn), assembled_packet, send_associated)?;
received_k2_trans(
&mut zeta,
&app,
kid_recv,
to_aes_nonce(&pn),
assembled_packet,
send_associated,
)?;
log!(app, K2IsAuthSentKeyConfirm(&session));
SessionEvent::Control
}
@@ -266,28 +297,37 @@ impl<App: ApplicationLayer> Context<App> {
if let Entry::Occupied(mut entry) = b2_map.entry(kid_recv) {
let zeta = entry.get_mut();
// Process recv fragmentation layer.
let result = zeta.defrag.received_fragment::<App>(raw_fragment, app.time(), |n, frag_no, frag_count| {
let (p, c) = from_nonce(n);
log!(app, ReceivedRawFragment(p, c, frag_no, frag_count));
if p == PACKET_TYPE_HANDSHAKE_COMPLETION && c == 0 {
Ok(())
} else {
Err(byzantine_fault!(InvalidPacket, true))
}
})?;
let result =
zeta.defrag
.received_fragment::<App>(raw_fragment, app.time(), |n, frag_no, frag_count| {
let (p, c) = from_nonce(n);
log!(app, ReceivedRawFragment(p, c, frag_no, frag_count));
if p == PACKET_TYPE_HANDSHAKE_COMPLETION && c == 0 {
Ok(())
} else {
Err(byzantine_fault!(InvalidPacket, true))
}
})?;
if let Some((_, assembled_packet)) = result {
log!(app, ReceivedRawX3);
let zeta = entry.remove();
let session = received_x3_trans(zeta, &app, ctx, kid_recv, assembled_packet, |Packet(kid, nonce, payload), hk| {
send_with_fragmentation::<App>(
send_unassociated_reply,
send_unassociated_mtu,
*kid,
to_packet_nonce(&nonce),
payload,
hk,
);
})?;
let session = received_x3_trans(
zeta,
&app,
ctx,
kid_recv,
assembled_packet,
|Packet(kid, nonce, payload), hk| {
send_with_fragmentation::<App>(
send_unassociated_reply,
send_unassociated_mtu,
*kid,
to_packet_nonce(&nonce),
payload,
hk,
);
},
)?;
log!(app, X3IsAuthSentKeyConfirm(&session));
Ok(ReceiveOk::Session(session, SessionEvent::NewSession))
} else {
@@ -301,11 +341,10 @@ impl<App: ApplicationLayer> Context<App> {
}
} else {
// Process recv fragmentation layer.
let result = ctx
.hello_defrag
.lock()
.unwrap()
.received_fragment::<App>(raw_fragment, app.time(), |n, frag_no, frag_count| {
let result = ctx.hello_defrag.lock().unwrap().received_fragment::<App>(
raw_fragment,
app.time(),
|n, frag_no, frag_count| {
let (p, c) = from_nonce(n);
log!(app, ReceivedRawFragment(p, c, frag_no, frag_count));
if p == PACKET_TYPE_HANDSHAKE_HELLO || p == PACKET_TYPE_CHALLENGE {
@@ -313,18 +352,18 @@ impl<App: ApplicationLayer> Context<App> {
} else {
Err(byzantine_fault!(InvalidPacket, true))
}
})?;
},
)?;
if let Some((n, mut assembled_packet)) = result {
let (p, _) = from_nonce(&n);
if p == PACKET_TYPE_HANDSHAKE_HELLO {
log!(app, ReceivedRawX1);
// Process recv challenge layer.
let challenge_start = assembled_packet.len() - CHALLENGE_SIZE;
let result = ctx
.challenge
.lock()
.unwrap()
.process_hello::<App::Hash>(remote_address, (&assembled_packet[challenge_start..]).try_into().unwrap());
let result = ctx.challenge.lock().unwrap().process_hello::<App::Hash>(
remote_address,
(&assembled_packet[challenge_start..]).try_into().unwrap(),
);
if let Err(challenge) = result {
log!(app, X1FailedChallengeSentNewChallenge);
let mut challenge_packet = Vec::new();
@@ -347,16 +386,22 @@ impl<App: ApplicationLayer> Context<App> {
assembled_packet.truncate(challenge_start);
// Process recv zeta layer.
received_x1_trans(&app, &ctx, to_aes_nonce(&n), assembled_packet, |Packet(kid, nonce, payload), hk| {
send_with_fragmentation::<App>(
send_unassociated_reply,
send_unassociated_mtu,
*kid,
to_packet_nonce(&nonce),
payload,
Some(hk),
);
})?;
received_x1_trans(
&app,
&ctx,
to_aes_nonce(&n),
assembled_packet,
|Packet(kid, nonce, payload), hk| {
send_with_fragmentation::<App>(
send_unassociated_reply,
send_unassociated_mtu,
*kid,
to_packet_nonce(&nonce),
payload,
Some(hk),
);
},
)?;
log!(app, X1IsAuthSentX2);
Ok(ReceiveOk::Unassociated)
} else if p == PACKET_TYPE_CHALLENGE {
@@ -365,10 +410,17 @@ impl<App: ApplicationLayer> Context<App> {
if assembled_packet.len() != KID_SIZE + CHALLENGE_SIZE {
return Err(byzantine_fault!(InvalidPacket, true));
}
if let Some(kid_recv) = NonZeroU32::new(u32::from_be_bytes(assembled_packet[..KID_SIZE].try_into().unwrap())) {
if let Some(Some(session)) = ctx.session_map.lock().unwrap().get(&kid_recv).map(|r| r.upgrade()) {
if let Some(kid_recv) =
NonZeroU32::new(u32::from_be_bytes(assembled_packet[..KID_SIZE].try_into().unwrap()))
{
if let Some(Some(session)) = ctx.session_map.lock().unwrap().get(&kid_recv).map(|r| r.upgrade())
{
let mut zeta = session.0.lock().unwrap();
respond_to_challenge(&mut zeta, &ctx.rng, &assembled_packet[KID_SIZE..].try_into().unwrap());
respond_to_challenge(
&mut zeta,
&ctx.rng,
&assembled_packet[KID_SIZE..].try_into().unwrap(),
);
log!(app, ChallengeIsAuth(&session));
return Ok(ReceiveOk::Unassociated);
}
@@ -390,7 +442,13 @@ impl<App: ApplicationLayer> Context<App> {
/// slice of `data`
/// * `mtu` - The MTU of the link, all packets passed to `send` will be at most `mtu` in length
/// * `payload` - Data to send
pub fn send(&self, session: &Arc<Session<App>>, send: impl FnMut(Vec<u8>) -> bool, mut mtu: usize, payload: Vec<u8>) -> Result<(), SendError> {
pub fn send(
&self,
session: &Arc<Session<App>>,
send: impl FnMut(Vec<u8>) -> bool,
mut mtu: usize,
payload: Vec<u8>,
) -> Result<(), SendError> {
mtu = mtu.max(MIN_TRANSPORT_MTU);
let mut zeta = session.0.lock().unwrap();
send_payload(&mut zeta, payload, |Packet(kid, nonce, payload), hk| {
@@ -405,7 +463,11 @@ impl<App: ApplicationLayer> Context<App> {
/// a problem.
///
/// * `send_to` - Function to get a sender and an MTU to send something over an active session
pub fn service<SendFn: FnMut(Vec<u8>) -> bool>(&self, app: App, mut send_to: impl FnMut(&Arc<Session<App>>) -> Option<(SendFn, usize)>) -> i64 {
pub fn service<SendFn: FnMut(Vec<u8>) -> bool>(
&self,
app: App,
mut send_to: impl FnMut(&Arc<Session<App>>) -> Option<(SendFn, usize)>,
) -> i64 {
let ctx = &self.0;
let sessions = ctx.sessions.lock().unwrap();
let current_time = app.time();
@@ -422,7 +484,14 @@ impl<App: ApplicationLayer> Context<App> {
|Packet(kid, nonce, payload): &Packet, hk| {
if let Some((send_fragment, mut mtu)) = send_to(&session) {
mtu = mtu.max(MIN_TRANSPORT_MTU);
send_with_fragmentation::<App>(send_fragment, mtu, *kid, to_packet_nonce(&nonce), payload, hk);
send_with_fragmentation::<App>(
send_fragment,
mtu,
*kid,
to_packet_nonce(&nonce),
payload,
hk,
);
}
},
);
+6 -1
View File
@@ -27,7 +27,12 @@ pub trait PrpAes256 {
pub trait AeadAesGcm {
/// Encrypt the given `buffer` of plaintext using AES-GCM-256, with the given `key`, `iv` and `aad`.
/// The ciphertext should be written directly back to `buffer`, and the GCM tag should be returned.
fn encrypt_in_place(key: &[u8; AES_256_KEY_SIZE], iv: [u8; AES_GCM_IV_SIZE], aad: Option<&[u8]>, buffer: &mut [u8]) -> [u8; AES_GCM_TAG_SIZE];
fn encrypt_in_place(
key: &[u8; AES_256_KEY_SIZE],
iv: [u8; AES_GCM_IV_SIZE],
aad: Option<&[u8]>,
buffer: &mut [u8],
) -> [u8; AES_GCM_TAG_SIZE];
/// Decrypt the given `buffer` of ciphertext using AES-GCM-256, with the given `key`, `iv` and `aad`.
/// The ciphertext should be written directly back to `buffer`, and the GCM tag should be returned.
fn decrypt_in_place(
+4 -1
View File
@@ -24,7 +24,10 @@ pub trait PrivateKeyKyber1024<Rng: RngCore + CryptoRng>: Sized + Send + Sync {
///
/// **CRITICAL**: This must return `None` if the given `public_key` is invalid in any way
/// according to the Kyber1024 spec.
fn encapsulate(rng: &mut Rng, public_key: &[u8; KYBER_PUBLIC_KEY_SIZE]) -> Option<([u8; KYBER_CIPHERTEXT_SIZE], [u8; KYBER_PLAINTEXT_SIZE])>;
fn encapsulate(
rng: &mut Rng,
public_key: &[u8; KYBER_PUBLIC_KEY_SIZE],
) -> Option<([u8; KYBER_CIPHERTEXT_SIZE], [u8; KYBER_PLAINTEXT_SIZE])>;
/// Decapsulate a Kyber1024 `ciphertext` received from the remote peer, retreiving
/// the raw bytes of the original plaintext. This plaintext is immediately hashed and deleted.
///
+6 -1
View File
@@ -18,7 +18,12 @@ impl PrpAes256 for Aes256 {
}
impl AeadAesGcm for Aes256Gcm {
fn encrypt_in_place(key: &[u8; AES_256_KEY_SIZE], iv: [u8; AES_GCM_IV_SIZE], aad: Option<&[u8]>, buffer: &mut [u8]) -> [u8; AES_GCM_TAG_SIZE] {
fn encrypt_in_place(
key: &[u8; AES_256_KEY_SIZE],
iv: [u8; AES_GCM_IV_SIZE],
aad: Option<&[u8]>,
buffer: &mut [u8],
) -> [u8; AES_GCM_TAG_SIZE] {
let key = Key::<Aes256Gcm>::from_slice(key);
let mut cipher = Aes256Gcm::new(&key);
cipher
+4 -1
View File
@@ -13,7 +13,10 @@ impl<Rng: RngCore + CryptoRng> PrivateKeyKyber1024<Rng> for PqcKyberSecretKey {
(Zeroizing::new(keypair.secret), keypair.public)
}
fn encapsulate(rng: &mut Rng, public_key: &[u8; KYBER_PUBLIC_KEY_SIZE]) -> Option<([u8; KYBER_CIPHERTEXT_SIZE], [u8; KYBER_PLAINTEXT_SIZE])> {
fn encapsulate(
rng: &mut Rng,
public_key: &[u8; KYBER_PUBLIC_KEY_SIZE],
) -> Option<([u8; KYBER_CIPHERTEXT_SIZE], [u8; KYBER_PLAINTEXT_SIZE])> {
pqc_kyber::encapsulate(public_key, rng).ok()
}
+7 -1
View File
@@ -26,6 +26,12 @@ impl<Rng: RngCore + CryptoRng> KeyPairP384<Rng> for EphemeralSecret {
}
fn agree(&self, public_key: &Self::PublicKey) -> Option<[u8; P384_ECDH_SHARED_SECRET_SIZE]> {
Some(self.diffie_hellman(public_key).raw_secret_bytes().as_slice().try_into().unwrap())
Some(
self.diffie_hellman(public_key)
.raw_secret_bytes()
.as_slice()
.try_into()
.unwrap(),
)
}
}
+16 -3
View File
@@ -10,7 +10,12 @@ use crate::proto::*;
use crate::result::{byzantine_fault, ReceiveError};
/// Corresponds to Figure 13 found in Section 6.
fn create_fragment_header(kid_send: u32, fragment_count: usize, fragment_no: usize, n: &[u8; PACKET_NONCE_SIZE]) -> [u8; HEADER_SIZE] {
fn create_fragment_header(
kid_send: u32,
fragment_count: usize,
fragment_no: usize,
n: &[u8; PACKET_NONCE_SIZE],
) -> [u8; HEADER_SIZE] {
debug_assert!(fragment_count > 0);
debug_assert!(fragment_count <= MAX_FRAGMENTS);
debug_assert!(fragment_no < MAX_FRAGMENTS);
@@ -47,7 +52,10 @@ pub fn send_with_fragmentation<App: ApplicationLayer>(
fragment.extend(&packet[i..j]);
if let Some(hk_send) = hk_send {
App::Prp::encrypt_in_place(hk_send, (&mut fragment[HEADER_AUTH_START..HEADER_AUTH_END]).try_into().unwrap());
App::Prp::encrypt_in_place(
hk_send,
(&mut fragment[HEADER_AUTH_START..HEADER_AUTH_END]).try_into().unwrap(),
);
}
if !send(fragment) {
return false;
@@ -87,7 +95,12 @@ impl DefragBuffer {
}
if let Some(hk_recv) = self.hk_recv.as_ref() {
App::Prp::decrypt_in_place(hk_recv, (&mut raw_fragment[HEADER_AUTH_START..HEADER_AUTH_END]).try_into().unwrap())
App::Prp::decrypt_in_place(
hk_recv,
(&mut raw_fragment[HEADER_AUTH_START..HEADER_AUTH_END])
.try_into()
.unwrap(),
)
}
let fragment_no = raw_fragment[FRAGMENT_NO_IDX] as usize;
+9 -4
View File
@@ -1,4 +1,6 @@
use crate::crypto::{AES_GCM_TAG_SIZE, KYBER_CIPHERTEXT_SIZE, KYBER_PUBLIC_KEY_SIZE, P384_PUBLIC_KEY_SIZE, SHA512_HASH_SIZE};
use crate::crypto::{
AES_GCM_TAG_SIZE, KYBER_CIPHERTEXT_SIZE, KYBER_PUBLIC_KEY_SIZE, P384_PUBLIC_KEY_SIZE, SHA512_HASH_SIZE,
};
/* Common constants */
@@ -71,7 +73,8 @@ pub(crate) const HASHLEN: usize = SHA512_HASH_SIZE;
pub const RATCHET_SIZE: usize = 32;
/// Initial value of 'h'.
pub(crate) const PROTOCOL_NAME_NOISE_XK: &[u8; HASHLEN] = b"Noise_XKhfs+psk2_P384+Kyber1024_AESGCM_SHA512\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
pub(crate) const PROTOCOL_NAME_NOISE_XK: &[u8; HASHLEN] =
b"Noise_XKhfs+psk2_P384+Kyber1024_AESGCM_SHA512\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
/// Initial value of 'ck' for rekeying.
pub(crate) const PROTOCOL_NAME_NOISE_KK: &[u8; HASHLEN] =
b"Noise_KKpsk0_P384_AESGCM_SHA512\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
@@ -112,10 +115,12 @@ pub(crate) const PACKET_TYPE_DATA: u8 = 8;
pub(crate) const PACKET_TYPE_CHALLENGE: u8 = 9;
pub(crate) const PACKET_TYPE_USES_COUNTER_RANGE: std::ops::Range<u8> = 3..9;
pub(crate) const HANDSHAKE_HELLO_MIN_SIZE: usize = KID_SIZE + P384_PUBLIC_KEY_SIZE + KYBER_PUBLIC_KEY_SIZE + AES_GCM_TAG_SIZE + AES_GCM_TAG_SIZE;
pub(crate) const HANDSHAKE_HELLO_MIN_SIZE: usize =
KID_SIZE + P384_PUBLIC_KEY_SIZE + KYBER_PUBLIC_KEY_SIZE + AES_GCM_TAG_SIZE + AES_GCM_TAG_SIZE;
pub(crate) const HANDSHAKE_HELLO_MAX_SIZE: usize = HANDSHAKE_HELLO_MIN_SIZE + RATCHET_SIZE;
pub(crate) const HANDSHAKE_RESPONSE_SIZE: usize = P384_PUBLIC_KEY_SIZE + KYBER_CIPHERTEXT_SIZE + AES_GCM_TAG_SIZE + KID_SIZE + AES_GCM_TAG_SIZE;
pub(crate) const HANDSHAKE_RESPONSE_SIZE: usize =
P384_PUBLIC_KEY_SIZE + KYBER_CIPHERTEXT_SIZE + AES_GCM_TAG_SIZE + KID_SIZE + AES_GCM_TAG_SIZE;
pub(crate) const HANDSHAKE_COMPLETION_MIN_SIZE: usize = P384_PUBLIC_KEY_SIZE + AES_GCM_TAG_SIZE + 0 + AES_GCM_TAG_SIZE;
pub(crate) const HANDSHAKE_COMPLETION_MAX_SIZE: usize = HANDSHAKE_COMPLETION_MIN_SIZE + IDENTITY_MAX_SIZE;
+20 -3
View File
@@ -84,7 +84,14 @@ impl<App: ApplicationLayer> SymmetricState<App> {
let mut next_ck = [0u8; HASHLEN];
let mut temp_k = [0u8; HASHLEN];
self.kbkdf(input_key_material, LABEL_KBKDF_CHAIN, 2, &mut next_ck, Some(&mut temp_k), None);
self.kbkdf(
input_key_material,
LABEL_KBKDF_CHAIN,
2,
&mut next_ck,
Some(&mut temp_k),
None,
);
*self.ck = next_ck;
self.k.clone_from_slice(&temp_k[..AES_256_KEY_SIZE]);
@@ -116,14 +123,24 @@ impl<App: ApplicationLayer> SymmetricState<App> {
self.k.clone_from_slice(&temp_k[..AES_256_KEY_SIZE]);
}
/// Corresponds to Noise `EncryptAndHash`.
pub fn encrypt_and_hash_in_place(&mut self, iv: [u8; AES_GCM_IV_SIZE], plaintext_start: usize, buffer: &mut Vec<u8>) {
pub fn encrypt_and_hash_in_place(
&mut self,
iv: [u8; AES_GCM_IV_SIZE],
plaintext_start: usize,
buffer: &mut Vec<u8>,
) {
let tag = App::Aead::encrypt_in_place(&self.k, iv, Some(&self.h), &mut buffer[plaintext_start..]);
buffer.extend(&tag);
self.mix_hash(&buffer[plaintext_start..]);
}
/// Corresponds to Noise `DecryptAndHash`.
#[must_use]
pub fn decrypt_and_hash_in_place(&mut self, iv: [u8; AES_GCM_IV_SIZE], buffer: &mut [u8], tag: [u8; AES_GCM_TAG_SIZE]) -> bool {
pub fn decrypt_and_hash_in_place(
&mut self,
iv: [u8; AES_GCM_IV_SIZE],
buffer: &mut [u8],
tag: [u8; AES_GCM_TAG_SIZE],
) -> bool {
let mut hash = App::Hash::new();
hash.update(&self.h);
hash.update(buffer);
+139 -36
View File
@@ -276,7 +276,15 @@ pub(crate) fn trans_to_a1<App: ApplicationLayer>(
let mut session_map = ctx.session_map.lock().unwrap();
let kid_recv = gen_kid(session_map.deref(), ctx.rng.lock().unwrap().deref_mut());
let a1 = create_a1_state(&ctx.rng, &s_remote, kid_recv, &ratchet_state1, ratchet_state2.as_ref(), identity).ok_or(OpenError::InvalidPublicKey)?;
let a1 = create_a1_state(
&ctx.rng,
&s_remote,
kid_recv,
&ratchet_state1,
ratchet_state2.as_ref(),
identity,
)
.ok_or(OpenError::InvalidPublicKey)?;
let packet = a1.packet.clone();
let (hk_recv, hk_send) = a1.noise.get_ask(LABEL_HEADER_KEY);
@@ -304,14 +312,21 @@ pub(crate) fn trans_to_a1<App: ApplicationLayer>(
let session = Arc::new(Session(Mutex::new(zeta)));
session_map.insert(kid_recv, Arc::downgrade(&session));
ctx.sessions.lock().unwrap().insert(Arc::as_ptr(&session), Arc::downgrade(&session));
ctx.sessions
.lock()
.unwrap()
.insert(Arc::as_ptr(&session), Arc::downgrade(&session));
send(&packet);
Ok(session)
}
/// Corresponds to Algorithm 13 found in Section 5.
pub(crate) fn respond_to_challenge<App: ApplicationLayer>(zeta: &mut Zeta<App>, rng: &Mutex<App::Rng>, challenge: &[u8; CHALLENGE_SIZE]) {
pub(crate) fn respond_to_challenge<App: ApplicationLayer>(
zeta: &mut Zeta<App>,
rng: &Mutex<App::Rng>,
challenge: &[u8; CHALLENGE_SIZE],
) {
if let ZetaAutomata::A1(StateA1 { packet: Packet(_, _, x1), .. }) = &mut zeta.beta {
let response_start = x1.len() - CHALLENGE_SIZE;
respond_to_challenge_in_place::<App::Rng, App::Hash>(
@@ -345,13 +360,16 @@ pub(crate) fn received_x1_trans<App: ApplicationLayer>(
// Noise process prologue.
let j = i + KID_SIZE;
noise.mix_hash(&x1[i..j]);
let kid_send = NonZeroU32::new(u32::from_be_bytes(x1[i..j].try_into().unwrap())).ok_or(byzantine_fault!(InvalidPacket, true))?;
let kid_send = NonZeroU32::new(u32::from_be_bytes(x1[i..j].try_into().unwrap()))
.ok_or(byzantine_fault!(InvalidPacket, true))?;
noise.mix_hash(&ctx.s_secret.public_key_bytes());
i = j;
// Process message pattern 1 e token.
let e_remote = noise.read_e(&mut i, &x1).ok_or(byzantine_fault!(FailedAuth, true))?;
// Process message pattern 1 es token.
noise.mix_dh(&ctx.s_secret, &e_remote).ok_or(byzantine_fault!(FailedAuth, true))?;
noise
.mix_dh(&ctx.s_secret, &e_remote)
.ok_or(byzantine_fault!(FailedAuth, true))?;
// Process message pattern 1 e1 token.
let j = i + KYBER_PUBLIC_KEY_SIZE;
let k = j + AES_GCM_TAG_SIZE;
@@ -396,12 +414,17 @@ pub(crate) fn received_x1_trans<App: ApplicationLayer>(
// Process message pattern 2 e token.
let e_secret = noise.write_e(&ctx.rng, &mut x2);
// Process message pattern 2 ee token.
noise.mix_dh(&e_secret, &e_remote).ok_or(byzantine_fault!(FailedAuth, true))?;
noise
.mix_dh(&e_secret, &e_remote)
.ok_or(byzantine_fault!(FailedAuth, true))?;
// Process message pattern 2 ekem1 token.
let i = x2.len();
let (ekem1, ekem1_secret) = App::Kem::encapsulate(ctx.rng.lock().unwrap().deref_mut(), (&x1[e1_start..e1_end]).try_into().unwrap())
.map(|(ct, secret)| (ct, Zeroizing::new(secret)))
.ok_or(byzantine_fault!(FailedAuth, true))?;
let (ekem1, ekem1_secret) = App::Kem::encapsulate(
ctx.rng.lock().unwrap().deref_mut(),
(&x1[e1_start..e1_end]).try_into().unwrap(),
)
.map(|(ct, secret)| (ct, Zeroizing::new(secret)))
.ok_or(byzantine_fault!(FailedAuth, true))?;
x2.extend(ekem1);
noise.encrypt_and_hash_in_place(to_nonce(PACKET_TYPE_HANDSHAKE_RESPONSE, 0), i, &mut x2);
noise.mix_key(ekem1_secret.as_ref());
@@ -436,7 +459,10 @@ pub(crate) fn received_x1_trans<App: ApplicationLayer>(
},
);
send(&Packet(kid_send.get(), to_nonce(PACKET_TYPE_HANDSHAKE_RESPONSE, c), x2), &hk_send);
send(
&Packet(kid_send.get(), to_nonce(PACKET_TYPE_HANDSHAKE_RESPONSE, c), x2),
&hk_send,
);
Ok(())
}
/// Corresponds to Transition Algorithm 3 found in Section 4.3.
@@ -470,7 +496,9 @@ pub(crate) fn received_x2_trans<App: ApplicationLayer>(
// Process message pattern 2 e token.
let e_remote = noise.read_e(&mut i, &x2).ok_or(byzantine_fault!(FailedAuth, true))?;
// Process message pattern 2 ee token.
noise.mix_dh(e_secret, &e_remote).ok_or(byzantine_fault!(FailedAuth, true))?;
noise
.mix_dh(e_secret, &e_remote)
.ok_or(byzantine_fault!(FailedAuth, true))?;
// Process message pattern 2 ekem1 token.
let j = i + KYBER_CIPHERTEXT_SIZE;
let k = j + AES_GCM_TAG_SIZE;
@@ -536,7 +564,9 @@ pub(crate) fn received_x2_trans<App: ApplicationLayer>(
x3.extend(&ctx.s_secret.public_key_bytes());
noise.encrypt_and_hash_in_place(to_nonce(PACKET_TYPE_HANDSHAKE_COMPLETION, 1), i, &mut x3);
// Process message pattern 3 se token.
noise.mix_dh(&ctx.s_secret, &e_remote).ok_or(byzantine_fault!(FailedAuth, true))?;
noise
.mix_dh(&ctx.s_secret, &e_remote)
.ok_or(byzantine_fault!(FailedAuth, true))?;
// Process message pattern 3 payload.
let i = x3.len();
x3.extend(identity);
@@ -623,10 +653,13 @@ pub(crate) fn received_x3_trans<App: ApplicationLayer>(
if !noise.decrypt_and_hash_in_place(to_nonce(PACKET_TYPE_HANDSHAKE_COMPLETION, 1), &mut x3[i..j], tag) {
return Err(byzantine_fault!(FailedAuth, true));
}
let s_remote = App::PublicKey::from_bytes((&x3[i..j]).try_into().unwrap()).ok_or(byzantine_fault!(FailedAuth, true))?;
let s_remote =
App::PublicKey::from_bytes((&x3[i..j]).try_into().unwrap()).ok_or(byzantine_fault!(FailedAuth, true))?;
i = k;
// Process message pattern 3 se token.
noise.mix_dh(&zeta.e_secret, &s_remote).ok_or(byzantine_fault!(FailedAuth, true))?;
noise
.mix_dh(&zeta.e_secret, &s_remote)
.ok_or(byzantine_fault!(FailedAuth, true))?;
// Process message pattern 3 payload.
let k = x3.len();
let j = k - AES_GCM_TAG_SIZE;
@@ -726,7 +759,10 @@ pub(crate) fn received_x3_trans<App: ApplicationLayer>(
defrag: zeta.defrag,
})));
entry.insert(Arc::downgrade(&session));
ctx.sessions.lock().unwrap().insert(Arc::as_ptr(&session), Arc::downgrade(&session));
ctx.sessions
.lock()
.unwrap()
.insert(Arc::as_ptr(&session), Arc::downgrade(&session));
send(&Packet(zeta.kid_send.get(), n, c1), Some(&zeta.hk_send));
Ok(session)
@@ -765,7 +801,12 @@ pub(crate) fn received_c1_trans<App: ApplicationLayer>(
return Err(byzantine_fault!(OutOfSequence, false));
};
let specified_key = zeta.key_ref(is_other).recv.kek.as_ref().ok_or(byzantine_fault!(OutOfSequence, true))?;
let specified_key = zeta
.key_ref(is_other)
.recv
.kek
.as_ref()
.ok_or(byzantine_fault!(OutOfSequence, true))?;
let tag = c1[..].try_into().unwrap();
if !App::Aead::decrypt_in_place(specified_key, n, None, &mut [], tag) {
return Err(byzantine_fault!(FailedAuth, true));
@@ -800,7 +841,8 @@ pub(crate) fn received_c1_trans<App: ApplicationLayer>(
zeta.timeout_timer = app.time()
+ App::SETTINGS
.rekey_after_time
.saturating_sub(rng.lock().unwrap().next_u64() % App::SETTINGS.rekey_time_max_jitter) as i64;
.saturating_sub(rng.lock().unwrap().next_u64() % App::SETTINGS.rekey_time_max_jitter)
as i64;
zeta.resend_timer = i64::MAX;
zeta.beta = ZetaAutomata::S2;
}
@@ -810,11 +852,19 @@ pub(crate) fn received_c1_trans<App: ApplicationLayer>(
let c = zeta.send_counter;
zeta.send_counter += 1;
let n = to_nonce(PACKET_TYPE_ACK, c);
let latest_confirmed_key = zeta.key_ref(false).send.kek.as_ref().ok_or(byzantine_fault!(OutOfSequence, true))?;
let latest_confirmed_key = zeta
.key_ref(false)
.send
.kek
.as_ref()
.ok_or(byzantine_fault!(OutOfSequence, true))?;
let tag = App::Aead::encrypt_in_place(latest_confirmed_key, n, None, &mut []);
c2.extend(&tag);
send(&Packet(zeta.key_ref(false).send.kid.unwrap().get(), n, c2), Some(&zeta.hk_send));
send(
&Packet(zeta.key_ref(false).send.kid.unwrap().get(), n, c2),
Some(&zeta.hk_send),
);
Ok(just_establised)
}
/// Corresponds to the trivial Transition Algorithm described for processing C_2 packets found in
@@ -929,7 +979,12 @@ pub(crate) fn service<App: ApplicationLayer>(
let c = zeta.send_counter;
zeta.send_counter += 1;
let n = to_nonce(p, c);
let tag = App::Aead::encrypt_in_place(zeta.key_ref(false).send.kek.as_ref().unwrap(), n, None, &mut control_payload);
let tag = App::Aead::encrypt_in_place(
zeta.key_ref(false).send.kek.as_ref().unwrap(),
n,
None,
&mut control_payload,
);
control_payload.extend(&tag);
send(
&Packet(zeta.key_ref(false).send.kid.unwrap().get(), n, control_payload),
@@ -937,7 +992,12 @@ pub(crate) fn service<App: ApplicationLayer>(
);
}
}
fn remap<App: ApplicationLayer>(session: &Arc<Session<App>>, zeta: &Zeta<App>, rng: &Mutex<App::Rng>, session_map: &SessionMap<App>) -> NonZeroU32 {
fn remap<App: ApplicationLayer>(
session: &Arc<Session<App>>,
zeta: &Zeta<App>,
rng: &Mutex<App::Rng>,
session_map: &SessionMap<App>,
) -> NonZeroU32 {
let mut session_map = session_map.lock().unwrap();
let weak = if let Some(Some(weak)) = zeta.key_ref(true).recv.kid.as_ref().map(|kid| session_map.remove(kid)) {
weak
@@ -1034,7 +1094,10 @@ fn timeout_trans<App: ApplicationLayer>(
let tag = App::Aead::encrypt_in_place(zeta.key_ref(false).send.kek.as_ref().unwrap(), n, None, &mut k1);
k1.extend(&tag);
send(&Packet(zeta.key_ref(false).send.kid.unwrap().get(), n, k1), Some(&zeta.hk_send));
send(
&Packet(zeta.key_ref(false).send.kid.unwrap().get(), n, k1),
Some(&zeta.hk_send),
);
}
ZetaAutomata::S1 { .. } => {
log!(app, TimeoutKeyConfirm(session));
@@ -1088,7 +1151,13 @@ pub(crate) fn received_k1_trans<App: ApplicationLayer>(
let i = k1.len() - AES_GCM_TAG_SIZE;
let tag = k1[i..].try_into().unwrap();
if !App::Aead::decrypt_in_place(zeta.key_ref(false).recv.kek.as_ref().unwrap(), n, None, &mut k1[..i], tag) {
if !App::Aead::decrypt_in_place(
zeta.key_ref(false).recv.kek.as_ref().unwrap(),
n,
None,
&mut k1[..i],
tag,
) {
return Err(byzantine_fault!(FailedAuth, true));
}
let (_, c) = from_nonce(&n);
@@ -1108,9 +1177,13 @@ pub(crate) fn received_k1_trans<App: ApplicationLayer>(
// Process message pattern 1 e token.
let e_remote = noise.read_e(&mut i, &k1).ok_or(byzantine_fault!(FailedAuth, true))?;
// Process message pattern 1 es token.
noise.mix_dh(s_secret, &e_remote).ok_or(byzantine_fault!(FailedAuth, true))?;
noise
.mix_dh(s_secret, &e_remote)
.ok_or(byzantine_fault!(FailedAuth, true))?;
// Process message pattern 1 ss token.
noise.mix_dh(s_secret, &zeta.s_remote).ok_or(byzantine_fault!(FailedAuth, true))?;
noise
.mix_dh(s_secret, &zeta.s_remote)
.ok_or(byzantine_fault!(FailedAuth, true))?;
// Process message pattern 1 payload.
let j = i + KID_SIZE;
let k = j + AES_GCM_TAG_SIZE;
@@ -1118,15 +1191,20 @@ pub(crate) fn received_k1_trans<App: ApplicationLayer>(
if !noise.decrypt_and_hash_in_place(to_nonce(PACKET_TYPE_REKEY_INIT, 0), &mut k1[i..j], tag) {
return Err(byzantine_fault!(FailedAuth, true));
}
let kid_send = NonZeroU32::new(u32::from_be_bytes(k1[i..j].try_into().unwrap())).ok_or(byzantine_fault!(FailedAuth, true))?;
let kid_send = NonZeroU32::new(u32::from_be_bytes(k1[i..j].try_into().unwrap()))
.ok_or(byzantine_fault!(FailedAuth, true))?;
let mut k2 = Vec::new();
// Process message pattern 2 e token.
let e_secret = noise.write_e(rng, &mut k2);
// Process message pattern 2 ee token.
noise.mix_dh(&e_secret, &e_remote).ok_or(byzantine_fault!(FailedAuth, true))?;
noise
.mix_dh(&e_secret, &e_remote)
.ok_or(byzantine_fault!(FailedAuth, true))?;
// Process message pattern 2 se token.
noise.mix_dh(&s_secret, &e_remote).ok_or(byzantine_fault!(FailedAuth, true))?;
noise
.mix_dh(&s_secret, &e_remote)
.ok_or(byzantine_fault!(FailedAuth, true))?;
// Process message pattern 2 payload.
let i = k2.len();
let new_kid_recv = remap(session, &zeta, rng, session_map);
@@ -1172,7 +1250,10 @@ pub(crate) fn received_k1_trans<App: ApplicationLayer>(
let tag = App::Aead::encrypt_in_place(zeta.key_ref(false).send.kek.as_ref().unwrap(), n, None, &mut k2);
k2.extend(&tag);
send(&Packet(zeta.key_ref(false).send.kid.unwrap().get(), n, k2), Some(&zeta.hk_send));
send(
&Packet(zeta.key_ref(false).send.kid.unwrap().get(), n, k2),
Some(&zeta.hk_send),
);
Ok(())
})();
if matches!(result, Err(ReceiveError::ByzantineFault { .. })) {
@@ -1205,7 +1286,13 @@ pub(crate) fn received_k2_trans<App: ApplicationLayer>(
let i = k2.len() - AES_GCM_TAG_SIZE;
let tag = k2[i..].try_into().unwrap();
if !App::Aead::decrypt_in_place(zeta.key_ref(false).recv.kek.as_ref().unwrap(), n, None, &mut k2[..i], tag) {
if !App::Aead::decrypt_in_place(
zeta.key_ref(false).recv.kek.as_ref().unwrap(),
n,
None,
&mut k2[..i],
tag,
) {
return Err(byzantine_fault!(FailedAuth, true));
}
let (_, c) = from_nonce(&n);
@@ -1220,9 +1307,13 @@ pub(crate) fn received_k2_trans<App: ApplicationLayer>(
// Process message pattern 2 e token.
let e_remote = noise.read_e(&mut i, &k2).ok_or(byzantine_fault!(FailedAuth, true))?;
// Process message pattern 2 ee token.
noise.mix_dh(e_secret, &e_remote).ok_or(byzantine_fault!(FailedAuth, true))?;
noise
.mix_dh(e_secret, &e_remote)
.ok_or(byzantine_fault!(FailedAuth, true))?;
// Process message pattern 2 se token.
noise.mix_dh(e_secret, &zeta.s_remote).ok_or(byzantine_fault!(FailedAuth, true))?;
noise
.mix_dh(e_secret, &zeta.s_remote)
.ok_or(byzantine_fault!(FailedAuth, true))?;
// Process message pattern 2 payload.
let j = i + KID_SIZE;
let k = j + AES_GCM_TAG_SIZE;
@@ -1230,7 +1321,8 @@ pub(crate) fn received_k2_trans<App: ApplicationLayer>(
if !noise.decrypt_and_hash_in_place(to_nonce(PACKET_TYPE_REKEY_COMPLETE, 0), &mut k2[i..j], tag) {
return Err(byzantine_fault!(FailedAuth, true));
}
let kid_send = NonZeroU32::new(u32::from_be_bytes(k2[i..j].try_into().unwrap())).ok_or(byzantine_fault!(InvalidPacket, true))?;
let kid_send = NonZeroU32::new(u32::from_be_bytes(k2[i..j].try_into().unwrap()))
.ok_or(byzantine_fault!(InvalidPacket, true))?;
let (rk, rf) = noise.get_ask(LABEL_RATCHET_STATE);
let new_ratchet_state = RatchetState::new(rk, rf, zeta.ratchet_state1.chain_len + 1);
@@ -1271,7 +1363,10 @@ pub(crate) fn received_k2_trans<App: ApplicationLayer>(
let tag = App::Aead::encrypt_in_place(zeta.key_ref(false).send.kek.as_ref().unwrap(), n, None, &mut []);
c1.extend(&tag);
send(&Packet(zeta.key_ref(false).send.kid.unwrap().get(), n, c1), Some(&zeta.hk_send));
send(
&Packet(zeta.key_ref(false).send.kid.unwrap().get(), n, c1),
Some(&zeta.hk_send),
);
Ok(())
} else {
unreachable!()
@@ -1314,7 +1409,10 @@ pub(crate) fn send_payload<App: ApplicationLayer>(
let tag = App::Aead::encrypt_in_place(zeta.key_ref(false).send.nk.as_ref().unwrap(), n, None, &mut payload);
payload.extend(&tag);
send(&Packet(zeta.key_ref(false).send.kid.unwrap().get(), n, payload), Some(&zeta.hk_send));
send(
&Packet(zeta.key_ref(false).send.kid.unwrap().get(), n, payload),
Some(&zeta.hk_send),
);
Ok(())
}
/// Corresponds to Algorithm 10 found in Section 4.3.
@@ -1340,7 +1438,12 @@ pub(crate) fn received_payload_in_place<App: ApplicationLayer>(
};
let i = payload.len() - AES_GCM_TAG_SIZE;
let specified_key = zeta.key_ref(is_other).recv.nk.as_ref().ok_or(byzantine_fault!(OutOfSequence, true))?;
let specified_key = zeta
.key_ref(is_other)
.recv
.nk
.as_ref()
.ok_or(byzantine_fault!(OutOfSequence, true))?;
let tag = payload[i..].try_into().unwrap();
if !App::Aead::decrypt_in_place(specified_key, n, None, &mut payload[..i], tag) {
return Err(byzantine_fault!(FailedAuth, true));