Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
/target
**/*.rs.bk
.vscode/
/target/
/Cargo.lock
158 changes: 150 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,152 @@
[workspace]
members = ["boringtun", "boringtun-cli"]
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.

[profile.release]
lto = true # Enable full link-time optimization.
codegen-units = 1 # Use only 1 codegen-unit to enable full optimizations.
[package]
edition = "2018"
name = "boringtun"
version = "0.7.1"
authors = [
"Noah Kennedy <nkennedy@cloudflare.com>",
"Andy Grover <agrover@cloudflare.com>",
"Jeff Hiner <jhiner@cloudflare.com>",
]
build = false
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "an implementation of the WireGuard® protocol designed for portability and speed"
documentation = "https://docs.rs/boringtun/0.7.1/boringtun/"
readme = "README.md"
license = "BSD-3-Clause"
repository = "https://github.com/cloudflare/boringtun"

[profile.bench]
lto = true # Enable full link-time optimization.
codegen-units = 1 # Use only 1 codegen-unit to enable full optimizations.
[features]
default = []
device = [
"socket2",
"thiserror",
]
ffi-bindings = ["tracing-subscriber"]
jni-bindings = [
"ffi-bindings",
"jni",
]
mock-instant = ["mock_instant"]

[lib]
name = "boringtun"
crate-type = [
"staticlib",
"cdylib",
"rlib",
]
path = "src/lib.rs"

[[bench]]
name = "crypto_benches"
path = "benches/crypto_benches/main.rs"
harness = false

[dependencies.aead]
version = "0.5.0-pre.2"

[dependencies.base64]
version = "0.22"

[dependencies.blake2]
version = "0.10"

[dependencies.chacha20poly1305]
version = "0.10.0-pre.1"

[dependencies.hex]
version = "0.4"

[dependencies.hmac]
version = "0.12"

[dependencies.ip_network]
version = "0.4.1"

[dependencies.ip_network_table]
version = "0.2.0"

[dependencies.jni]
version = "0.19.0"
optional = true

[dependencies.libc]
version = "0.2"

[dependencies.mock_instant]
version = "0.3"
optional = true

[dependencies.parking_lot]
version = "0.12"

[dependencies.portable-atomic]
version = "1.13.1"
features = ["fallback"]

[dependencies.rand_core]
version = "0.6.4"
features = ["getrandom"]

[dependencies.ring]
version = "0.17"

[dependencies.socket2]
version = "0.4.7"
features = ["all"]
optional = true

[dependencies.thiserror]
version = "1"
optional = true

[dependencies.tracing]
version = "0.1.40"

[dependencies.tracing-subscriber]
version = "0.3"
features = ["fmt"]
optional = true

[dependencies.untrusted]
version = "0.9.0"

[dependencies.x25519-dalek]
version = "2.0.1"
features = [
"reusable_secrets",
"static_secrets",
]

[dev-dependencies.criterion]
version = "0.8.2"
features = ["html_reports"]

[dev-dependencies.etherparse]
version = "0.13"

[dev-dependencies.tracing-subscriber]
version = "0.3"

[target."cfg(unix)".dependencies.nix]
version = "0.31"
features = [
"time",
"user",
]
default-features = false
24 changes: 24 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Copyright (c) 2019 Cloudflare, Inc. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 changes: 35 additions & 0 deletions YAT_PATCHES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# YAT patches to boringtun 0.7.1

Source: the published `boringtun` 0.7.1 crate, upstream
<https://github.com/cloudflare/boringtun>, BSD-3-Clause. Original copyright
headers remain in the source. Both yat-wireguard and yat-network use this copy.

Local changes:

- `src/device/mod.rs`: update existing peer routing/endpoint/keepalive in place
instead of panicking; rebuild destination routes after replacing AllowedIPs
to recover prefixes shadowed by legacy overlapping relay routes. Changing a
preshared key still replaces the cryptographic session.
- `src/device/peer.rs`: update routing metadata while preserving the Tunn,
receiver index, counters and session keys; regression test with an established
authenticated session and AllowedIPs handoff.
- `src/noise/timers.rs`: setter for persistent keepalive, used by peer updates.
- `src/device/api.rs`: reset parser state between peer sections and emit
`last_handshake_time_sec/nsec` as Unix time, as required by the WireGuard UAPI.
- `src/lib.rs`: crate-level `#![allow(...)]` for `deprecated`,
`mismatched_lifetime_syntaxes`, `unused_variables`, `dead_code`, silencing
upstream diagnostics from `ring::constant_time::verify_slices_are_equal`,
`base64::decode`, elided lifetimes on `Iter`/`LockReadGuard`/`Packet`, and
feature-gated helpers (`fwmark`, `set_persistent_keepalive`, `KeyBytes`).
Keeps the vendor tree close to upstream; API migrations are tracked
separately.

No cryptographic algorithms or packet formats are changed. The timestamp fix
must ship with YAT's corresponding UAPI stats parser change. Rebuild the Agent
and privileged helper together; old running helper processes retain old code.

Run regression tests without creating an OS tunnel:

```sh
cargo test --manifest-path vendor/boringtun/Cargo.toml --features device --lib yat_
```
90 changes: 90 additions & 0 deletions benches/crypto_benches/blake2s_benching.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use blake2::digest::{FixedOutput, KeyInit};
use blake2::{Blake2s256, Blake2sMac, Digest};
use criterion::{BenchmarkId, Criterion, Throughput};
use ring::rand::{SecureRandom, SystemRandom};

pub fn bench_blake2s_hash(c: &mut Criterion) {
let mut group = c.benchmark_group("blake2s_hash");

group.sample_size(1000);

for size in [32, 64, 128] {
group.throughput(Throughput::Bytes(size as u64));

group.bench_with_input(BenchmarkId::new("blake2s_crate", size), &size, |b, _| {
let buf_in = vec![0u8; size];

b.iter(|| {
let mut hasher = Blake2s256::new();
hasher.update(&buf_in);
hasher.finalize();
});
});
}

group.finish();
}

pub fn bench_blake2s_hmac(c: &mut Criterion) {
let mut group = c.benchmark_group("blake2s_hmac");

group.sample_size(1000);

for size in [16, 32] {
group.throughput(Throughput::Bytes(size as u64));

group.bench_with_input(BenchmarkId::new("blake2s_crate", size), &size, |b, _| {
let buf_in = vec![0u8; size];
let rng = SystemRandom::new();

b.iter_batched(
|| {
let mut key = [0u8; 32];
rng.fill(&mut key).unwrap();
key
},
|key| {
use blake2::digest::Update;
type HmacBlake2s = hmac::SimpleHmac<blake2::Blake2s256>;
let mut hmac = HmacBlake2s::new_from_slice(&key).unwrap();
hmac.update(&buf_in);
hmac.finalize_fixed();
},
criterion::BatchSize::SmallInput,
);
});
}

group.finish();
}

pub fn bench_blake2s_keyed(c: &mut Criterion) {
let mut group = c.benchmark_group("blake2s_keyed_mac");

group.sample_size(1000);

for size in [128, 1024] {
group.throughput(Throughput::Bytes(size as u64));

group.bench_with_input(BenchmarkId::new("blake2s_crate", size), &size, |b, _| {
let buf_in = vec![0u8; size];
let rng = SystemRandom::new();

b.iter_batched(
|| {
let mut key = [0u8; 16];
rng.fill(&mut key).unwrap();
key
},
|key| -> [u8; 16] {
let mut hmac = Blake2sMac::new_from_slice(&key).unwrap();
blake2::digest::Update::update(&mut hmac, &buf_in);
hmac.finalize_fixed().into()
},
criterion::BatchSize::SmallInput,
);
});
}

group.finish();
}
79 changes: 79 additions & 0 deletions benches/crypto_benches/chacha20poly1305_benching.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use aead::{AeadInPlace, KeyInit};
use criterion::{BenchmarkId, Criterion, Throughput};
use rand_core::{OsRng, RngCore};
use ring::aead::{Aad, LessSafeKey, Nonce, UnboundKey, CHACHA20_POLY1305};

fn chacha20poly1305_ring(key_bytes: &[u8], buf: &mut [u8]) {
let len = buf.len();
let n = len - 16;

let key = LessSafeKey::new(UnboundKey::new(&CHACHA20_POLY1305, key_bytes).unwrap());

let tag = key
.seal_in_place_separate_tag(
Nonce::assume_unique_for_key([0u8; 12]),
Aad::from(&[]),
&mut buf[..n],
)
.unwrap();

buf[n..].copy_from_slice(tag.as_ref())
}

fn chacha20poly1305_non_ring(key_bytes: &[u8], buf: &mut [u8]) {
let len = buf.len();
let n = len - 16;

let aead = chacha20poly1305::ChaCha20Poly1305::new_from_slice(key_bytes).unwrap();
let nonce = chacha20poly1305::Nonce::default();

let tag = aead
.encrypt_in_place_detached(&nonce, &[], &mut buf[..n])
.unwrap();

buf[n..].copy_from_slice(tag.as_ref());
}

pub fn bench_chacha20poly1305(c: &mut Criterion) {
let mut group = c.benchmark_group("chacha20poly1305");

group.sample_size(1000);

for size in [128, 192, 1400, 8192] {
group.throughput(Throughput::Bytes(size as u64));

group.bench_with_input(
BenchmarkId::new("chacha20poly1305_ring", size),
&size,
|b, i| {
let mut key = [0; 32];
let mut buf = vec![0; i + 16];

let mut rng = OsRng::default();

rng.fill_bytes(&mut key);
rng.fill_bytes(&mut buf);

b.iter(|| chacha20poly1305_ring(&key, &mut buf));
},
);

group.bench_with_input(
BenchmarkId::new("chacha20poly1305_non_ring", size),
&size,
|b, i| {
let mut key = [0; 32];
let mut buf = vec![0; i + 16];

let mut rng = OsRng::default();

rng.fill_bytes(&mut key);
rng.fill_bytes(&mut buf);

b.iter(|| chacha20poly1305_non_ring(&key, &mut buf));
},
);
}

group.finish();
}
Loading