Compare commits

..

14 Commits

Author SHA1 Message Date
Alice Bowman
60a411e363 removed m1 cargo test 2024-06-17 15:39:43 +02:00
Alice Bowman
caf8801004 trialing cargo m1 test 2024-06-13 15:42:02 +02:00
Alice Bowman
858c0904ad refactored different cargo os tests into an array 2024-06-13 15:19:20 +02:00
Alice Bowman
e9838722b0 changed qc arm test to mac-14 to avoid bug 2024-06-13 15:12:34 +02:00
Alice Bowman
69043fbae7 added Mac ARM cargo test 2024-06-13 15:01:20 +02:00
Prabhpreet Dua
a70b71d509 Include uncommited changes 2024-06-13 17:35:10 +05:30
Prabhpreet Dua
96bed38ad0 Enable privileged only on linux 2024-06-13 17:34:48 +05:30
Prabhpreet Dua
a75d7a53e0 Add cfg flag to bin .rs files 2024-06-13 17:19:57 +05:30
Prabhpreet Dua
c4314c0eff Limit wireguard broker privledged/socket handler to linux 2024-06-13 17:13:00 +05:30
Alice Bowman
511a59fe1b Alter target OS for mod.rs 2024-06-13 13:18:23 +02:00
Alice Bowman
5e4a7c3b7f netlink.rs and cargo.toml features re: xplatform 2024-06-13 13:07:51 +02:00
Alice Bowman
139e62d1fb fixed indentation 2024-06-13 12:34:06 +02:00
Alice Bowman
c417fafe2a fixed qc-yaml test name 2024-06-13 12:30:56 +02:00
Alice Bowman
8f4141a159 added cargo-test runner for macos 86-64 2024-06-13 12:27:58 +02:00
28 changed files with 150 additions and 451 deletions

View File

@@ -1,33 +0,0 @@
#!/usr/bin/env bash
iterations="$1"
sleep_time="$2"
PWD="$(pwd)"
EXEC="$PWD/target/release/rosenpass"
LOGS="$PWD/output/logs"
mkdir -p "$LOGS"
run_command() {
local file=$1
local log_file="$2"
("$EXEC" exchange-config "$file" 2>&1 | tee -a "$log_file") &
echo $!
}
pids=()
(cd output/dut && run_command "configs/dut-$iterations.toml" "$LOGS/dut.log")
for (( x=0; x<iterations; x++ )); do
(cd output/ate && run_command "configs/ate-$x.toml" "$LOGS/ate-$x.log") & pids+=($!)
done
sleep "$sleep_time"
lsof -i :9999 | awk 'NR!=1 {print $2}' | xargs kill
for (( x=0; x<iterations; x++ )); do
port=$((x + 50000))
lsof -i :$port | awk 'NR!=1 {print $2}' | xargs kill
done

View File

@@ -1,21 +0,0 @@
name: QC
on:
pull_request:
push:
branches: [main]
permissions:
checks: write
contents: read
jobs:
multi-peer:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: cargo build --bin rosenpass --release
- run: python misc/generate_configs.py
- run: chmod +x .ci/run-regression.sh
- run: .ci/run-regression.sh 100 20
- run: |
[ $(ls -1 output/ate/out | wc -l) -eq 100 ]

2
.gitignore vendored
View File

@@ -20,5 +20,3 @@ _markdown_*
**/result
**/result-*
.direnv
/output

View File

@@ -1 +0,0 @@
Clara Engler <cve@cve.cx> <me@emilengler.com>

93
Cargo.lock generated
View File

@@ -387,9 +387,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.9"
version = "4.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462"
checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f"
dependencies = [
"clap_builder",
"clap_derive",
@@ -397,9 +397,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.9"
version = "4.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942"
checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f"
dependencies = [
"anstream",
"anstyle",
@@ -409,9 +409,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.5.8"
version = "4.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085"
checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6"
dependencies = [
"heck",
"proc-macro2",
@@ -984,10 +984,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if 1.0.0",
"js-sys",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
"wasm-bindgen",
]
[[package]]
@@ -1230,38 +1228,6 @@ version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "libcrux"
version = "0.0.2-pre.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31d9dcd435758db03438089760c55a45e6bcab7e4e299ee261f75225ab29d482"
dependencies = [
"getrandom 0.2.15",
"libcrux-hacl",
"libcrux-platform",
"libjade-sys",
"rand 0.8.5",
]
[[package]]
name = "libcrux-hacl"
version = "0.0.2-pre.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52b2581ce493c5c22700077b5552b47be69b67b8176716572b02856218db0b68"
dependencies = [
"cc",
"libcrux-platform",
]
[[package]]
name = "libcrux-platform"
version = "0.0.2-pre.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "647e39666194b11df17c19451d1154b9be79df98b9821532560c2ecad0cf3410"
dependencies = [
"libc",
]
[[package]]
name = "libfuzzer-sys"
version = "0.4.7"
@@ -1273,16 +1239,6 @@ dependencies = [
"once_cell",
]
[[package]]
name = "libjade-sys"
version = "0.0.2-pre.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec4d22bba476bf8f5aebe36ccfd0e56dba8707e0c3b5c76996576028f48ffb8e"
dependencies = [
"cc",
"libcrux-platform",
]
[[package]]
name = "libloading"
version = "0.8.3"
@@ -1311,9 +1267,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.22"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "memchr"
@@ -1935,7 +1891,7 @@ name = "rosenpass"
version = "0.2.1"
dependencies = [
"anyhow",
"clap 4.5.9",
"clap 4.5.7",
"criterion",
"derive_builder 0.20.0",
"env_logger",
@@ -1974,7 +1930,6 @@ dependencies = [
"anyhow",
"blake2",
"chacha20poly1305",
"libcrux",
"rosenpass-constant-time",
"rosenpass-oqs",
"rosenpass-secret-memory",
@@ -2059,7 +2014,7 @@ name = "rosenpass-wireguard-broker"
version = "0.1.0"
dependencies = [
"anyhow",
"clap 4.5.9",
"clap 4.5.7",
"derive_builder 0.20.0",
"env_logger",
"log",
@@ -2199,18 +2154,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]]
name = "serde"
version = "1.0.204"
version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.204"
version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
dependencies = [
"proc-macro2",
"quote",
@@ -2417,18 +2372,18 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
[[package]]
name = "thiserror"
version = "1.0.63"
version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.63"
version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
dependencies = [
"proc-macro2",
"quote",
@@ -2447,9 +2402,9 @@ dependencies = [
[[package]]
name = "tokio"
version = "1.38.1"
version = "1.38.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df"
checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
dependencies = [
"backtrace",
"bytes",
@@ -2945,9 +2900,9 @@ dependencies = [
[[package]]
name = "zerocopy"
version = "0.7.35"
version = "0.7.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
dependencies = [
"byteorder",
"zerocopy-derive",
@@ -2955,9 +2910,9 @@ dependencies = [
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
version = "0.7.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
dependencies = [
"proc-macro2",
"quote",

View File

@@ -35,7 +35,7 @@ doc-comment = "0.3.3"
base64ct = {version = "1.6.0", default-features=false}
zeroize = "1.8.1"
memoffset = "0.9.1"
thiserror = "1.0.63"
thiserror = "1.0.61"
paste = "1.0.15"
env_logger = "0.10.2"
toml = "0.7.8"
@@ -44,9 +44,9 @@ allocator-api2 = "0.2.14"
memsec = { git="https://github.com/rosenpass/memsec.git" ,rev="aceb9baee8aec6844125bd6612f92e9a281373df", features = [ "alloc_ext", ] }
rand = "0.8.5"
typenum = "1.17.0"
log = { version = "0.4.22" }
clap = { version = "4.5.9", features = ["derive"] }
serde = { version = "1.0.204", features = ["derive"] }
log = { version = "0.4.21" }
clap = { version = "4.5.7", features = ["derive"] }
serde = { version = "1.0.203", features = ["derive"] }
arbitrary = { version = "1.3.2", features = ["derive"] }
anyhow = { version = "1.0.86", features = ["backtrace", "std"] }
mio = { version = "0.8.11", features = ["net", "os-poll"] }
@@ -59,12 +59,11 @@ chacha20poly1305 = { version = "0.10.1", default-features = false, features = [
"std",
"heapless",
] }
zerocopy = { version = "0.7.35", features = ["derive"] }
zerocopy = { version = "0.7.34", features = ["derive"] }
home = "0.5.9"
derive_builder = "0.20.0"
tokio = { version = "1.38", features = ["macros", "rt-multi-thread"] }
postcard= {version = "1.0.8", features = ["alloc"]}
libcrux = { version = "0.0.2-pre.2" }
#Dev dependencies
serial_test = "3.1.1"

View File

@@ -9,9 +9,6 @@ homepage = "https://rosenpass.eu/"
repository = "https://github.com/rosenpass/rosenpass"
readme = "readme.md"
[features]
experiment_libcrux = ["dep:libcrux"]
[dependencies]
anyhow = { workspace = true }
rosenpass-to = { workspace = true }
@@ -23,4 +20,3 @@ static_assertions = { workspace = true }
zeroize = { workspace = true }
chacha20poly1305 = { workspace = true }
blake2 = { workspace = true }
libcrux = { workspace = true, optional = true }

View File

@@ -9,9 +9,6 @@ const_assert!(KEY_LEN == hash_domain::KEY_LEN);
/// Authenticated encryption with associated data
pub mod aead {
#[cfg(not(feature = "libcrux"))]
pub use crate::subtle::chacha20poly1305_ietf::{decrypt, encrypt, KEY_LEN, NONCE_LEN, TAG_LEN};
#[cfg(feature = "libcrux")]
pub use crate::subtle::chacha20poly1305_ietf::{decrypt, encrypt, KEY_LEN, NONCE_LEN, TAG_LEN};
}

View File

@@ -1,60 +0,0 @@
use rosenpass_to::ops::copy_slice;
use rosenpass_to::To;
use zeroize::Zeroize;
pub const KEY_LEN: usize = 32; // Grrrr! Libcrux, please provide me these constants.
pub const TAG_LEN: usize = 16;
pub const NONCE_LEN: usize = 12;
#[inline]
pub fn encrypt(
ciphertext: &mut [u8],
key: &[u8],
nonce: &[u8],
ad: &[u8],
plaintext: &[u8],
) -> anyhow::Result<()> {
let (ciphertext, mac) = ciphertext.split_at_mut(ciphertext.len() - TAG_LEN);
use libcrux::aead as C;
let crux_key = C::Key::Chacha20Poly1305(C::Chacha20Key(key.try_into().unwrap()));
let crux_iv = C::Iv(nonce.try_into().unwrap());
copy_slice(plaintext).to(ciphertext);
let crux_tag = libcrux::aead::encrypt(&crux_key, ciphertext, crux_iv, ad).unwrap();
copy_slice(crux_tag.as_ref()).to(mac);
match crux_key {
C::Key::Chacha20Poly1305(mut k) => k.0.zeroize(),
_ => panic!(),
}
Ok(())
}
#[inline]
pub fn decrypt(
plaintext: &mut [u8],
key: &[u8],
nonce: &[u8],
ad: &[u8],
ciphertext: &[u8],
) -> anyhow::Result<()> {
let (ciphertext, mac) = ciphertext.split_at(ciphertext.len() - TAG_LEN);
use libcrux::aead as C;
let crux_key = C::Key::Chacha20Poly1305(C::Chacha20Key(key.try_into().unwrap()));
let crux_iv = C::Iv(nonce.try_into().unwrap());
let crux_tag = C::Tag::from_slice(mac).unwrap();
copy_slice(ciphertext).to(plaintext);
libcrux::aead::decrypt(&crux_key, plaintext, crux_iv, ad, &crux_tag).unwrap();
match crux_key {
C::Key::Chacha20Poly1305(mut k) => k.0.zeroize(),
_ => panic!(),
}
Ok(())
}

View File

@@ -1,7 +1,4 @@
pub mod blake2b;
#[cfg(not(feature = "libcrux"))]
pub mod chacha20poly1305_ietf;
#[cfg(feature = "libcrux")]
pub mod chacha20poly1305_ietf_libcrux;
pub mod incorrect_hmac_blake2b;
pub mod xchacha20poly1305_ietf;

View File

@@ -108,7 +108,7 @@ Rosenpass was created by Karolin Varner, Benjamin Lipp, Wanja Zaeske,
Marei Peischl, Stephan Ajuvo, and Lisa Schmidt.
.Pp
This manual page was written by
.An Clara Engler
.An Emil Engler
.Sh BUGS
The bugs are tracked at
.Lk https://github.com/rosenpass/rosenpass/issues .

View File

@@ -113,7 +113,7 @@ Rosenpass was created by Karolin Varner, Benjamin Lipp, Wanja Zaeske,
Marei Peischl, Stephan Ajuvo, and Lisa Schmidt.
.Pp
This manual page was written by
.An Clara Engler
.An Emil Engler
.Sh BUGS
The bugs are tracked at
.Lk https://github.com/rosenpass/rosenpass/issues .

View File

@@ -4,9 +4,6 @@ version = "0.0.1"
publish = false
edition = "2021"
[features]
experiment_libcrux = ["rosenpass-ciphers/experiment_libcrux"]
[package.metadata]
cargo-fuzz = true

View File

@@ -7,14 +7,14 @@ use rosenpass::protocol::CryptoServer;
use rosenpass_cipher_traits::Kem;
use rosenpass_ciphers::kem::StaticKem;
use rosenpass_secret_memory::policy::*;
use rosenpass_secret_memory::{PublicBox, Secret};
use rosenpass_secret_memory::Secret;
use std::sync::Once;
static ONCE: Once = Once::new();
fuzz_target!(|rx_buf: &[u8]| {
ONCE.call_once(secret_policy_use_only_malloc_secrets);
let sk = Secret::from_slice(&[0; StaticKem::SK_LEN]);
let pk = PublicBox::from_slice(&[0; StaticKem::PK_LEN]);
let pk = Secret::from_slice(&[0; StaticKem::PK_LEN]);
let mut cs = CryptoServer::new(sk, pk);
let mut tx_buf = [0; 10240];

View File

@@ -14,7 +14,7 @@ pub struct Input {
fuzz_target!(|input: Input| {
let mut ciphertext = [0u8; EphemeralKem::CT_LEN];
let mut shared_secret = [0u8; EphemeralKem::SHK_LEN];
let mut shared_secret = [0u8; EphemeralKem::SK_LEN];
EphemeralKem::encaps(&mut shared_secret, &mut ciphertext, &input.pk).unwrap();
});

View File

@@ -1,14 +1,14 @@
from pathlib import Path
from subprocess import run
import os
config = dict(
peer_counts=[1, 5, 10, 50, 100, 500],
peer_count_max=100,
ate_ip="127.0.0.1",
dut_ip="127.0.0.1",
ate_ip="192.168.2.1",
dut_ip="192.168.2.4",
dut_port=9999,
path_to_rosenpass_bin=os.getcwd() + "/target/release/rosenpass",
path_to_rosenpass_bin="/Users/user/src/rosenppass/rosenpass/target/debug/rosenpass",
)
print(config)

View File

@@ -54,4 +54,3 @@ procspawn = {workspace = true}
[features]
enable_broker_api = ["rosenpass-wireguard-broker/enable_broker_api"]
enable_memfd_alloc = []
experiment_libcrux = ["rosenpass-ciphers/experiment_libcrux"]

View File

@@ -1,6 +1,5 @@
use anyhow::Result;
use rosenpass::protocol::{CryptoServer, HandleMsgResult, MsgBuf, PeerPtr, SPk, SSk, SymKey};
use std::ops::DerefMut;
use rosenpass_cipher_traits::Kem;
use rosenpass_ciphers::kem::StaticKem;
@@ -41,7 +40,7 @@ fn hs(ini: &mut CryptoServer, res: &mut CryptoServer) -> Result<()> {
fn keygen() -> Result<(SSk, SPk)> {
let (mut sk, mut pk) = (SSk::zero(), SPk::zero());
StaticKem::keygen(sk.secret_mut(), pk.deref_mut())?;
StaticKem::keygen(sk.secret_mut(), pk.secret_mut())?;
Ok((sk, pk))
}

View File

@@ -6,11 +6,10 @@ use rosenpass_secret_memory::file::StoreSecret;
use rosenpass_secret_memory::{
secret_policy_try_use_memfd_secrets, secret_policy_use_only_malloc_secrets,
};
use rosenpass_util::file::{LoadValue, LoadValueB64, StoreValue};
use rosenpass_util::file::{LoadValue, LoadValueB64};
use rosenpass_wireguard_broker::brokers::native_unix::{
NativeUnixBroker, NativeUnixBrokerConfigBaseBuilder, NativeUnixBrokerConfigBaseBuilderError,
};
use std::ops::DerefMut;
use std::path::PathBuf;
use crate::app_server::AppServerTest;
@@ -371,7 +370,7 @@ impl CliCommand {
fn generate_and_save_keypair(secret_key: PathBuf, public_key: PathBuf) -> anyhow::Result<()> {
let mut ssk = crate::protocol::SSk::random();
let mut spk = crate::protocol::SPk::random();
StaticKem::keygen(ssk.secret_mut(), spk.deref_mut())?;
StaticKem::keygen(ssk.secret_mut(), spk.secret_mut())?;
ssk.store_secret(secret_key)?;
spk.store(public_key)
}

View File

@@ -19,7 +19,6 @@
//! [CryptoServer].
//!
//! ```
//! use std::ops::DerefMut;
//! use rosenpass_secret_memory::policy::*;
//! use rosenpass_cipher_traits::Kem;
//! use rosenpass_ciphers::kem::StaticKem;
@@ -33,11 +32,11 @@
//!
//! // initialize secret and public key for peer a ...
//! let (mut peer_a_sk, mut peer_a_pk) = (SSk::zero(), SPk::zero());
//! StaticKem::keygen(peer_a_sk.secret_mut(), peer_a_pk.deref_mut())?;
//! StaticKem::keygen(peer_a_sk.secret_mut(), peer_a_pk.secret_mut())?;
//!
//! // ... and for peer b
//! let (mut peer_b_sk, mut peer_b_pk) = (SSk::zero(), SPk::zero());
//! StaticKem::keygen(peer_b_sk.secret_mut(), peer_b_pk.deref_mut())?;
//! StaticKem::keygen(peer_b_sk.secret_mut(), peer_b_pk.secret_mut())?;
//!
//! // initialize server and a pre-shared key
//! let psk = SymKey::random();
@@ -72,7 +71,6 @@
use std::convert::Infallible;
use std::mem::size_of;
use std::ops::Deref;
use std::{
collections::hash_map::{
Entry::{Occupied, Vacant},
@@ -90,7 +88,7 @@ use rosenpass_ciphers::hash_domain::{SecretHashDomain, SecretHashDomainNamespace
use rosenpass_ciphers::kem::{EphemeralKem, StaticKem};
use rosenpass_ciphers::{aead, xaead, KEY_LEN};
use rosenpass_constant_time as constant_time;
use rosenpass_secret_memory::{Public, PublicBox, Secret};
use rosenpass_secret_memory::{Public, Secret};
use rosenpass_util::{cat, mem::cpy_min, ord::max_usize, time::Timebase};
use zerocopy::{AsBytes, FromBytes, Ref};
@@ -165,7 +163,7 @@ pub fn has_happened(ev: Timing, now: Timing) -> bool {
// DATA STRUCTURES & BASIC TRAITS & ACCESSORS ////
pub type SPk = PublicBox<{ StaticKem::PK_LEN }>;
pub type SPk = Secret<{ StaticKem::PK_LEN }>; // Just Secret<> instead of Public<> so it gets allocated on the heap
pub type SSk = Secret<{ StaticKem::SK_LEN }>;
pub type EPk = Public<{ EphemeralKem::PK_LEN }>;
pub type ESk = Secret<{ EphemeralKem::SK_LEN }>;
@@ -550,7 +548,7 @@ impl CryptoServer {
pub fn pidm(&self) -> Result<PeerId> {
Ok(Public::new(
hash_domains::peerid()?
.mix(self.spkm.deref())?
.mix(self.spkm.secret())?
.into_value()))
}
@@ -710,7 +708,7 @@ impl Peer {
pub fn pidt(&self) -> Result<PeerId> {
Ok(Public::new(
hash_domains::peerid()?
.mix(self.spkt.deref())?
.mix(self.spkt.secret())?
.into_value()))
}
}
@@ -1019,7 +1017,7 @@ impl CryptoServer {
let cookie_value = active_cookie_value.unwrap();
let cookie_key = hash_domains::cookie_key()?
.mix(self.spkm.deref())?
.mix(self.spkm.secret())?
.into_value();
let mut msg_out = truncating_cast_into::<CookieReply>(tx_buf)?;
@@ -1511,7 +1509,7 @@ where
/// Calculate the message authentication code (`mac`) and also append cookie value
pub fn seal(&mut self, peer: PeerPtr, srv: &CryptoServer) -> Result<()> {
let mac = hash_domains::mac()?
.mix(peer.get(srv).spkt.deref())?
.mix(peer.get(srv).spkt.secret())?
.mix(&self.as_bytes()[span_of!(Self, msg_type..mac)])?;
self.mac.copy_from_slice(mac.into_value()[..16].as_ref());
self.seal_cookie(peer, srv)?;
@@ -1538,7 +1536,7 @@ where
/// Check the message authentication code
pub fn check_seal(&self, srv: &CryptoServer) -> Result<bool> {
let expected = hash_domains::mac()?
.mix(srv.spkm.deref())?
.mix(srv.spkm.secret())?
.mix(&self.as_bytes()[span_of!(Self, msg_type..mac)])?;
Ok(constant_time::memcmp(
&self.mac,
@@ -1643,7 +1641,7 @@ impl HandshakeState {
// calculate ad contents
let ad = hash_domains::biscuit_ad()?
.mix(srv.spkm.deref())?
.mix(srv.spkm.secret())?
.mix(self.sidi.as_slice())?
.mix(self.sidr.as_slice())?
.into_value();
@@ -1678,7 +1676,7 @@ impl HandshakeState {
// Calculate additional data fields
let ad = hash_domains::biscuit_ad()?
.mix(srv.spkm.deref())?
.mix(srv.spkm.secret())?
.mix(sidi.as_slice())?
.mix(sidr.as_slice())?
.into_value();
@@ -1765,7 +1763,7 @@ impl CryptoServer {
let mut hs = InitiatorHandshake::zero_with_timestamp(self);
// IHI1
hs.core.init(peer.get(self).spkt.deref())?;
hs.core.init(peer.get(self).spkt.secret())?;
// IHI2
hs.core.sidi.randomize();
@@ -1782,7 +1780,7 @@ impl CryptoServer {
hs.core
.encaps_and_mix::<StaticKem, { StaticKem::SHK_LEN }>(
ih.sctr.as_mut_slice(),
peer.get(self).spkt.deref(),
peer.get(self).spkt.secret(),
)?;
// IHI6
@@ -1791,7 +1789,7 @@ impl CryptoServer {
// IHI7
hs.core
.mix(self.spkm.deref())?
.mix(self.spkm.secret())?
.mix(peer.get(self).psk.secret())?;
// IHI8
@@ -1809,7 +1807,7 @@ impl CryptoServer {
core.sidi = SessionId::from_slice(&ih.sidi);
// IHR1
core.init(self.spkm.deref())?;
core.init(self.spkm.secret())?;
// IHR4
core.mix(&ih.sidi)?.mix(&ih.epki)?;
@@ -1817,7 +1815,7 @@ impl CryptoServer {
// IHR5
core.decaps_and_mix::<StaticKem, { StaticKem::SHK_LEN }>(
self.sskm.secret(),
self.spkm.deref(),
self.spkm.secret(),
&ih.sctr,
)?;
@@ -1830,7 +1828,7 @@ impl CryptoServer {
};
// IHR7
core.mix(peer.get(self).spkt.deref())?
core.mix(peer.get(self).spkt.secret())?
.mix(peer.get(self).psk.secret())?;
// IHR8
@@ -1850,7 +1848,7 @@ impl CryptoServer {
// RHR5
core.encaps_and_mix::<StaticKem, { StaticKem::SHK_LEN }>(
&mut rh.scti,
peer.get(self).spkt.deref(),
peer.get(self).spkt.secret(),
)?;
// RHR6
@@ -1911,14 +1909,14 @@ impl CryptoServer {
// RHI4
core.decaps_and_mix::<EphemeralKem, { EphemeralKem::SHK_LEN }>(
hs!().eski.secret(),
hs!().epki.deref(),
&*hs!().epki,
&rh.ecti,
)?;
// RHI5
core.decaps_and_mix::<StaticKem, { StaticKem::SHK_LEN }>(
self.sskm.secret(),
self.spkm.deref(),
self.spkm.secret(),
&rh.scti,
)?;
@@ -2115,7 +2113,7 @@ impl CryptoServer {
),
}?;
let spkt = peer.get(self).spkt.deref();
let spkt = peer.get(self).spkt.secret();
let cookie_key = hash_domains::cookie_key()?.mix(spkt)?.into_value();
let cookie_value = peer.cv().update_mut(self).unwrap();
@@ -2148,7 +2146,7 @@ fn truncating_cast_into_nomut<T: FromBytes>(buf: &[u8]) -> Result<Ref<&[u8], T>,
#[cfg(test)]
mod test {
use std::{net::SocketAddrV4, ops::DerefMut, thread::sleep, time::Duration};
use std::{net::SocketAddrV4, thread::sleep, time::Duration};
use super::*;
use serial_test::serial;
@@ -2257,7 +2255,7 @@ mod test {
fn keygen() -> Result<(SSk, SPk)> {
// TODO: Copied from the benchmark; deduplicate
let (mut sk, mut pk) = (SSk::zero(), SPk::zero());
StaticKem::keygen(sk.secret_mut(), pk.deref_mut())?;
StaticKem::keygen(sk.secret_mut(), pk.secret_mut())?;
Ok((sk, pk))
}

View File

@@ -2,11 +2,14 @@ use std::{
fs,
net::UdpSocket,
path::PathBuf,
sync::{Arc, Mutex},
time::Duration,
};
use clap::Parser;
use rosenpass::{app_server::AppServerTestBuilder, cli::CliArgs};
use rosenpass_secret_memory::{Public, Secret};
use rosenpass_wireguard_broker::{WireguardBrokerMio, WG_KEY_LEN, WG_PEER_LEN};
use serial_test::serial;
use std::io::Write;
@@ -271,3 +274,58 @@ fn check_exchange_under_dos() {
// cleanup
fs::remove_dir_all(&tmpdir).unwrap();
}
#[allow(dead_code)]
#[derive(Debug, Default)]
struct MockBrokerInner {
psk: Option<Secret<WG_KEY_LEN>>,
peer_id: Option<Public<WG_PEER_LEN>>,
interface: Option<String>,
}
#[derive(Debug, Default)]
struct MockBroker {
inner: Arc<Mutex<MockBrokerInner>>,
}
impl WireguardBrokerMio for MockBroker {
type MioError = anyhow::Error;
fn register(
&mut self,
_registry: &mio::Registry,
_token: mio::Token,
) -> Result<(), Self::MioError> {
Ok(())
}
fn process_poll(&mut self) -> Result<(), Self::MioError> {
Ok(())
}
fn unregister(&mut self, _registry: &mio::Registry) -> Result<(), Self::MioError> {
Ok(())
}
}
impl rosenpass_wireguard_broker::WireGuardBroker for MockBroker {
type Error = anyhow::Error;
fn set_psk(
&mut self,
config: rosenpass_wireguard_broker::SerializedBrokerConfig<'_>,
) -> Result<(), Self::Error> {
loop {
let mut lock = self.inner.try_lock();
if let Ok(ref mut mutex) = lock {
**mutex = MockBrokerInner {
psk: Some(config.psk.clone()),
peer_id: Some(config.peer_id.clone()),
interface: Some(std::str::from_utf8(config.interface).unwrap().to_string()),
};
break Ok(());
}
}
}
}

View File

@@ -40,4 +40,3 @@ stacker = {workspace = true}
[features]
enable_memfd_alloc = []
experiment_libcrux = ["rosenpass-ciphers/experiment_libcrux"]

View File

@@ -2,9 +2,7 @@ use std::{net::SocketAddr, path::PathBuf};
use anyhow::Result;
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
use crate::key::WG_B64_LEN;
#[derive(Default)]
pub struct ExchangePeer {
pub public_keys_dir: PathBuf,

View File

@@ -1,12 +1,11 @@
use std::{
fs::{self, DirBuilder},
ops::DerefMut,
os::unix::fs::{DirBuilderExt, PermissionsExt},
path::Path,
};
use anyhow::{anyhow, Result};
use rosenpass_util::file::{LoadValueB64, StoreValue, StoreValueB64};
use rosenpass_util::file::{LoadValueB64, StoreValueB64};
use zeroize::Zeroize;
use rosenpass::protocol::{SPk, SSk};
@@ -57,8 +56,8 @@ pub fn genkey(private_keys_dir: &Path) -> Result<()> {
if !pqsk_path.exists() && !pqpk_path.exists() {
let mut pqsk = SSk::random();
let mut pqpk = SPk::random();
StaticKem::keygen(pqsk.secret_mut(), pqpk.deref_mut())?;
pqpk.store(pqpk_path)?;
StaticKem::keygen(pqsk.secret_mut(), pqpk.secret_mut())?;
pqpk.store_secret(pqpk_path)?;
pqsk.store_secret(pqsk_path)?;
} else {
eprintln!(

View File

@@ -6,7 +6,6 @@ pub mod alloc;
mod public;
pub use crate::public::Public;
pub use crate::public::PublicBox;
mod secret;
pub use crate::secret::Secret;

View File

@@ -172,153 +172,12 @@ impl<const N: usize> StoreValueB64Writer for Public<N> {
}
}
#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[repr(transparent)]
pub struct PublicBox<const N: usize> {
pub inner: Box<Public<N>>,
}
impl<const N: usize> PublicBox<N> {
/// Create a new [PublicBox] from a byte slice
pub fn from_slice(value: &[u8]) -> Self {
Self {
inner: Box::new(Public::from_slice(value)),
}
}
/// Create a new [PublicBox] from a byte array
pub fn new(value: [u8; N]) -> Self {
Self {
inner: Box::new(Public::new(value)),
}
}
/// Create a zero initialized [PublicBox]
pub fn zero() -> Self {
Self {
inner: Box::new(Public::zero()),
}
}
/// Create a random initialized [PublicBox]
pub fn random() -> Self {
Self {
inner: Box::new(Public::random()),
}
}
/// Randomize all bytes in an existing [PublicBox]
pub fn randomize(&mut self) {
self.inner.randomize()
}
}
impl<const N: usize> Randomize for PublicBox<N> {
fn try_fill<R: Rng + ?Sized>(&mut self, rng: &mut R) -> Result<(), rand::Error> {
self.inner.try_fill(rng)
}
}
impl<const N: usize> fmt::Debug for PublicBox<N> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
debug_crypto_array(&**self, fmt)
}
}
impl<const N: usize> Deref for PublicBox<N> {
type Target = [u8; N];
fn deref(&self) -> &[u8; N] {
self.inner.deref()
}
}
impl<const N: usize> DerefMut for PublicBox<N> {
fn deref_mut(&mut self) -> &mut [u8; N] {
self.inner.deref_mut()
}
}
impl<const N: usize> Borrow<[u8]> for PublicBox<N> {
fn borrow(&self) -> &[u8] {
self.deref()
}
}
impl<const N: usize> BorrowMut<[u8]> for PublicBox<N> {
fn borrow_mut(&mut self) -> &mut [u8] {
self.deref_mut()
}
}
impl<const N: usize> LoadValue for PublicBox<N> {
type Error = anyhow::Error;
// This is implemented separately from Public to avoid allocating too much stack memory
fn load<P: AsRef<Path>>(path: P) -> anyhow::Result<Self> {
let mut p = Self::random();
fopen_r(path)?.read_exact_to_end(p.deref_mut())?;
Ok(p)
}
}
impl<const N: usize> StoreValue for PublicBox<N> {
type Error = anyhow::Error;
fn store<P: AsRef<Path>>(&self, path: P) -> anyhow::Result<()> {
self.inner.store(path)
}
}
impl<const N: usize> LoadValueB64 for PublicBox<N> {
type Error = anyhow::Error;
// This is implemented separately from Public to avoid allocating too much stack memory
fn load_b64<const F: usize, P: AsRef<Path>>(path: P) -> Result<Self, Self::Error>
where
Self: Sized,
{
// A vector is used here to ensure heap allocation without copy from stack
let mut f = vec![0u8; F];
let mut v = PublicBox::zero();
let p = path.as_ref();
let len = fopen_r(p)?
.read_slice_to_end(&mut f)
.with_context(|| format!("Could not load file {p:?}"))?;
b64_decode(&f[0..len], v.deref_mut())
.with_context(|| format!("Could not decode base64 file {p:?}"))?;
Ok(v)
}
}
impl<const N: usize> StoreValueB64 for PublicBox<N> {
type Error = anyhow::Error;
fn store_b64<const F: usize, P: AsRef<Path>>(&self, path: P) -> anyhow::Result<()> {
self.inner.store_b64::<F, P>(path)
}
}
impl<const N: usize> StoreValueB64Writer for PublicBox<N> {
type Error = anyhow::Error;
fn store_b64_writer<const F: usize, W: std::io::Write>(
&self,
writer: W,
) -> Result<(), Self::Error> {
self.inner.store_b64_writer::<F, W>(writer)
}
}
#[cfg(test)]
mod tests {
#[cfg(test)]
mod tests {
use crate::{Public, PublicBox};
use crate::Public;
use rosenpass_util::{
b64::b64_encode,
file::{
@@ -326,35 +185,32 @@ mod tests {
Visibility,
},
};
use std::{fs, ops::Deref, os::unix::fs::PermissionsExt};
use std::{fs, os::unix::fs::PermissionsExt};
use tempfile::tempdir;
/// Number of bytes in payload for load and store tests
/// test loading a public from an example file, and then storing it again in a different file
#[test]
fn test_public_load_store() {
const N: usize = 100;
/// Convenience function for running a load/store test
fn run_load_store_test<
T: LoadValue<Error = anyhow::Error>
+ StoreValue<Error = anyhow::Error>
+ Deref<Target = [u8; N]>,
>() {
// Generate original random bytes
let original_bytes: [u8; N] = [rand::random(); N];
// Create a temporary directory
let temp_dir = tempdir().unwrap();
// Store the original bytes to an example file in the temporary directory
// Store the original public to an example file in the temporary directory
let example_file = temp_dir.path().join("example_file");
std::fs::write(example_file.clone(), &original_bytes).unwrap();
// Load the value from the example file into our generic type
let loaded_public = T::load(&example_file).unwrap();
// Load the public from the example file
// Check that the loaded value matches the original bytes
assert_eq!(loaded_public.deref(), &original_bytes);
let loaded_public = Public::load(&example_file).unwrap();
// Store the loaded value to a different file in the temporary directory
// Check that the loaded public matches the original bytes
assert_eq!(&loaded_public.value, &original_bytes);
// Store the loaded public to a different file in the temporary directory
let new_file = temp_dir.path().join("new_file");
loaded_public.store(&new_file).unwrap();
@@ -368,13 +224,10 @@ mod tests {
assert_eq!(new_file_contents, original_file_contents);
}
/// Convenience function for running a base64 load/store test
fn run_base64_load_store_test<
T: LoadValueB64<Error = anyhow::Error>
+ StoreValueB64<Error = anyhow::Error>
+ StoreValueB64Writer<Error = anyhow::Error>
+ Deref<Target = [u8; N]>,
>() {
/// test loading a base64 encoded public from an example file, and then storing it again in a different file
#[test]
fn test_public_load_store_base64() {
const N: usize = 100;
// Generate original random bytes
let original_bytes: [u8; N] = [rand::random(); N];
// Create a temporary directory
@@ -385,9 +238,9 @@ mod tests {
std::fs::write(&example_file, encoded_public).unwrap();
// Load the public from the example file
let loaded_public = T::load_b64::<{ N * 2 }, _>(&example_file).unwrap();
let loaded_public = Public::load_b64::<{ N * 2 }, _>(&example_file).unwrap();
// Check that the loaded public matches the original bytes
assert_eq!(loaded_public.deref(), &original_bytes);
assert_eq!(&loaded_public.value, &original_bytes);
// Store the loaded public to a different file in the temporary directory
let new_file = temp_dir.path().join("new_file");
@@ -422,31 +275,5 @@ mod tests {
let metadata = fs::metadata(&new_file).unwrap();
assert_eq!(metadata.permissions().mode() & 0o000777, 0o644);
}
/// Test loading a [Public] from an example file, and then storing it again in a new file
#[test]
fn test_public_load_store() {
run_load_store_test::<Public<N>>();
}
/// Test loading a [PublicBox] from an example file, and then storing it again in a new file
#[test]
fn test_public_box_load_store() {
run_load_store_test::<PublicBox<N>>();
}
/// Test loading a base64-encoded [Public] from an example file, and then storing it again
/// in a different file
#[test]
fn test_public_load_store_base64() {
run_base64_load_store_test::<Public<N>>();
}
/// Test loading a base64-encoded [PublicBox] from an example file, and then storing it
/// again in a different file
#[test]
fn test_public_box_load_store_base64() {
run_base64_load_store_test::<PublicBox<N>>();
}
}
}

View File

@@ -19,7 +19,7 @@ wireguard-uapi = { workspace = true }
# Socket handler only
rosenpass-to = { workspace = true }
tokio = { version = "1.38.1", features = ["sync", "full", "mio"] }
tokio = { version = "1.38.0", features = ["sync", "full", "mio"] }
anyhow = { workspace = true }
clap = { workspace = true }
env_logger = { workspace = true }