Add tests for CREATE_FAST handshake

This commit is contained in:
Nick Mathewson 2020-09-19 13:03:31 -04:00
parent 80d1d27810
commit 56d8bc1756
4 changed files with 100 additions and 26 deletions

View File

@ -9,3 +9,5 @@
pub mod cell;
pub mod handshake;
pub mod ll;
#[cfg(test)]
mod testing;

View File

@ -83,3 +83,72 @@ impl super::ServerHandshake for CreateFastServer {
Ok((super::TAPKeyGenerator::new(inp.into()), reply))
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::crypto::handshake::{ClientHandshake, KeyGenerator, ServerHandshake};
use hex_literal::hex;
#[test]
fn roundtrip() {
let mut rng = rand::thread_rng();
let (state, cmsg) = CreateFastClient::client1(&mut rng, &()).unwrap();
let (s_kg, smsg) = CreateFastServer::server(&mut rng, &[()], cmsg).unwrap();
let c_kg = CreateFastClient::client2(state, smsg).unwrap();
let s_key = s_kg.expand(200).unwrap();
let c_key = c_kg.expand(200).unwrap();
assert_eq!(s_key, c_key);
}
#[test]
fn failure() {
let mut rng = rand::thread_rng();
// badly formatted client message.
let cmsg = [6u8; 19];
let ans = CreateFastServer::server(&mut rng, &[()], cmsg);
assert!(ans.is_err());
// corrupt/ incorrect server reply.
let (state, cmsg) = CreateFastClient::client1(&mut rng, &()).unwrap();
let (_, mut smsg) = CreateFastServer::server(&mut rng, &[()], cmsg).unwrap();
smsg[35] ^= 16;
let ans = CreateFastClient::client2(state, smsg);
assert!(ans.is_err());
}
fn test_one_handshake(cmsg: [u8; 20], smsg: [u8; 40], keys: [u8; 100]) {
use crate::crypto::testing::FakePRNG;
let mut rng = FakePRNG::new(&cmsg);
let (state, cmsg) = CreateFastClient::client1(&mut rng, &()).unwrap();
let mut rng = FakePRNG::new(&smsg);
let (s_kg, smsg) = CreateFastServer::server(&mut rng, &[()], cmsg).unwrap();
let c_kg = CreateFastClient::client2(state, smsg).unwrap();
let s_key = s_kg.expand(100).unwrap();
let c_key = c_kg.expand(100).unwrap();
assert_eq!(s_key, c_key);
assert_eq!(&s_key[..], &keys[..]);
}
#[test]
fn testvec() {
// Generated from Tor.
test_one_handshake(
hex!("080E247DF7C252FCD2DC10F459703480C223E3A6"),
hex!("BA95C0D092335428BF80093BBED0B7A26C49E1E8696FBF9C8D6BE26504219C000D26AFE370FCEF04"),
hex!("AFA89B4FC8CF882335A582C52478B5FCB1E08DAF707E2C2D23B8C27D30BD461F3DF98A3AF82221CB658AD0AA8680B99067E4F7DBC546970EA9A56B26433C71DA867BDD09C14A1308BC327D6A448D71D2382B3AB6AF0BB4E19649A8DFF607DB9C57A04AC3"));
test_one_handshake(
hex!("5F786C724C2F5978474A04FA63772057AD896A03"),
hex!("6210B037001405742FE78B6F5B34E6DB3C9F2F7E24239498613E0ED872E110A00774A3FCB37A7507"),
hex!("D41B65D83FB4B34A322B658BE4D706EDCD8B62813757E719118C394E1F22E1C8EA8959BAB30E856A914C3054946F547397094DE031F5BCA384C65C8880BF7AAB9CE7BEE33971F9DE8C22A23366F46BF8B5E5112321E216B0E02C62EEA3ABB72A0E062592"));
}
}

View File

@ -276,6 +276,7 @@ where
#[cfg(test)]
mod tests {
use super::*;
use crate::crypto::testing::FakePRNG;
#[test]
fn simple() -> Result<()> {
@ -308,32 +309,6 @@ mod tests {
Ok(())
}
struct FakePRNG<'a> {
bytes: &'a [u8],
}
impl<'a> FakePRNG<'a> {
fn new(bytes: &'a [u8]) -> Self {
Self { bytes }
}
}
impl<'a> RngCore for FakePRNG<'a> {
fn next_u32(&mut self) -> u32 {
rand_core::impls::next_u32_via_fill(self)
}
fn next_u64(&mut self) -> u64 {
rand_core::impls::next_u64_via_fill(self)
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> std::result::Result<(), rand_core::Error> {
Ok(self.fill_bytes(dest))
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
assert!(dest.len() <= self.bytes.len());
dest.copy_from_slice(&self.bytes[0..dest.len()]);
self.bytes = &self.bytes[dest.len()..];
}
}
impl rand_core::CryptoRng for FakePRNG<'_> {}
fn make_fake_ephem_key(bytes: &[u8]) -> EphemeralSecret {
assert_eq!(bytes.len(), 32);
let mut rng = FakePRNG::new(bytes);

View File

@ -0,0 +1,28 @@
use rand_core;
pub struct FakePRNG<'a> {
bytes: &'a [u8],
}
impl<'a> FakePRNG<'a> {
pub fn new(bytes: &'a [u8]) -> Self {
Self { bytes }
}
}
impl<'a> rand_core::RngCore for FakePRNG<'a> {
fn next_u32(&mut self) -> u32 {
rand_core::impls::next_u32_via_fill(self)
}
fn next_u64(&mut self) -> u64 {
rand_core::impls::next_u64_via_fill(self)
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> std::result::Result<(), rand_core::Error> {
Ok(self.fill_bytes(dest))
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
assert!(dest.len() <= self.bytes.len());
dest.copy_from_slice(&self.bytes[0..dest.len()]);
self.bytes = &self.bytes[dest.len()..];
}
}
impl rand_core::CryptoRng for FakePRNG<'_> {}