Simplify.

This commit is contained in:
Adam Ierymenko 2021-11-17 15:56:41 -05:00
parent b57104afe2
commit 532d709b88
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3

View file

@ -19,7 +19,7 @@ use zerotier_core_crypto::sidhp751::{SIDHPublicKeyAlice, SIDHPublicKeyBob, SIDHS
use zerotier_core_crypto::varint; use zerotier_core_crypto::varint;
use crate::vl1::Address; use crate::vl1::Address;
use crate::vl1::protocol::{EphemeralKeyAgreementAlgorithm, EPHEMERAL_SECRET_USE_SIDH_EVERY_N_RATCHETS, EPHEMERAL_SECRET_REKEY_AFTER_TIME, EPHEMERAL_SECRET_REKEY_AFTER_USES, EPHEMERAL_SECRET_REJECT_AFTER_TIME}; use crate::vl1::protocol::*;
use crate::vl1::symmetricsecret::SymmetricSecret; use crate::vl1::symmetricsecret::SymmetricSecret;
/// A set of ephemeral secret key pairs. Multiple algorithms are used. /// A set of ephemeral secret key pairs. Multiple algorithms are used.
@ -124,7 +124,8 @@ impl EphemeralKeyPairSet {
) )
}); });
let mut algs: Vec<EphemeralKeyAgreementAlgorithm> = Vec::with_capacity(3); let mut ok = false;
let mut fips_compliant = false; // ends up true if last algorithm was FIPS compliant
let mut other_public_bytes = other_public_bytes; let mut other_public_bytes = other_public_bytes;
// Make sure the state of the ratchet matches on both ends. Otherwise it must restart. // Make sure the state of the ratchet matches on both ends. Otherwise it must restart.
@ -161,7 +162,8 @@ impl EphemeralKeyPairSet {
let c25519_secret = self.c25519.agree(&other_public_bytes[0..C25519_PUBLIC_KEY_SIZE]); let c25519_secret = self.c25519.agree(&other_public_bytes[0..C25519_PUBLIC_KEY_SIZE]);
other_public_bytes = &other_public_bytes[C25519_PUBLIC_KEY_SIZE..]; other_public_bytes = &other_public_bytes[C25519_PUBLIC_KEY_SIZE..];
key.0 = SHA384::hmac(&key.0, &c25519_secret.0); key.0 = SHA384::hmac(&key.0, &c25519_secret.0);
algs.push(EphemeralKeyAgreementAlgorithm::C25519); ok = true;
fips_compliant = false;
c25519_ratchet_count += 1; c25519_ratchet_count += 1;
}, },
@ -187,7 +189,8 @@ impl EphemeralKeyPairSet {
None => None, None => None,
}.map(|sidh_secret| { }.map(|sidh_secret| {
key.0 = SHA384::hmac(&key.0, &sidh_secret.0); key.0 = SHA384::hmac(&key.0, &sidh_secret.0);
algs.push(EphemeralKeyAgreementAlgorithm::SIDHP751); ok = true;
fips_compliant = false;
sidh_ratchet_count += 1; sidh_ratchet_count += 1;
}); });
other_public_bytes = &other_public_bytes[(SIDH_P751_PUBLIC_KEY_SIZE + 1)..]; other_public_bytes = &other_public_bytes[(SIDH_P751_PUBLIC_KEY_SIZE + 1)..];
@ -207,7 +210,8 @@ impl EphemeralKeyPairSet {
return None; return None;
} }
key.0 = SHA384::hmac(&key.0, &p521_key.unwrap().0); key.0 = SHA384::hmac(&key.0, &p521_key.unwrap().0);
algs.push(EphemeralKeyAgreementAlgorithm::NistP521ECDH); ok = true;
fips_compliant = true;
nistp521_ratchet_count += 1; nistp521_ratchet_count += 1;
}, },
@ -225,14 +229,14 @@ impl EphemeralKeyPairSet {
Some(EphemeralSymmetricSecret { Some(EphemeralSymmetricSecret {
secret: SymmetricSecret::new(key), secret: SymmetricSecret::new(key),
ratchet_state: SHA384::hash(&key.0)[0..16].try_into().unwrap(), ratchet_state: SHA384::hash(&key.0)[0..16].try_into().unwrap(),
agreement_algorithms: algs,
rekey_time: time_ticks + EPHEMERAL_SECRET_REKEY_AFTER_TIME, rekey_time: time_ticks + EPHEMERAL_SECRET_REKEY_AFTER_TIME,
expire_time: time_ticks + EPHEMERAL_SECRET_REJECT_AFTER_TIME, expire_time: time_ticks + EPHEMERAL_SECRET_REJECT_AFTER_TIME,
c25519_ratchet_count, c25519_ratchet_count,
sidhp751_ratchet_count, sidhp751_ratchet_count,
nistp512_ratchet_count, nistp512_ratchet_count,
encrypt_uses: AtomicU32::new(0), encrypt_uses: AtomicU32::new(0),
decrypt_uses: AtomicU32::new(0) decrypt_uses: AtomicU32::new(0),
fips_compliant
}) })
} else { } else {
None None
@ -244,7 +248,6 @@ impl EphemeralKeyPairSet {
pub struct EphemeralSymmetricSecret { pub struct EphemeralSymmetricSecret {
secret: SymmetricSecret, secret: SymmetricSecret,
ratchet_state: [u8; 16], ratchet_state: [u8; 16],
agreement_algorithms: Vec<EphemeralKeyAgreementAlgorithm>,
rekey_time: i64, rekey_time: i64,
expire_time: i64, expire_time: i64,
c25519_ratchet_count: u64, c25519_ratchet_count: u64,
@ -252,6 +255,7 @@ pub struct EphemeralSymmetricSecret {
nistp512_ratchet_count: u64, nistp512_ratchet_count: u64,
encrypt_uses: AtomicU32, encrypt_uses: AtomicU32,
decrypt_uses: AtomicU32, decrypt_uses: AtomicU32,
fips_compliant: bool,
} }
impl EphemeralSymmetricSecret { impl EphemeralSymmetricSecret {
@ -267,16 +271,15 @@ impl EphemeralSymmetricSecret {
&self.secret &self.secret
} }
pub fn is_fips_compliant(&self) -> bool {
self.agreement_algorithms.last().map_or(false, |alg| alg.is_fips_compliant())
}
pub fn should_rekey(&self, time_ticks: i64) -> bool { pub fn should_rekey(&self, time_ticks: i64) -> bool {
time_ticks >= self.rekey_time || self.encrypt_uses.load(Ordering::Relaxed).max(self.decrypt_uses.load(Ordering::Relaxed)) >= EPHEMERAL_SECRET_REKEY_AFTER_USES time_ticks >= self.rekey_time || self.encrypt_uses.load(Ordering::Relaxed).max(self.decrypt_uses.load(Ordering::Relaxed)) >= EPHEMERAL_SECRET_REKEY_AFTER_USES
} }
pub fn expired(&self, time_ticks: i64) -> bool {
time_ticks >= self.expire_time || self.encrypt_uses.load(Ordering::Relaxed).max(self.decrypt_uses.load(Ordering::Relaxed)) >= EPHEMERAL_SECRET_REJECT_AFTER_USES
}
} }
#[derive(Copy, Clone)]
enum SIDHEphemeralKeyPair { enum SIDHEphemeralKeyPair {
Alice(SIDHPublicKeyAlice, SIDHSecretKeyAlice), Alice(SIDHPublicKeyAlice, SIDHSecretKeyAlice),
Bob(SIDHPublicKeyBob, SIDHSecretKeyBob) Bob(SIDHPublicKeyBob, SIDHSecretKeyBob)