mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-22 06:56:54 +02:00
Rekeying is now tested and works.
This commit is contained in:
parent
652f7360f0
commit
8b6c9051fb
4 changed files with 158 additions and 107 deletions
|
@ -31,7 +31,7 @@ pub trait ApplicationLayer: Sized {
|
|||
/// Attempting to encrypt more than this many messages with a key will cause a hard error
|
||||
/// and the internal erasure of ephemeral key material. You'll only ever hit this if something
|
||||
/// goes wrong and rekeying fails.
|
||||
const EXPIRE_AFTER_USES: u64 = 2147483648;
|
||||
const EXPIRE_AFTER_USES: u64 = 2147483647;
|
||||
|
||||
/// Start attempting to rekey after a key has been in use for this many milliseconds.
|
||||
///
|
||||
|
|
102
zssp/src/main.rs
102
zssp/src/main.rs
|
@ -14,7 +14,7 @@ struct TestApplication {
|
|||
}
|
||||
|
||||
impl zssp::ApplicationLayer for TestApplication {
|
||||
const REKEY_AFTER_USES: u64 = 131072;
|
||||
const REKEY_AFTER_USES: u64 = 100000;
|
||||
const EXPIRE_AFTER_USES: u64 = 2147483648;
|
||||
const REKEY_AFTER_TIME_MS: i64 = 1000 * 60 * 60 * 2;
|
||||
const REKEY_AFTER_TIME_MS_MAX_JITTER: u32 = 1000 * 60 * 10;
|
||||
|
@ -44,6 +44,9 @@ fn alice_main(
|
|||
let context = zssp::Context::<TestApplication>::new(16);
|
||||
let mut data_buf = [0u8; 65536];
|
||||
let mut next_service = ms_monotonic() + 500;
|
||||
let mut last_ratchet_count = 0;
|
||||
let test_data = [1u8; 10000];
|
||||
let mut up = false;
|
||||
|
||||
let alice_session = context
|
||||
.open(
|
||||
|
@ -62,51 +65,57 @@ fn alice_main(
|
|||
|
||||
println!("[alice] opening session {}", alice_session.id.to_string());
|
||||
|
||||
let test_data = [1u8; 10000];
|
||||
let mut up = false;
|
||||
|
||||
while run.load(Ordering::Relaxed) {
|
||||
let pkt = alice_in.try_recv();
|
||||
let current_time = ms_monotonic();
|
||||
|
||||
if let Ok(pkt) = pkt {
|
||||
//println!("bob >> alice {}", pkt.len());
|
||||
match context.receive(
|
||||
alice_app,
|
||||
|| true,
|
||||
|s_public, _| Some((P384PublicKey::from_bytes(s_public).unwrap(), Secret::default(), ())),
|
||||
|_, b| {
|
||||
let _ = alice_out.send(b.to_vec());
|
||||
},
|
||||
&mut data_buf,
|
||||
pkt,
|
||||
TEST_MTU,
|
||||
current_time,
|
||||
) {
|
||||
Ok(zssp::ReceiveResult::Ok) => {
|
||||
//println!("[alice] ok");
|
||||
}
|
||||
Ok(zssp::ReceiveResult::OkData(_, _)) => {
|
||||
//println!("[alice] received {}", data.len());
|
||||
}
|
||||
Ok(zssp::ReceiveResult::OkNewSession(s)) => {
|
||||
println!("[alice] new session {}", s.id.to_string());
|
||||
}
|
||||
Ok(zssp::ReceiveResult::Rejected) => {}
|
||||
Err(e) => {
|
||||
println!("[alice] ERROR {}", e.to_string());
|
||||
loop {
|
||||
let pkt = alice_in.try_recv();
|
||||
if let Ok(pkt) = pkt {
|
||||
//println!("bob >> alice {}", pkt.len());
|
||||
match context.receive(
|
||||
alice_app,
|
||||
|| true,
|
||||
|s_public, _| Some((P384PublicKey::from_bytes(s_public).unwrap(), Secret::default(), ())),
|
||||
|_, b| {
|
||||
let _ = alice_out.send(b.to_vec());
|
||||
},
|
||||
&mut data_buf,
|
||||
pkt,
|
||||
TEST_MTU,
|
||||
current_time,
|
||||
) {
|
||||
Ok(zssp::ReceiveResult::Ok) => {
|
||||
//println!("[alice] ok");
|
||||
}
|
||||
Ok(zssp::ReceiveResult::OkData(_, data)) => {
|
||||
//println!("[alice] received {}", data.len());
|
||||
}
|
||||
Ok(zssp::ReceiveResult::OkNewSession(s)) => {
|
||||
println!("[alice] new session {}", s.id.to_string());
|
||||
}
|
||||
Ok(zssp::ReceiveResult::Rejected) => {}
|
||||
Err(e) => {
|
||||
println!("[alice] ERROR {}", e.to_string());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if up {
|
||||
let ratchet_count = alice_session.key_info().unwrap().0;
|
||||
if ratchet_count > last_ratchet_count {
|
||||
last_ratchet_count = ratchet_count;
|
||||
println!("[alice] new key! ratchet count {}", ratchet_count);
|
||||
}
|
||||
|
||||
assert!(alice_session
|
||||
.send(
|
||||
|b| {
|
||||
let _ = alice_out.send(b.to_vec());
|
||||
},
|
||||
&mut data_buf[..TEST_MTU],
|
||||
&test_data[..2048 + ((zerotier_crypto::random::xorshift64_random() as usize) % (test_data.len() - 2048))],
|
||||
&test_data[..1000 + ((zerotier_crypto::random::xorshift64_random() as usize) % (test_data.len() - 1000))],
|
||||
)
|
||||
.is_ok());
|
||||
} else {
|
||||
|
@ -137,6 +146,8 @@ fn bob_main(
|
|||
) {
|
||||
let context = zssp::Context::<TestApplication>::new(16);
|
||||
let mut data_buf = [0u8; 65536];
|
||||
let mut data_buf_2 = [0u8; TEST_MTU];
|
||||
let mut last_ratchet_count = 0;
|
||||
let mut last_speed_metric = ms_monotonic();
|
||||
let mut next_service = last_speed_metric + 500;
|
||||
let mut transferred = 0u64;
|
||||
|
@ -144,7 +155,7 @@ fn bob_main(
|
|||
let mut bob_session = None;
|
||||
|
||||
while run.load(Ordering::Relaxed) {
|
||||
let pkt = bob_in.recv_timeout(Duration::from_millis(10));
|
||||
let pkt = bob_in.recv_timeout(Duration::from_millis(100));
|
||||
let current_time = ms_monotonic();
|
||||
|
||||
if let Ok(pkt) = pkt {
|
||||
|
@ -164,9 +175,18 @@ fn bob_main(
|
|||
Ok(zssp::ReceiveResult::Ok) => {
|
||||
//println!("[bob] ok");
|
||||
}
|
||||
Ok(zssp::ReceiveResult::OkData(_, data)) => {
|
||||
Ok(zssp::ReceiveResult::OkData(s, data)) => {
|
||||
//println!("[bob] received {}", data.len());
|
||||
transferred += data.len() as u64;
|
||||
assert!(s
|
||||
.send(
|
||||
|b| {
|
||||
let _ = bob_out.send(b.to_vec());
|
||||
},
|
||||
&mut data_buf_2,
|
||||
data.as_mut(),
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
Ok(zssp::ReceiveResult::OkNewSession(s)) => {
|
||||
println!("[bob] new session {}", s.id.to_string());
|
||||
|
@ -179,6 +199,14 @@ fn bob_main(
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(bob_session) = bob_session.as_ref() {
|
||||
let ratchet_count = bob_session.key_info().unwrap().0;
|
||||
if ratchet_count > last_ratchet_count {
|
||||
last_ratchet_count = ratchet_count;
|
||||
println!("[bob] new key! ratchet count {}", ratchet_count);
|
||||
}
|
||||
}
|
||||
|
||||
let speed_metric_elapsed = current_time - last_speed_metric;
|
||||
if speed_metric_elapsed >= 1000 {
|
||||
last_speed_metric = current_time;
|
||||
|
@ -208,8 +236,8 @@ fn main() {
|
|||
let alice_app = TestApplication { identity_key: P384KeyPair::generate() };
|
||||
let bob_app = TestApplication { identity_key: P384KeyPair::generate() };
|
||||
|
||||
let (alice_out, bob_in) = mpsc::sync_channel::<Vec<u8>>(128);
|
||||
let (bob_out, alice_in) = mpsc::sync_channel::<Vec<u8>>(128);
|
||||
let (alice_out, bob_in) = mpsc::sync_channel::<Vec<u8>>(1024);
|
||||
let (bob_out, alice_in) = mpsc::sync_channel::<Vec<u8>>(1024);
|
||||
|
||||
thread::scope(|ts| {
|
||||
let alice_thread = ts.spawn(|| alice_main(&run, &alice_app, &bob_app, alice_out, alice_in));
|
||||
|
|
|
@ -33,8 +33,8 @@ pub(crate) const PACKET_TYPE_DATA: u8 = 0;
|
|||
pub(crate) const PACKET_TYPE_ALICE_NOISE_XK_INIT: u8 = 1;
|
||||
pub(crate) const PACKET_TYPE_BOB_NOISE_XK_ACK: u8 = 2;
|
||||
pub(crate) const PACKET_TYPE_ALICE_NOISE_XK_ACK: u8 = 3;
|
||||
pub(crate) const PACKET_TYPE_ALICE_REKEY_INIT: u8 = 4;
|
||||
pub(crate) const PACKET_TYPE_BOB_REKEY_ACK: u8 = 5;
|
||||
pub(crate) const PACKET_TYPE_REKEY_INIT: u8 = 4;
|
||||
pub(crate) const PACKET_TYPE_REKEY_ACK: u8 = 5;
|
||||
|
||||
pub(crate) const HEADER_SIZE: usize = 16;
|
||||
pub(crate) const HEADER_PROTECT_ENCRYPT_START: usize = 6;
|
||||
|
@ -123,24 +123,26 @@ pub(crate) const ALICE_NOISE_XK_ACK_MIN_SIZE: usize = ALICE_NOISE_XK_ACK_ENC_STA
|
|||
|
||||
#[allow(unused)]
|
||||
#[repr(C, packed)]
|
||||
pub(crate) struct AliceRekeyInit {
|
||||
pub(crate) struct RekeyInit {
|
||||
pub header: [u8; HEADER_SIZE],
|
||||
pub session_protocol_version: u8,
|
||||
// -- start AES-GCM encrypted portion (using current key)
|
||||
pub alice_e: [u8; P384_PUBLIC_KEY_SIZE],
|
||||
// -- end AES-GCM encrypted portion
|
||||
pub gcm_mac: [u8; AES_GCM_TAG_SIZE],
|
||||
}
|
||||
|
||||
impl AliceRekeyInit {
|
||||
pub const ENC_START: usize = HEADER_SIZE;
|
||||
impl RekeyInit {
|
||||
pub const ENC_START: usize = HEADER_SIZE + 1;
|
||||
pub const AUTH_START: usize = Self::ENC_START + P384_PUBLIC_KEY_SIZE;
|
||||
pub const SIZE: usize = Self::AUTH_START + AES_GCM_TAG_SIZE;
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
#[repr(C, packed)]
|
||||
pub(crate) struct BobRekeyAck {
|
||||
pub(crate) struct RekeyAck {
|
||||
pub header: [u8; HEADER_SIZE],
|
||||
pub session_protocol_version: u8,
|
||||
// -- start AES-GCM encrypted portion (using current key)
|
||||
pub bob_e: [u8; P384_PUBLIC_KEY_SIZE],
|
||||
pub next_key_fingerprint: [u8; SHA384_HASH_SIZE],
|
||||
|
@ -148,8 +150,8 @@ pub(crate) struct BobRekeyAck {
|
|||
pub gcm_mac: [u8; AES_GCM_TAG_SIZE],
|
||||
}
|
||||
|
||||
impl BobRekeyAck {
|
||||
pub const ENC_START: usize = HEADER_SIZE;
|
||||
impl RekeyAck {
|
||||
pub const ENC_START: usize = HEADER_SIZE + 1;
|
||||
pub const AUTH_START: usize = Self::ENC_START + P384_PUBLIC_KEY_SIZE + SHA384_HASH_SIZE;
|
||||
pub const SIZE: usize = Self::AUTH_START + AES_GCM_TAG_SIZE;
|
||||
}
|
||||
|
@ -161,8 +163,8 @@ pub(crate) trait ProtocolFlatBuffer {}
|
|||
impl ProtocolFlatBuffer for AliceNoiseXKInit {}
|
||||
impl ProtocolFlatBuffer for BobNoiseXKAck {}
|
||||
//impl ProtocolFlatBuffer for NoiseXKAliceStaticAck {}
|
||||
impl ProtocolFlatBuffer for AliceRekeyInit {}
|
||||
impl ProtocolFlatBuffer for BobRekeyAck {}
|
||||
impl ProtocolFlatBuffer for RekeyInit {}
|
||||
impl ProtocolFlatBuffer for RekeyAck {}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C, packed)]
|
||||
|
|
139
zssp/src/zssp.rs
139
zssp/src/zssp.rs
|
@ -119,7 +119,7 @@ struct OutgoingSessionInit {
|
|||
enum Offer {
|
||||
None,
|
||||
NoiseXKInit(Box<OutgoingSessionInit>),
|
||||
RekeyInit(P384KeyPair, [u8; AliceRekeyInit::SIZE], AtomicI64),
|
||||
RekeyInit(P384KeyPair, [u8; RekeyInit::SIZE], AtomicI64),
|
||||
}
|
||||
|
||||
/// An ephemeral session key with expiration info.
|
||||
|
@ -181,6 +181,7 @@ impl<Application: ApplicationLayer> Context<Application> {
|
|||
&& (current_time >= key.rekey_at_time
|
||||
|| session.send_counter.load(Ordering::Relaxed) >= key.rekey_at_counter)
|
||||
{
|
||||
drop(state);
|
||||
session.initiate_rekey(|b| send(&session, b), current_time);
|
||||
}
|
||||
}
|
||||
|
@ -1106,8 +1107,8 @@ impl<Application: ApplicationLayer> Context<Application> {
|
|||
}
|
||||
}
|
||||
|
||||
PACKET_TYPE_ALICE_REKEY_INIT => {
|
||||
if pkt_assembled.len() != AliceRekeyInit::SIZE {
|
||||
PACKET_TYPE_REKEY_INIT => {
|
||||
if pkt_assembled.len() != RekeyInit::SIZE {
|
||||
return Err(Error::InvalidPacket);
|
||||
}
|
||||
if incoming.is_some() {
|
||||
|
@ -1116,58 +1117,74 @@ 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() {
|
||||
// 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();
|
||||
c.reset_init_gcm(&incoming_message_nonce);
|
||||
c.crypt_in_place(&mut pkt_assembled[AliceRekeyInit::ENC_START..AliceRekeyInit::AUTH_START]);
|
||||
let aead_authentication_ok = c.finish_decrypt(&pkt_assembled[AliceRekeyInit::AUTH_START..]);
|
||||
key.return_receive_cipher(c);
|
||||
if let Some(remote_session_id) = state.remote_session_id {
|
||||
if let Some(key) = state.keys[key_index].as_ref() {
|
||||
// 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();
|
||||
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..]);
|
||||
key.return_receive_cipher(c);
|
||||
|
||||
if aead_authentication_ok {
|
||||
let pkt: &AliceRekeyInit = byte_array_as_proto_buffer(&pkt_assembled).unwrap();
|
||||
if let Some(alice_e) = P384PublicKey::from_bytes(&pkt.alice_e) {
|
||||
let bob_e_secret = P384KeyPair::generate();
|
||||
let next_session_key = Secret(hmac_sha512(
|
||||
key.ratchet_key.as_bytes(),
|
||||
bob_e_secret.agree(&alice_e).ok_or(Error::FailedAuthentication)?.as_bytes(),
|
||||
));
|
||||
if aead_authentication_ok {
|
||||
let pkt: &RekeyInit = byte_array_as_proto_buffer(&pkt_assembled).unwrap();
|
||||
if let Some(alice_e) = P384PublicKey::from_bytes(&pkt.alice_e) {
|
||||
let bob_e_secret = P384KeyPair::generate();
|
||||
let next_session_key = Secret(hmac_sha512(
|
||||
key.ratchet_key.as_bytes(),
|
||||
bob_e_secret.agree(&alice_e).ok_or(Error::FailedAuthentication)?.as_bytes(),
|
||||
));
|
||||
|
||||
let mut reply_buf = [0u8; BobRekeyAck::SIZE];
|
||||
let reply: &mut BobRekeyAck = byte_array_as_proto_buffer_mut(&mut reply_buf).unwrap();
|
||||
reply.bob_e = *bob_e_secret.public_key_bytes();
|
||||
reply.next_key_fingerprint = SHA384::hash(next_session_key.as_bytes());
|
||||
let mut reply_buf = [0u8; RekeyAck::SIZE];
|
||||
let reply: &mut RekeyAck = byte_array_as_proto_buffer_mut(&mut reply_buf).unwrap();
|
||||
reply.session_protocol_version = SESSION_PROTOCOL_VERSION;
|
||||
reply.bob_e = *bob_e_secret.public_key_bytes();
|
||||
reply.next_key_fingerprint = SHA384::hash(next_session_key.as_bytes());
|
||||
|
||||
let counter = session.get_next_outgoing_counter().ok_or(Error::MaxKeyLifetimeExceeded)?;
|
||||
let mut c = key.get_send_cipher(counter.get())?;
|
||||
c.reset_init_gcm(&create_message_nonce(PACKET_TYPE_BOB_REKEY_ACK, counter.get()));
|
||||
c.crypt_in_place(&mut reply_buf[BobRekeyAck::ENC_START..BobRekeyAck::AUTH_START]);
|
||||
reply_buf[BobRekeyAck::AUTH_START..].copy_from_slice(&c.finish_encrypt());
|
||||
key.return_send_cipher(c);
|
||||
let counter = session.get_next_outgoing_counter().ok_or(Error::MaxKeyLifetimeExceeded)?.get();
|
||||
set_packet_header(
|
||||
&mut reply_buf,
|
||||
1,
|
||||
0,
|
||||
PACKET_TYPE_REKEY_ACK,
|
||||
u64::from(remote_session_id),
|
||||
state.current_key,
|
||||
counter,
|
||||
);
|
||||
|
||||
send(Some(&session), &mut reply_buf);
|
||||
let mut 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());
|
||||
key.return_send_cipher(c);
|
||||
|
||||
// The new "Bob" doesn't know yet if Alice has received the new key, so the
|
||||
// new key is recorded as the "alt" (key_index ^ 1) but the current key is
|
||||
// not advanced yet. This happens automatically the first time we receive a
|
||||
// valid packet with the new key.
|
||||
let next_ratchet_count = key.ratchet_count + 1;
|
||||
drop(state);
|
||||
let mut state = session.state.write().unwrap();
|
||||
let _ = state.keys[key_index ^ 1].replace(SessionKey::new::<Application>(
|
||||
next_session_key,
|
||||
next_ratchet_count,
|
||||
current_time,
|
||||
counter.get(),
|
||||
false,
|
||||
));
|
||||
session.header_protection_cipher.encrypt_block_in_place(
|
||||
&mut reply_buf[HEADER_PROTECT_ENCRYPT_START..HEADER_PROTECT_ENCRYPT_END],
|
||||
);
|
||||
send(Some(&session), &mut reply_buf);
|
||||
|
||||
return Ok(ReceiveResult::Ok);
|
||||
// The new "Bob" doesn't know yet if Alice has received the new key, so the
|
||||
// new key is recorded as the "alt" (key_index ^ 1) but the current key is
|
||||
// not advanced yet. This happens automatically the first time we receive a
|
||||
// valid packet with the new key.
|
||||
let next_ratchet_count = key.ratchet_count + 1;
|
||||
drop(state);
|
||||
let mut state = session.state.write().unwrap();
|
||||
let _ = state.keys[key_index ^ 1].replace(SessionKey::new::<Application>(
|
||||
next_session_key,
|
||||
next_ratchet_count,
|
||||
current_time,
|
||||
counter,
|
||||
false,
|
||||
));
|
||||
|
||||
return Ok(ReceiveResult::Ok);
|
||||
}
|
||||
}
|
||||
return Err(Error::FailedAuthentication);
|
||||
}
|
||||
return Err(Error::FailedAuthentication);
|
||||
}
|
||||
}
|
||||
return Err(Error::OutOfSequence);
|
||||
|
@ -1176,8 +1193,8 @@ impl<Application: ApplicationLayer> Context<Application> {
|
|||
}
|
||||
}
|
||||
|
||||
PACKET_TYPE_BOB_REKEY_ACK => {
|
||||
if pkt_assembled.len() != BobRekeyAck::SIZE {
|
||||
PACKET_TYPE_REKEY_ACK => {
|
||||
if pkt_assembled.len() != RekeyAck::SIZE {
|
||||
return Err(Error::InvalidPacket);
|
||||
}
|
||||
if incoming.is_some() {
|
||||
|
@ -1192,12 +1209,12 @@ impl<Application: ApplicationLayer> Context<Application> {
|
|||
if key.bob {
|
||||
let mut c = key.get_receive_cipher();
|
||||
c.reset_init_gcm(&incoming_message_nonce);
|
||||
c.crypt_in_place(&mut pkt_assembled[BobRekeyAck::ENC_START..BobRekeyAck::AUTH_START]);
|
||||
let aead_authentication_ok = c.finish_decrypt(&pkt_assembled[BobRekeyAck::AUTH_START..]);
|
||||
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..]);
|
||||
key.return_receive_cipher(c);
|
||||
|
||||
if aead_authentication_ok {
|
||||
let pkt: &BobRekeyAck = byte_array_as_proto_buffer(&pkt_assembled).unwrap();
|
||||
let pkt: &RekeyAck = byte_array_as_proto_buffer(&pkt_assembled).unwrap();
|
||||
if let Some(bob_e) = P384PublicKey::from_bytes(&pkt.bob_e) {
|
||||
let next_session_key = Secret(hmac_sha512(
|
||||
key.ratchet_key.as_bytes(),
|
||||
|
@ -1333,8 +1350,9 @@ impl<Application: ApplicationLayer> Session<Application> {
|
|||
fn initiate_rekey<SendFunction: FnMut(&mut [u8])>(&self, mut send: SendFunction, current_time: i64) {
|
||||
let rekey_e = P384KeyPair::generate();
|
||||
|
||||
let mut rekey_buf = [0u8; AliceRekeyInit::SIZE];
|
||||
let pkt: &mut AliceRekeyInit = byte_array_as_proto_buffer_mut(&mut rekey_buf).unwrap();
|
||||
let mut rekey_buf = [0u8; RekeyInit::SIZE];
|
||||
let pkt: &mut RekeyInit = byte_array_as_proto_buffer_mut(&mut rekey_buf).unwrap();
|
||||
pkt.session_protocol_version = SESSION_PROTOCOL_VERSION;
|
||||
pkt.alice_e = *rekey_e.public_key_bytes();
|
||||
|
||||
let state = self.state.read().unwrap();
|
||||
|
@ -1342,9 +1360,9 @@ impl<Application: ApplicationLayer> Session<Application> {
|
|||
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()) {
|
||||
gcm.reset_init_gcm(&create_message_nonce(PACKET_TYPE_ALICE_REKEY_INIT, counter.get()));
|
||||
gcm.crypt_in_place(&mut rekey_buf[AliceRekeyInit::ENC_START..AliceRekeyInit::AUTH_START]);
|
||||
rekey_buf[AliceRekeyInit::AUTH_START..].copy_from_slice(&gcm.finish_encrypt());
|
||||
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());
|
||||
key.return_send_cipher(gcm);
|
||||
|
||||
debug_assert!(rekey_buf.len() <= MIN_TRANSPORT_MTU);
|
||||
|
@ -1352,15 +1370,18 @@ impl<Application: ApplicationLayer> Session<Application> {
|
|||
&mut rekey_buf,
|
||||
1,
|
||||
0,
|
||||
PACKET_TYPE_ALICE_REKEY_INIT,
|
||||
PACKET_TYPE_REKEY_INIT,
|
||||
u64::from(remote_session_id),
|
||||
state.current_key,
|
||||
counter.get(),
|
||||
);
|
||||
|
||||
drop(state);
|
||||
|
||||
self.header_protection_cipher
|
||||
.encrypt_block_in_place(&mut rekey_buf[HEADER_PROTECT_ENCRYPT_START..HEADER_PROTECT_ENCRYPT_END]);
|
||||
send(&mut rekey_buf);
|
||||
|
||||
drop(state);
|
||||
self.state.write().unwrap().current_offer = Offer::RekeyInit(rekey_e, rekey_buf, AtomicI64::new(current_time));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue