Compare commits

..

2 Commits

Author SHA1 Message Date
Prabhpreet Dua
c0c57e5ffc Merge branch 'main' into feat/improved-memfd-allocation 2024-06-12 17:36:28 +05:30
Prabhpreet Dua
32d30a6f63 feat: Improved memfd-secret allocation 2024-06-12 17:32:11 +05:30
28 changed files with 126 additions and 606 deletions

View File

@@ -110,12 +110,7 @@ jobs:
- run: RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --document-private-items - run: RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --document-private-items
cargo-test: cargo-test:
runs-on: ${{ matrix.os }} runs-on: ubuntu-latest
strategy:
matrix:
os: [ubuntu-latest, macos-13]
# - ubuntu is x86-64
# - macos-13 is also x86-64 architecture
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/cache@v3 - uses: actions/cache@v3

View File

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

87
Cargo.lock generated
View File

@@ -387,9 +387,9 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.8" version = "4.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@@ -397,9 +397,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.8" version = "4.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@@ -409,9 +409,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "4.5.8" version = "4.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
@@ -984,10 +984,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"js-sys",
"libc", "libc",
"wasi 0.11.0+wasi-snapshot-preview1", "wasi 0.11.0+wasi-snapshot-preview1",
"wasm-bindgen",
] ]
[[package]] [[package]]
@@ -1068,12 +1066,6 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]] [[package]]
name = "home" name = "home"
version = "0.5.9" version = "0.5.9"
@@ -1230,38 +1222,6 @@ version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" 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]] [[package]]
name = "libfuzzer-sys" name = "libfuzzer-sys"
version = "0.4.7" version = "0.4.7"
@@ -1273,16 +1233,6 @@ dependencies = [
"once_cell", "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]] [[package]]
name = "libloading" name = "libloading"
version = "0.8.3" version = "0.8.3"
@@ -1311,9 +1261,9 @@ dependencies = [
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.22" version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]] [[package]]
name = "memchr" name = "memchr"
@@ -1935,7 +1885,7 @@ name = "rosenpass"
version = "0.2.1" version = "0.2.1"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap 4.5.8", "clap 4.5.7",
"criterion", "criterion",
"derive_builder 0.20.0", "derive_builder 0.20.0",
"env_logger", "env_logger",
@@ -1974,7 +1924,6 @@ dependencies = [
"anyhow", "anyhow",
"blake2", "blake2",
"chacha20poly1305", "chacha20poly1305",
"libcrux",
"rosenpass-constant-time", "rosenpass-constant-time",
"rosenpass-oqs", "rosenpass-oqs",
"rosenpass-secret-memory", "rosenpass-secret-memory",
@@ -2059,7 +2008,7 @@ name = "rosenpass-wireguard-broker"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap 4.5.8", "clap 4.5.7",
"derive_builder 0.20.0", "derive_builder 0.20.0",
"env_logger", "env_logger",
"log", "log",
@@ -2376,12 +2325,6 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "take-until"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4e17d8598067a8c134af59cd33c1c263470e089924a11ab61cf61690919fe3b"
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.10.1" version = "3.10.1"
@@ -2914,10 +2857,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ba4e9811befc20af3b6efb15924a7238ee5e8e8706a196576462a00b9f1af1" checksum = "89ba4e9811befc20af3b6efb15924a7238ee5e8e8706a196576462a00b9f1af1"
dependencies = [ dependencies = [
"derive_builder 0.10.2", "derive_builder 0.10.2",
"hex",
"libc", "libc",
"neli", "neli",
"take-until",
"thiserror", "thiserror",
] ]
@@ -2945,9 +2886,9 @@ dependencies = [
[[package]] [[package]]
name = "zerocopy" name = "zerocopy"
version = "0.7.35" version = "0.7.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"zerocopy-derive", "zerocopy-derive",
@@ -2955,9 +2896,9 @@ dependencies = [
[[package]] [[package]]
name = "zerocopy-derive" name = "zerocopy-derive"
version = "0.7.35" version = "0.7.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View File

@@ -44,8 +44,8 @@ allocator-api2 = "0.2.14"
memsec = { git="https://github.com/rosenpass/memsec.git" ,rev="aceb9baee8aec6844125bd6612f92e9a281373df", features = [ "alloc_ext", ] } memsec = { git="https://github.com/rosenpass/memsec.git" ,rev="aceb9baee8aec6844125bd6612f92e9a281373df", features = [ "alloc_ext", ] }
rand = "0.8.5" rand = "0.8.5"
typenum = "1.17.0" typenum = "1.17.0"
log = { version = "0.4.22" } log = { version = "0.4.21" }
clap = { version = "4.5.8", features = ["derive"] } clap = { version = "4.5.7", features = ["derive"] }
serde = { version = "1.0.203", features = ["derive"] } serde = { version = "1.0.203", features = ["derive"] }
arbitrary = { version = "1.3.2", features = ["derive"] } arbitrary = { version = "1.3.2", features = ["derive"] }
anyhow = { version = "1.0.86", features = ["backtrace", "std"] } anyhow = { version = "1.0.86", features = ["backtrace", "std"] }
@@ -59,12 +59,11 @@ chacha20poly1305 = { version = "0.10.1", default-features = false, features = [
"std", "std",
"heapless", "heapless",
] } ] }
zerocopy = { version = "0.7.35", features = ["derive"] } zerocopy = { version = "0.7.34", features = ["derive"] }
home = "0.5.9" home = "0.5.9"
derive_builder = "0.20.0" derive_builder = "0.20.0"
tokio = { version = "1.38", features = ["macros", "rt-multi-thread"] } tokio = { version = "1.38", features = ["macros", "rt-multi-thread"] }
postcard= {version = "1.0.8", features = ["alloc"]} postcard= {version = "1.0.8", features = ["alloc"]}
libcrux = { version = "0.0.2-pre.2" }
#Dev dependencies #Dev dependencies
serial_test = "3.1.1" serial_test = "3.1.1"
@@ -78,6 +77,6 @@ procspawn = {version = "1.0.0", features= ["test-support"]}
#Broker dependencies (might need cleanup or changes) #Broker dependencies (might need cleanup or changes)
wireguard-uapi = { version = "3.0.0", features = ["xplatform"] } wireguard-uapi = "3.0.0"
command-fds = "0.2.3" command-fds = "0.2.3"
rustix = { version = "0.38.27", features = ["net"] } rustix = { version = "0.38.27", features = ["net"] }

View File

@@ -9,9 +9,6 @@ homepage = "https://rosenpass.eu/"
repository = "https://github.com/rosenpass/rosenpass" repository = "https://github.com/rosenpass/rosenpass"
readme = "readme.md" readme = "readme.md"
[features]
experiment_libcrux = ["dep:libcrux"]
[dependencies] [dependencies]
anyhow = { workspace = true } anyhow = { workspace = true }
rosenpass-to = { workspace = true } rosenpass-to = { workspace = true }
@@ -23,4 +20,3 @@ static_assertions = { workspace = true }
zeroize = { workspace = true } zeroize = { workspace = true }
chacha20poly1305 = { workspace = true } chacha20poly1305 = { workspace = true }
blake2 = { 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 /// Authenticated encryption with associated data
pub mod aead { 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}; 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; pub mod blake2b;
#[cfg(not(feature = "libcrux"))]
pub mod chacha20poly1305_ietf; pub mod chacha20poly1305_ietf;
#[cfg(feature = "libcrux")]
pub mod chacha20poly1305_ietf_libcrux;
pub mod incorrect_hmac_blake2b; pub mod incorrect_hmac_blake2b;
pub mod xchacha20poly1305_ietf; 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. Marei Peischl, Stephan Ajuvo, and Lisa Schmidt.
.Pp .Pp
This manual page was written by This manual page was written by
.An Clara Engler .An Emil Engler
.Sh BUGS .Sh BUGS
The bugs are tracked at The bugs are tracked at
.Lk https://github.com/rosenpass/rosenpass/issues . .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. Marei Peischl, Stephan Ajuvo, and Lisa Schmidt.
.Pp .Pp
This manual page was written by This manual page was written by
.An Clara Engler .An Emil Engler
.Sh BUGS .Sh BUGS
The bugs are tracked at The bugs are tracked at
.Lk https://github.com/rosenpass/rosenpass/issues . .Lk https://github.com/rosenpass/rosenpass/issues .

View File

@@ -4,9 +4,6 @@ version = "0.0.1"
publish = false publish = false
edition = "2021" edition = "2021"
[features]
experiment_libcrux = ["rosenpass-ciphers/experiment_libcrux"]
[package.metadata] [package.metadata]
cargo-fuzz = true cargo-fuzz = true
@@ -84,4 +81,4 @@ doc = false
name = "fuzz_vec_secret_alloc_memfdsec_mallocfb" name = "fuzz_vec_secret_alloc_memfdsec_mallocfb"
path = "fuzz_targets/vec_secret_alloc_memfdsec_mallocfb.rs" path = "fuzz_targets/vec_secret_alloc_memfdsec_mallocfb.rs"
test = false test = false
doc = false doc = false

View File

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

View File

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

View File

@@ -1,40 +0,0 @@
# Additional files
This folder contains additional files that are used in the project.
## `generate_configs.py`
The script is used to generate configuration files for a benchmark setup
consisting of a device under testing (DUT) and automatic test equipment (ATE),
basically a strong machine capable of running multiple Rosenpass instances at
once.
At the top of the script multiple variables can be set to configure the DUT IP
address and more. Once configured you may run `python3 generate_configs.py` to
create the configuration files.
A new folder called `output/` is created containing the subfolder `dut/` and
`ate/`. The former has to be copied on the DUT, ideally reproducible hardware
like a Raspberry Pi, while the latter is copied to the ATE, i.e. a laptop.
### Running a benchmark
On the ATE a run script is required since multiple instances of `rosenpass` are
started with different configurations in parallel. The scripts are named after
the number of instances they start, e.g. `run-50.sh` starts 50 instances.
```shell
# on the ATE aka laptop
cd output/ate
./run-10.sh
```
On the DUT you start a single Rosenpass instance with the configuration matching
the ATE number of peers.
```shell
# on the DUT aka Raspberry Pi
rosenpass exchange-config configs/dut-10.toml
```
Use whatever measurement tool you like to monitor the DUT and ATE.

View File

@@ -1,105 +0,0 @@
from pathlib import Path
from subprocess import run
config = dict(
peer_counts=[1, 5, 10, 50, 100, 500],
peer_count_max=100,
ate_ip="192.168.2.1",
dut_ip="192.168.2.4",
dut_port=9999,
path_to_rosenpass_bin="/Users/user/src/rosenppass/rosenpass/target/debug/rosenpass",
)
print(config)
output_dir = Path("output")
output_dir.mkdir(exist_ok=True)
template_dut = """
public_key = "keys/dut-public-key"
secret_key = "keys/dut-secret-key"
listen = ["{dut_ip}:{dut_port}"]
verbosity = "Quiet"
"""
template_dut_peer = """
[[peers]] # ATE-{i}
public_key = "keys/ate-{i}-public-key"
endpoint = "{ate_ip}:{ate_port}"
key_out = "out/key_out_{i}"
"""
template_ate = """
public_key = "keys/ate-{i}-public-key"
secret_key = "keys/ate-{i}-secret-key"
listen = ["{ate_ip}:{ate_port}"]
verbosity = "Quiet"
[[peers]] # DUT
public_key = "keys/dut-public-key"
endpoint = "{dut_ip}:{dut_port}"
key_out = "out/key_out_{i}"
"""
(output_dir / "dut" / "keys").mkdir(exist_ok=True, parents=True)
(output_dir / "dut" / "out").mkdir(exist_ok=True, parents=True)
(output_dir / "dut" / "configs").mkdir(exist_ok=True, parents=True)
(output_dir / "ate" / "keys").mkdir(exist_ok=True, parents=True)
(output_dir / "ate" / "out").mkdir(exist_ok=True, parents=True)
(output_dir / "ate" / "configs").mkdir(exist_ok=True, parents=True)
for peer_count in config["peer_counts"]:
dut_config = template_dut.format(**config)
for i in range(peer_count):
dut_config += template_dut_peer.format(**config, i=i, ate_port=50000 + i)
(output_dir / "dut" / "configs" / f"dut-{peer_count}.toml").write_text(dut_config)
if not (output_dir / "dut" / "keys" / "dut-public-key").exists():
print("Generate DUT keys")
run(
[
config["path_to_rosenpass_bin"],
"gen-keys",
f"configs/dut-{peer_count}.toml",
],
cwd=output_dir / "dut",
)
else:
print("DUT keys already exist")
# copy the DUT public key to the ATE
(output_dir / "ate" / "keys" / "dut-public-key").write_bytes(
(output_dir / "dut" / "keys" / "dut-public-key").read_bytes()
)
ate_script = "(trap 'kill 0' SIGINT; \\\n"
for i in range(config["peer_count_max"]):
(output_dir / "ate" / "configs" / f"ate-{i}.toml").write_text(
template_ate.format(**config, i=i, ate_port=50000 + i)
)
if not (output_dir / "ate" / "keys" / f"ate-{i}-public-key").exists():
# generate ATE keys
run(
[config["path_to_rosenpass_bin"], "gen-keys", f"configs/ate-{i}.toml"],
cwd=output_dir / "ate",
)
else:
print(f"ATE-{i} keys already exist")
# copy the ATE public keys to the DUT
(output_dir / "dut" / "keys" / f"ate-{i}-public-key").write_bytes(
(output_dir / "ate" / "keys" / f"ate-{i}-public-key").read_bytes()
)
ate_script += (
f"{config['path_to_rosenpass_bin']} exchange-config configs/ate-{i}.toml & \\\n"
)
if (i + 1) in config["peer_counts"]:
write_script = ate_script
write_script += "wait)"
(output_dir / "ate" / f"run-{i+1}.sh").write_text(write_script)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -23,4 +23,4 @@ log = { workspace = true }
allocator-api2-tests = { workspace = true } allocator-api2-tests = { workspace = true }
tempfile = {workspace = true} tempfile = {workspace = true}
base64ct = {workspace = true} base64ct = {workspace = true}
procspawn = {workspace = true} procspawn = {workspace = true}

View File

@@ -6,7 +6,6 @@ pub mod alloc;
mod public; mod public;
pub use crate::public::Public; pub use crate::public::Public;
pub use crate::public::PublicBox;
mod secret; mod secret;
pub use crate::secret::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)] #[cfg(test)]
mod tests { mod tests {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::{Public, PublicBox}; use crate::Public;
use rosenpass_util::{ use rosenpass_util::{
b64::b64_encode, b64::b64_encode,
file::{ file::{
@@ -326,35 +185,32 @@ mod tests {
Visibility, Visibility,
}, },
}; };
use std::{fs, ops::Deref, os::unix::fs::PermissionsExt}; use std::{fs, os::unix::fs::PermissionsExt};
use tempfile::tempdir; 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
const N: usize = 100; #[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 // Generate original random bytes
let original_bytes: [u8; N] = [rand::random(); N]; let original_bytes: [u8; N] = [rand::random(); N];
// Create a temporary directory // Create a temporary directory
let temp_dir = tempdir().unwrap(); 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"); let example_file = temp_dir.path().join("example_file");
std::fs::write(example_file.clone(), &original_bytes).unwrap(); std::fs::write(example_file.clone(), &original_bytes).unwrap();
// Load the value from the example file into our generic type // Load the public from the example file
let loaded_public = T::load(&example_file).unwrap();
// Check that the loaded value matches the original bytes let loaded_public = Public::load(&example_file).unwrap();
assert_eq!(loaded_public.deref(), &original_bytes);
// 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"); let new_file = temp_dir.path().join("new_file");
loaded_public.store(&new_file).unwrap(); loaded_public.store(&new_file).unwrap();
@@ -368,13 +224,10 @@ mod tests {
assert_eq!(new_file_contents, original_file_contents); assert_eq!(new_file_contents, original_file_contents);
} }
/// Convenience function for running a base64 load/store test /// test loading a base64 encoded public from an example file, and then storing it again in a different file
fn run_base64_load_store_test< #[test]
T: LoadValueB64<Error = anyhow::Error> fn test_public_load_store_base64() {
+ StoreValueB64<Error = anyhow::Error> const N: usize = 100;
+ StoreValueB64Writer<Error = anyhow::Error>
+ Deref<Target = [u8; N]>,
>() {
// Generate original random bytes // Generate original random bytes
let original_bytes: [u8; N] = [rand::random(); N]; let original_bytes: [u8; N] = [rand::random(); N];
// Create a temporary directory // Create a temporary directory
@@ -385,9 +238,9 @@ mod tests {
std::fs::write(&example_file, encoded_public).unwrap(); std::fs::write(&example_file, encoded_public).unwrap();
// Load the public from the example file // 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 // 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 // Store the loaded public to a different file in the temporary directory
let new_file = temp_dir.path().join("new_file"); let new_file = temp_dir.path().join("new_file");
@@ -400,7 +253,7 @@ mod tests {
// Check that the contents of the new file match the original file // Check that the contents of the new file match the original file
assert_eq!(new_file_contents, original_file_contents); assert_eq!(new_file_contents, original_file_contents);
// Check new file permissions are public //Check new file permissions are public
let metadata = fs::metadata(&new_file).unwrap(); let metadata = fs::metadata(&new_file).unwrap();
assert_eq!(metadata.permissions().mode() & 0o000777, 0o644); assert_eq!(metadata.permissions().mode() & 0o000777, 0o644);
@@ -418,35 +271,9 @@ mod tests {
// Check that the contents of the new file match the original file // Check that the contents of the new file match the original file
assert_eq!(new_file_contents, original_file_contents); assert_eq!(new_file_contents, original_file_contents);
// Check new file permissions are public //Check new file permissions are public
let metadata = fs::metadata(&new_file).unwrap(); let metadata = fs::metadata(&new_file).unwrap();
assert_eq!(metadata.permissions().mode() & 0o000777, 0o644); 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

@@ -44,7 +44,6 @@ path = "src/bin/priviledged.rs"
test = false test = false
doc = false doc = false
required-features=["enable_broker_api"] required-features=["enable_broker_api"]
cfg = { target_os = "linux" }
[[bin]] [[bin]]
name = "rosenpass-wireguard-broker-socket-handler" name = "rosenpass-wireguard-broker-socket-handler"
@@ -52,4 +51,3 @@ test = false
path = "src/bin/socket_handler.rs" path = "src/bin/socket_handler.rs"
doc = false doc = false
required-features=["enable_broker_api"] required-features=["enable_broker_api"]
cfg = { target_os = "linux" }

View File

@@ -1,67 +1,56 @@
fn main() { use std::io::{stdin, stdout, Read, Write};
#[cfg(target_os = "linux")] use std::result::Result;
linux::main().unwrap();
#[cfg(not(target_os = "linux"))] use rosenpass_wireguard_broker::api::msgs;
panic!("This binary is only supported on Linux"); use rosenpass_wireguard_broker::api::server::BrokerServer;
use rosenpass_wireguard_broker::brokers::netlink as wg;
#[derive(thiserror::Error, Debug)]
pub enum BrokerAppError {
#[error(transparent)]
IoError(#[from] std::io::Error),
#[error(transparent)]
WgConnectError(#[from] wg::ConnectError),
#[error(transparent)]
WgSetPskError(#[from] wg::SetPskError),
#[error("Oversized message {}; something about the request is fatally wrong", .0)]
OversizedMessage(u64),
} }
#[cfg(target_os = "linux")] fn main() -> Result<(), BrokerAppError> {
pub mod linux { let mut broker = BrokerServer::new(wg::NetlinkWireGuardBroker::new()?);
use std::io::{stdin, stdout, Read, Write};
use std::result::Result;
use rosenpass_wireguard_broker::api::msgs; let mut stdin = stdin().lock();
use rosenpass_wireguard_broker::api::server::BrokerServer; let mut stdout = stdout().lock();
use rosenpass_wireguard_broker::brokers::netlink as wg; loop {
// Read the message length
let mut len = [0u8; 8];
stdin.read_exact(&mut len)?;
#[derive(thiserror::Error, Debug)] // Parse the message length
pub enum BrokerAppError { let len = u64::from_le_bytes(len);
#[error(transparent)] if (len as usize) > msgs::REQUEST_MSG_BUFFER_SIZE {
IoError(#[from] std::io::Error), return Err(BrokerAppError::OversizedMessage(len));
#[error(transparent)]
WgConnectError(#[from] wg::ConnectError),
#[error(transparent)]
WgSetPskError(#[from] wg::SetPskError),
#[error("Oversized message {}; something about the request is fatally wrong", .0)]
OversizedMessage(u64),
}
pub fn main() -> Result<(), BrokerAppError> {
let mut broker = BrokerServer::new(wg::NetlinkWireGuardBroker::new()?);
let mut stdin = stdin().lock();
let mut stdout = stdout().lock();
loop {
// Read the message length
let mut len = [0u8; 8];
stdin.read_exact(&mut len)?;
// Parse the message length
let len = u64::from_le_bytes(len);
if (len as usize) > msgs::REQUEST_MSG_BUFFER_SIZE {
return Err(BrokerAppError::OversizedMessage(len));
}
// Read the message itself
let mut req_buf = [0u8; msgs::REQUEST_MSG_BUFFER_SIZE];
let req_buf = &mut req_buf[..(len as usize)];
stdin.read_exact(req_buf)?;
// Process the message
let mut res_buf = [0u8; msgs::RESPONSE_MSG_BUFFER_SIZE];
let res = match broker.handle_message(req_buf, &mut res_buf) {
Ok(len) => &res_buf[..len],
Err(e) => {
eprintln!("Error processing message for wireguard PSK broker: {e:?}");
continue;
}
};
// Write the response
stdout.write_all(&(res.len() as u64).to_le_bytes())?;
stdout.write_all(&res)?;
stdout.flush()?;
} }
// Read the message itself
let mut req_buf = [0u8; msgs::REQUEST_MSG_BUFFER_SIZE];
let req_buf = &mut req_buf[..(len as usize)];
stdin.read_exact(req_buf)?;
// Process the message
let mut res_buf = [0u8; msgs::RESPONSE_MSG_BUFFER_SIZE];
let res = match broker.handle_message(req_buf, &mut res_buf) {
Ok(len) => &res_buf[..len],
Err(e) => {
eprintln!("Error processing message for wireguard PSK broker: {e:?}");
continue;
}
};
// Write the response
stdout.write_all(&(res.len() as u64).to_le_bytes())?;
stdout.write_all(&res)?;
stdout.flush()?;
} }
} }

View File

@@ -1,6 +1,6 @@
#[cfg(feature = "enable_broker_api")] #[cfg(feature = "enable_broker_api")]
pub mod mio_client; pub mod mio_client;
#[cfg(all(feature = "enable_broker_api", target_os = "linux"))] #[cfg(feature = "enable_broker_api")]
pub mod netlink; pub mod netlink;
pub mod native_unix; pub mod native_unix;

View File

@@ -1,5 +1,3 @@
#![cfg(target_os = "linux")]
use std::fmt::Debug; use std::fmt::Debug;
use wireguard_uapi::linux as wg; use wireguard_uapi::linux as wg;