mirror of
https://github.com/rosenpass/rosenpass.git
synced 2025-12-13 07:50:38 -08:00
Compare commits
28 Commits
v0.1.1-rc.
...
dev/rustif
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60155a5530 | ||
|
|
664c591138 | ||
|
|
566795afd2 | ||
|
|
8eea5284bf | ||
|
|
df00c1987c | ||
|
|
becc8c057a | ||
|
|
1625d94b71 | ||
|
|
a62405190e | ||
|
|
5afa6c19a6 | ||
|
|
ecc1b75b00 | ||
|
|
fe80792873 | ||
|
|
3fc28a0b70 | ||
|
|
97f5d75838 | ||
|
|
aa15872f2b | ||
|
|
1d10e7f036 | ||
|
|
cc01472942 | ||
|
|
4b33938d66 | ||
|
|
f4c351c74b | ||
|
|
12522e90ea | ||
|
|
0995317fa6 | ||
|
|
4b4902cacd | ||
|
|
c389d39fbd | ||
|
|
12933de42b | ||
|
|
9b3f4670af | ||
|
|
8313a61cc7 | ||
|
|
175a9c20af | ||
|
|
a9c13caeaa | ||
|
|
92838250b5 |
23
.github/workflows/nix.yaml
vendored
23
.github/workflows/nix.yaml
vendored
@@ -31,38 +31,37 @@ jobs:
|
||||
- name: Generate gitHeadInfo.gin for the whitepaper
|
||||
if: ${{ matrix.derivation == 'whitepaper' }}
|
||||
run: ( cd papers && ./tex/gitinfo2.sh && git add gitHeadInfo.gin )
|
||||
- name: Build ${{ matrix.derivation }}
|
||||
- name: Build ${{ matrix.derivation }}@${{ matrix.nix-system }}
|
||||
run: |
|
||||
# build the package
|
||||
nix build .#packages.${{ matrix.nix-system }}.${{ matrix.derivation }} --print-build-logs
|
||||
|
||||
# copy over the results
|
||||
if [[ -f $(readlink --canonicalize result ) ]]; then
|
||||
mkdir -- ${{ matrix.derivation }}
|
||||
mkdir -- ${{ matrix.derivation }}-${{ matrix.nix-system }}
|
||||
fi
|
||||
cp --recursive -- $(readlink --canonicalize -- result) ${{ matrix.derivation }}
|
||||
chmod --recursive -- ug+rw ${{ matrix.derivation }}
|
||||
cp --recursive -- $(readlink --canonicalize result) ${{ matrix.derivation }}-${{ matrix.nix-system }}
|
||||
chmod --recursive ug+rw -- ${{ matrix.derivation }}-${{ matrix.nix-system }}
|
||||
|
||||
# add version information
|
||||
git rev-parse --abbrev-ref HEAD > ${{ matrix.derivation }}/git-version
|
||||
git rev-parse HEAD > ${{ matrix.derivation }}/git-sha
|
||||
git rev-parse --abbrev-ref HEAD > ${{ matrix.derivation }}-${{ matrix.nix-system }}/git-version
|
||||
git rev-parse HEAD > ${{ matrix.derivation }}-${{ matrix.nix-system }}/git-sha
|
||||
|
||||
# override the `rp` script to keep compatible with non-nix systems
|
||||
if [[ -f ${{ matrix.derivation }}/bin/rp ]]
|
||||
then
|
||||
cp --force rp ${{ matrix.derivation }}/bin/
|
||||
if [[ -f ${{ matrix.derivation }}-${{ matrix.nix-system }}/bin/rp ]]; then
|
||||
cp --force -- rp ${{ matrix.derivation }}-${{ matrix.nix-system }}/bin/
|
||||
fi
|
||||
- name: Upload build results
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.derivation }}@${{ matrix.nix-system }}
|
||||
path: ${{ matrix.derivation }}
|
||||
name: ${{ matrix.derivation }}-${{ matrix.nix-system }}
|
||||
path: ${{ matrix.derivation }}-${{ matrix.nix-system }}
|
||||
- name: Deploy PDF artifacts
|
||||
if: ${{ matrix.derivation == 'whitepaper' && github.ref == 'refs/heads/main' }}
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: whitepaper
|
||||
publish_dir: ${{ matrix.derivation }}-${{ matrix.nix-system }}
|
||||
publish_branch: papers-pdf
|
||||
force_orphan: true
|
||||
checks:
|
||||
|
||||
30
.github/workflows/release.yaml
vendored
Normal file
30
.github/workflows/release.yaml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
name: Release
|
||||
permissions:
|
||||
contents: write
|
||||
on:
|
||||
push:
|
||||
tags: ["v*"]
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Release for ${{ matrix.nix-system }}
|
||||
runs-on:
|
||||
- nix
|
||||
- ${{ matrix.nix-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
nix-system:
|
||||
- x86_64-linux
|
||||
# - aarch64-linux
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build release-package for ${{ matrix.nix-system }}
|
||||
run: nix build .#release-package --print-build-logs
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
draft: ${{ contains(github.ref_name, 'rc') }}
|
||||
prerelease: ${{ contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta') }}
|
||||
files: |
|
||||
result/*
|
||||
84
Cargo.lock
generated
84
Cargo.lock
generated
@@ -186,7 +186,7 @@ checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"clap_lex",
|
||||
"clap_lex 0.2.4",
|
||||
"indexmap",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
@@ -194,6 +194,34 @@ dependencies = [
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d7ae14b20b94cb02149ed21a86c423859cbe18dc7ed69845cace50e52b40a5"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"clap_derive",
|
||||
"clap_lex 0.3.2",
|
||||
"is-terminal",
|
||||
"once_cell",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44bec8e5c9d09e439c4335b1af0abaab56dcf3b94999a936e1bb47b9134288f0"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.2.4"
|
||||
@@ -203,6 +231,15 @@ dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "350b9cf31731f9957399229e9b2adc51eeabdfbe9d71d9a0552275fd12710d09"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.49"
|
||||
@@ -429,6 +466,12 @@ version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
@@ -776,6 +819,30 @@ dependencies = [
|
||||
"plotters-backend",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.51"
|
||||
@@ -865,7 +932,7 @@ checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422"
|
||||
|
||||
[[package]]
|
||||
name = "rosenpass"
|
||||
version = "0.1.1-rc.2"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
@@ -883,6 +950,13 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rp"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap 4.1.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.21"
|
||||
@@ -1176,6 +1250,12 @@ version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.2"
|
||||
|
||||
39
Cargo.toml
39
Cargo.toml
@@ -1,35 +1,6 @@
|
||||
[package]
|
||||
name = "rosenpass"
|
||||
version = "0.1.1-rc.2"
|
||||
authors = ["Karolin Varner <karo@cupdev.net>", "wucke13 <wucke13@gmail.com>"]
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "Build post-quantum-secure VPNs with WireGuard!"
|
||||
homepage = "https://rosenpass.eu/"
|
||||
repository = "https://github.com/rosenpass/rosenpass"
|
||||
readme = "readme.md"
|
||||
[workspace]
|
||||
|
||||
[[bench]]
|
||||
name = "handshake"
|
||||
harness = false
|
||||
|
||||
[dependencies]
|
||||
anyhow = { version = "1.0.52", features = ["backtrace"] }
|
||||
base64 = "0.13.0"
|
||||
clap = { version = "3.0.0", features = ["yaml"] }
|
||||
static_assertions = "1.1.0"
|
||||
memoffset = "0.6.5"
|
||||
libsodium-sys-stable = { version = "1.19.26", features = ["use-pkg-config"] }
|
||||
oqs-sys = { version = "0.7.1", default-features = false, features = ['classic_mceliece', 'kyber'] }
|
||||
lazy_static = "1.4.0"
|
||||
thiserror = "1.0.38"
|
||||
paste = "1.0.11"
|
||||
log = { version = "0.4.17", optional = true }
|
||||
env_logger = { version = "0.10.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3.5"
|
||||
test_bin = "0.4.0"
|
||||
|
||||
[features]
|
||||
default = ["log", "env_logger"]
|
||||
members = [
|
||||
"rosenpass",
|
||||
"rp",
|
||||
]
|
||||
23
flake.nix
23
flake.nix
@@ -132,6 +132,29 @@
|
||||
default = rosenpass;
|
||||
rosenpass = rpDerivation pkgs;
|
||||
rosenpass-oci-image = rosenpassOCI "rosenpass";
|
||||
|
||||
# derivation for the release
|
||||
release-package =
|
||||
let
|
||||
version = cargoToml.package.version;
|
||||
package =
|
||||
if pkgs.hostPlatform.isLinux then
|
||||
packages.rosenpass-static
|
||||
else packages.rosenpass;
|
||||
oci-image =
|
||||
if pkgs.hostPlatform.isLinux then
|
||||
packages.rosenpass-static-oci-image
|
||||
else packages.rosenpass-oci-image;
|
||||
in
|
||||
pkgs.runCommandNoCC "lace-result" { }
|
||||
''
|
||||
mkdir {bin,$out}
|
||||
cp ${./.}/rp bin/
|
||||
tar -cvf $out/rosenpass-${system}-${version}.tar bin/rp \
|
||||
-C ${package} bin/rosenpass
|
||||
cp ${oci-image} \
|
||||
$out/rosenpass-oci-image-${system}-${version}.tar.gz
|
||||
'';
|
||||
} // (if pkgs.stdenv.isLinux then rec {
|
||||
rosenpass-static = rpDerivation pkgs.pkgsStatic;
|
||||
rosenpass-static-oci-image = rosenpassOCI "rosenpass-static";
|
||||
|
||||
5
papers/graphics/readme.md
Normal file
5
papers/graphics/readme.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Illustrations
|
||||
|
||||
## License
|
||||
|
||||
The graphics graphics (SVG, PDF, and PNG files) in this folder are released under the CC BY-SA 4.0 license.
|
||||
@@ -1,218 +0,0 @@
|
||||
root: 0 { shape: text }
|
||||
PROTOCOL: "PROTOCOL" { shape: text }
|
||||
|
||||
protocol_comment: 'PROTOCOL = "rosenpass 1 rosenpass.eu aead=chachapoly1305 dprf=blake2s ekem=lightsaber skem=mceliece460896 xaead=xchachapoly1305"' { shape: text}
|
||||
|
||||
ck_init: '"chaining key init"' { shape: text }
|
||||
ck_ext: '"chaining key extract"' { shape: text }
|
||||
|
||||
mac: '"mac"' { shape: text }
|
||||
mac_param: MAC_WIRE_DATA { shape: text }
|
||||
cookie: '"cookie"' { shape: text }
|
||||
cookie_param: COOKIE_WIRE_DATA { shape: text }
|
||||
peer_id: '"peer_id"' { shape: text }
|
||||
peer_id_p1: spkm { shape: text}
|
||||
peer_id_p2: spkt { shape: text}
|
||||
|
||||
root -> PROTOCOL
|
||||
|
||||
PROTOCOL -> mac -> mac_param
|
||||
PROTOCOL -> cookie -> cookie_param
|
||||
PROTOCOL -> peer_id -> peer_id_p1 -> peer_id_p2
|
||||
PROTOCOL -> ck_init
|
||||
PROTOCOL -> ck_ext
|
||||
|
||||
mix: '"mix"' { shape: text }
|
||||
user: '"user"' { shape: text }
|
||||
rp_eu: '"rosenpass.eu"' { shape: text }
|
||||
wg_psk: '"wireguard psk"' { shape: text }
|
||||
hs_enc: '"handshake encryption"' { shape: text }
|
||||
ini_enc: '"initiator session encryption"' { shape: text }
|
||||
res_enc: '"responder session encryption"' { shape: text }
|
||||
|
||||
ck_ext -> mix
|
||||
ck_ext -> user -> rp_eu -> wg_psk
|
||||
ck_ext -> hs_enc
|
||||
ck_ext -> ini_enc
|
||||
ck_ext -> res_enc
|
||||
|
||||
# ck_init -> InitHello.start
|
||||
|
||||
InitHello {
|
||||
start -> d0 \
|
||||
-> m1 -> d1 \
|
||||
-> m2 -> d2
|
||||
|
||||
d2 -> encaps_spkr.m1
|
||||
encaps_spkr.d3 -> encrypt_ltk.m1
|
||||
encaps_spkr.d3 -> encrypt_ltk.key
|
||||
encrypt_ltk.d1 -> encrypt_auth.m1
|
||||
encrypt_ltk.d1 -> encrypt_auth.key
|
||||
|
||||
m1: "mix" { shape: text }
|
||||
m2: "mix" { shape: text }
|
||||
|
||||
start: '"chaining key init"' { shape: text }
|
||||
d0: "spkr" { shape: circle }
|
||||
d1: "sidi" { shape: circle }
|
||||
d2: "epki" { shape: circle }
|
||||
|
||||
encaps_spkr {
|
||||
m1 -> d1 \
|
||||
-> m2 -> d2 \
|
||||
-> m3 -> d3 \
|
||||
|
||||
m1: "mix" { shape: text }
|
||||
m2: "mix" { shape: text }
|
||||
m3: "mix" { shape: text }
|
||||
|
||||
d1: "spkr" { shape: circle }
|
||||
d2: "sctr" { shape: circle }
|
||||
d3: "sptr" { shape: circle }
|
||||
}
|
||||
|
||||
encrypt_ltk {
|
||||
m1 -> d1
|
||||
|
||||
encrypt: 'Aead::enc(peer_id(spkr, spki))'
|
||||
key -> encrypt: {
|
||||
target-arrowhead.label: key
|
||||
}
|
||||
data -> encrypt: {
|
||||
target-arrowhead.label: data
|
||||
}
|
||||
encrypt -> d1: {
|
||||
source-arrowhead.label: output
|
||||
}
|
||||
|
||||
m1: "mix" { shape: text }
|
||||
key: '"handshake encryption"' { shape: text }
|
||||
data: 'ref from "peer id" branch after spkt' { shape: text }
|
||||
d1: "ct" { shape: diamond }
|
||||
}
|
||||
|
||||
encrypt_auth {
|
||||
m1 -> d1
|
||||
|
||||
encrypt: 'Aead::enc(empty())'
|
||||
key -> encrypt: {
|
||||
target-arrowhead.label: key
|
||||
}
|
||||
encrypt -> d1: {
|
||||
source-arrowhead.label: output
|
||||
}
|
||||
|
||||
m1: "mix" { shape: text }
|
||||
key: '"handshake encryption"' { shape: text }
|
||||
d1: "ct" { shape: diamond }
|
||||
}
|
||||
}
|
||||
|
||||
RespHello {
|
||||
start -> d0 -> m1 -> d1
|
||||
d1 -> encaps_epki.m1
|
||||
encaps_epki.d3 -> encaps_spki.m1
|
||||
encaps_spki.d3 -> m2 -> d2
|
||||
d2 -> encrypt_auth.m1
|
||||
|
||||
store_biscuit -> d2
|
||||
"pidi" -> store_biscuit {
|
||||
target-arrowhead.label: "field=peerid"
|
||||
}
|
||||
encaps_spki.d3 -> store_biscuit {
|
||||
target-arrowhead.label: "field=ck"
|
||||
}
|
||||
|
||||
|
||||
m1: "mix" { shape: text }
|
||||
m2: "mix" { shape: text }
|
||||
|
||||
start: '(state from InitHello)' { shape: text }
|
||||
d0: "sidr" { shape: circle }
|
||||
d1: "sidi" { shape: circle }
|
||||
d2: "biscuit" { shape: diamond }
|
||||
|
||||
store_biscuit: "store_biscuit()"
|
||||
|
||||
encaps_epki {
|
||||
m1 -> d1 \
|
||||
-> m2 -> d2 \
|
||||
-> m3 -> d3 \
|
||||
|
||||
m1: "mix" { shape: text }
|
||||
m2: "mix" { shape: text }
|
||||
m3: "mix" { shape: text }
|
||||
|
||||
d1: "epki" { shape: circle }
|
||||
d2: "ecti" { shape: circle }
|
||||
d3: "epti" { shape: circle }
|
||||
}
|
||||
|
||||
encaps_spki {
|
||||
m1 -> d1 \
|
||||
-> m2 -> d2 \
|
||||
-> m3 -> d3 \
|
||||
|
||||
m1: "mix" { shape: text }
|
||||
m2: "mix" { shape: text }
|
||||
m3: "mix" { shape: text }
|
||||
|
||||
d1: "spki" { shape: circle }
|
||||
d2: "scti" { shape: circle }
|
||||
d3: "spti" { shape: circle }
|
||||
}
|
||||
|
||||
encrypt_auth {
|
||||
m1 -> d1
|
||||
|
||||
encrypt: 'Aead::enc(empty())'
|
||||
key -> encrypt: {
|
||||
target-arrowhead.label: key
|
||||
}
|
||||
encrypt -> d1: {
|
||||
source-arrowhead.label: output
|
||||
}
|
||||
|
||||
m1: "mix" { shape: text }
|
||||
key: '"handshake encryption"' { shape: text }
|
||||
d1: "ct" { shape: diamond }
|
||||
}
|
||||
}
|
||||
|
||||
InitConf {
|
||||
start -> d0 -> m1 -> d1 -> encrypt_auth.m1
|
||||
|
||||
encrypt_auth.d1 -> ol1 -> o1
|
||||
encrypt_auth.d1 -> ol2 -> o2
|
||||
encrypt_auth.d1 -> ol3 -> o3
|
||||
|
||||
m1: "mix" { shape: text }
|
||||
|
||||
start: '(state from RespHello)' { shape: text }
|
||||
d0: "sidi" { shape: circle }
|
||||
d1: "sidr" { shape: circle }
|
||||
|
||||
ol1: '"wireguard psk"' { shape: text }
|
||||
ol2: '"initiator session encryption"' { shape: text }
|
||||
ol3: '"responder session encryption"' { shape: text}
|
||||
o2: "" { shape: page }
|
||||
o1: "" { shape: step }
|
||||
o2: "" { shape: step }
|
||||
o3: "" { shape: step }
|
||||
|
||||
encrypt_auth {
|
||||
m1 -> d1
|
||||
|
||||
encrypt: 'Aead::enc(empty())'
|
||||
key -> encrypt: {
|
||||
target-arrowhead.label: key
|
||||
}
|
||||
encrypt -> d1: {
|
||||
source-arrowhead.label: output
|
||||
}
|
||||
|
||||
m1: "mix" { shape: text }
|
||||
key: '"handshake encryption"' { shape: text }
|
||||
d1: "ct" { shape: diamond }
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 847 KiB |
@@ -23,3 +23,7 @@ inside `papers/`. The PDF files will be located directly in `papers/`.
|
||||
The version info is using gitinfo2. To use the setup one has to run the `papers/tex/gitinfo2.sh` script. In local copies it's also possible to add this as a post-checkout or post-commit hook to keep it automatically up to date.
|
||||
|
||||
The version information in the footer automatically includes a “draft”. This can be removed by tagging a release version using `\jobname-release`, e.h. `whitepaper-release` for the `whitepaper.md` file.
|
||||
|
||||
## Licensing of assets
|
||||
|
||||
The text files and graphics in this folder (i.e. whitepaper.md, the SVG, PDF, and PNG files in the graphics/ folder) are released under the CC BY-SA 4.0 license.
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
Protocol: {
|
||||
shape: sequence_diagram
|
||||
ini: "Initiator"
|
||||
res: "Responder"
|
||||
ini -> res: "InitHello"
|
||||
res -> ini: "RespHello"
|
||||
ini -> res: "InitConf"
|
||||
res -> ini: "EmptyData"
|
||||
}
|
||||
|
||||
Envelope: "Envelope" {
|
||||
shape: class
|
||||
type: "1"
|
||||
'': 3
|
||||
payload: variable
|
||||
mac: 16
|
||||
cookie: 16
|
||||
}
|
||||
|
||||
Envelope.payload -> InitHello
|
||||
InitHello: "InitHello (type=0x81)" {
|
||||
shape: class
|
||||
sidi: 4
|
||||
epki: 800
|
||||
sctr: 188
|
||||
peerid: 32 + 16 = 48
|
||||
auth: 16
|
||||
}
|
||||
|
||||
Envelope.payload -> RespHello
|
||||
RespHello: "RespHello (type=0x82)" {
|
||||
shape: class
|
||||
sidr: 4
|
||||
sidi: 4
|
||||
ecti: 768
|
||||
scti: 188
|
||||
biscuit: 76 + 24 + 16 = 116
|
||||
auth: 16
|
||||
}
|
||||
|
||||
Envelope.payload -> InitConf
|
||||
InitConf: "InitConf (type=0x83)" {
|
||||
shape: class
|
||||
sidi: 4
|
||||
sidr: 4
|
||||
biscuit: 76 + 24 +16 = 116
|
||||
auth: 16
|
||||
}
|
||||
|
||||
Envelope.payload -> EmptyData
|
||||
EmptyData: "EmptyData (type=0x84)" {
|
||||
shape: class
|
||||
sidx: 4
|
||||
ctr: 8
|
||||
auth: 16
|
||||
}
|
||||
|
||||
Envelope.payload -> Data
|
||||
Data: "Data (type=0x85)" {
|
||||
shape: class
|
||||
sidx: 4
|
||||
ctr: 8
|
||||
data: variable + 16
|
||||
}
|
||||
|
||||
Envelope.payload -> CookieReply
|
||||
CookieReply: "CookieReply (type=0x86)" {
|
||||
shape: class
|
||||
sidx: 4
|
||||
nonce: 24
|
||||
cookie: 16 + 16 = 32
|
||||
}
|
||||
|
||||
RespHello.biscuit -> Biscuit
|
||||
InitConf.biscuit -> Biscuit
|
||||
Biscuit: "Biscuit" {
|
||||
shape: class
|
||||
peerid: 32
|
||||
no: 12
|
||||
ck: 32
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 669 KiB |
@@ -130,7 +130,7 @@
|
||||
\bool_set_false:N \l_tmpa_bool
|
||||
\gitAbbrevHash{}~(\gitAuthorDate
|
||||
\clist_map_inline:Nn \gitTags {
|
||||
\exp_args:Nx \str_if_eq:nnT {\jobname-release} {test-whitepaper} {\bool_set_true:N \l_tmpa_bool\clist_map_break:}
|
||||
\exp_args:Nx \str_if_eq:nnT {\jobname-release} {whitepaper-release} {\bool_set_true:N \l_tmpa_bool\clist_map_break:}
|
||||
}
|
||||
\bool_if:NF \l_tmpa_bool {~--~draft}
|
||||
)
|
||||
|
||||
@@ -33,7 +33,7 @@ abstract: |
|
||||
Rosenpass inherits most security properties from Post-Quantum WireGuard (PQWG). The security properties mentioned here are covered by the symbolic analysis in the Rosenpass repository.
|
||||
|
||||
## Secrecy
|
||||
Three key encapsulations using the keypairs `sski`/`spki`, `sskr`/`spkr`, and `eski`/`epki` provide secrecy (see Section \ref{variables} for an introduction of the variables). Their respective ciphertexts are called `scti`, `sctr`, and `ectr` and the resulting keys are called `spti`, `sptr`, `epti`. A single secure encapsulation is sufficient to provide secrecy. We use two different KEMs (Key Encapsulation Methods; see section \ref{skem}): Kyber and Classic McEliece.
|
||||
Three key encapsulations using the keypairs `sski`/`spki`, `sskr`/`spkr`, and `eski`/`epki` provide secrecy (see Section \ref{variables} for an introduction of the variables). Their respective ciphertexts are called `scti`, `sctr`, and `ectr` and the resulting keys are called `spti`, `sptr`, `epti`. A single secure encapsulation is sufficient to provide secrecy. We use two different KEMs (Key Encapsulation Mechanisms; see section \ref{skem}): Kyber and Classic McEliece.
|
||||
|
||||
## Authenticity
|
||||
|
||||
|
||||
35
rosenpass/Cargo.toml
Normal file
35
rosenpass/Cargo.toml
Normal file
@@ -0,0 +1,35 @@
|
||||
[package]
|
||||
name = "rosenpass"
|
||||
version = "0.1.1"
|
||||
authors = ["Karolin Varner <karo@cupdev.net>", "wucke13 <wucke13@gmail.com>"]
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "Build post-quantum-secure VPNs with WireGuard!"
|
||||
homepage = "https://rosenpass.eu/"
|
||||
repository = "https://github.com/rosenpass/rosenpass"
|
||||
readme = "../readme.md"
|
||||
|
||||
[[bench]]
|
||||
name = "handshake"
|
||||
harness = false
|
||||
|
||||
[dependencies]
|
||||
anyhow = { version = "1.0.52", features = ["backtrace"] }
|
||||
base64 = "0.13.0"
|
||||
clap = { version = "3.0.0", features = ["yaml"] }
|
||||
static_assertions = "1.1.0"
|
||||
memoffset = "0.6.5"
|
||||
libsodium-sys-stable = { version = "1.19.26", features = ["use-pkg-config"] }
|
||||
oqs-sys = { version = "0.7.1", default-features = false, features = ['classic_mceliece', 'kyber'] }
|
||||
lazy_static = "1.4.0"
|
||||
thiserror = "1.0.38"
|
||||
paste = "1.0.11"
|
||||
log = { version = "0.4.17", optional = true }
|
||||
env_logger = { version = "0.10.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3.5"
|
||||
test_bin = "0.4.0"
|
||||
|
||||
[features]
|
||||
default = ["log", "env_logger"]
|
||||
@@ -11,9 +11,6 @@ DESCRIPTION
|
||||
These keys can then be passed to various services such as wireguard or other vpn services
|
||||
as pre-shared-keys to achieve security against attackers with quantum computers.
|
||||
|
||||
This is a research project and quantum computers are not thought to become practical in less than ten years.
|
||||
If you are not specifically tasked with developing post-quantum secure systems, you probably do not need this tool.
|
||||
|
||||
COMMANDS
|
||||
|
||||
keygen private-key <file-path> public-key <file-path>
|
||||
@@ -35,11 +32,11 @@ COMMANDS
|
||||
You must either specify the outfile or wireguard output option.
|
||||
|
||||
endpoint <ip>[:<port>]
|
||||
Specifies the address where the peer can be reached. This will be automatically updated after the first sucessfull
|
||||
Specifies the address where the peer can be reached. This will be automatically updated after the first successful
|
||||
key exchange with the peer. If this is unspecified, the peer must initiate the connection.
|
||||
|
||||
preshared-key <file-path>
|
||||
You may specifie a pre-shared key which will be mixied into the final secret.
|
||||
You may specify a pre-shared key which will be mixed into the final secret.
|
||||
|
||||
outfile <file-path>
|
||||
You may specify a file to write the exchanged keys to. If this option is specified, {0} will
|
||||
352
rp
352
rp
@@ -1,352 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# String formatting subsystem
|
||||
|
||||
formatting_init() {
|
||||
endl=$'\n'
|
||||
}
|
||||
|
||||
enquote() {
|
||||
while (( $# > 1 )); do
|
||||
printf "%q " "${1}"; shift
|
||||
done
|
||||
if (( $# == 1 )); then
|
||||
printf "%q" "${1}"; shift
|
||||
fi
|
||||
}
|
||||
|
||||
multiline() {
|
||||
# shellcheck disable=SC1004
|
||||
echo "${1} " | awk '
|
||||
function pm(a, b, l) {
|
||||
return length(a) > l \
|
||||
&& length(b) > l \
|
||||
&& substr(a, 1, l+1) == substr(b, 1, l+1) \
|
||||
? pm(a, b, l+1) : l;
|
||||
}
|
||||
|
||||
!started && $0 !~ /^[ \t]*$/ {
|
||||
started=1
|
||||
match($0, /^[ \t]*/)
|
||||
prefix=substr($0, 1, RLENGTH)
|
||||
}
|
||||
|
||||
started {
|
||||
print(substr($0, 1 + pm($0, prefix)));
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
dbg() {
|
||||
echo >&2 "$@"
|
||||
}
|
||||
|
||||
# Cleanup subsystem (sigterm)
|
||||
|
||||
cleanup_init() {
|
||||
cleanup_actions=()
|
||||
trap cleanup_apply exit
|
||||
}
|
||||
|
||||
cleanup_apply() {
|
||||
local f
|
||||
for f in "${cleanup_actions[@]}"; do
|
||||
eval "${f}"
|
||||
done
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
cleanup_actions+=("$(multiline "${1}")")
|
||||
}
|
||||
|
||||
# Transactional execution subsystem
|
||||
|
||||
frag_init() {
|
||||
explain=0
|
||||
frag_transaction=()
|
||||
frag "
|
||||
#! /bin/bash
|
||||
set -e"
|
||||
}
|
||||
|
||||
frag_apply() {
|
||||
local f
|
||||
for f in "${frag_transaction[@]}"; do
|
||||
if (( explain == 1 )); then
|
||||
dbg "${f}"
|
||||
fi
|
||||
eval "${f}"
|
||||
done
|
||||
}
|
||||
|
||||
frag() {
|
||||
frag_transaction+=("$(multiline "${1}")")
|
||||
}
|
||||
|
||||
frag_append() {
|
||||
local len; len="${#frag_transaction[@]}"
|
||||
frag_transaction=("${frag_transaction[@]:0:len-1}" "${frag_transaction[len-1]}${1}")
|
||||
}
|
||||
|
||||
frag_append_esc() {
|
||||
frag_append " \\${endl}${1}"
|
||||
}
|
||||
|
||||
# Usage documentation subsystem
|
||||
usage_init() {
|
||||
usagestack=("${script}")
|
||||
}
|
||||
|
||||
usage_snap() {
|
||||
echo "${#usagestack}"
|
||||
}
|
||||
|
||||
usage_restore() {
|
||||
local n; n="${1}"
|
||||
dbg REST "${1}"
|
||||
usagestack=("${usagestack[@]:0:n-2}")
|
||||
}
|
||||
|
||||
|
||||
usage() {
|
||||
dbg "Usage: ${usagestack[*]}"
|
||||
}
|
||||
|
||||
fatal() {
|
||||
dbg "FATAL: $*"
|
||||
usage
|
||||
exit 1
|
||||
}
|
||||
|
||||
genkey() {
|
||||
usagestack+=("PRIVATE_KEYS_DIR")
|
||||
local skdir
|
||||
skdir="${1%/}"; shift || fatal "Required positional argument: PRIVATE_KEYS_DIR"
|
||||
|
||||
while (( $# > 0 )); do
|
||||
local arg; arg="$1"; shift
|
||||
case "${arg}" in
|
||||
-h | -help | --help | help) usage; return 0 ;;
|
||||
*) fatal "Unknown option ${arg}";;
|
||||
esac
|
||||
done
|
||||
|
||||
if test -e "${skdir}"; then
|
||||
fatal "PRIVATE_KEYS_DIR \"${skdir}\" already exists"
|
||||
fi
|
||||
|
||||
frag "
|
||||
umask 077
|
||||
mkdir -p $(enquote "${skdir}")
|
||||
wg genkey > $(enquote "${skdir}"/wgsk)
|
||||
$(enquote "${binary}") keygen \\
|
||||
private-key $(enquote "${skdir}"/pqsk) \\
|
||||
public-key $(enquote "${skdir}"/pqpk)"
|
||||
}
|
||||
|
||||
pubkey() {
|
||||
usagestack+=("PRIVATE_KEYS_DIR" "PUBLIC_KEYS_DIR")
|
||||
local skdir pkdir
|
||||
skdir="${1%/}"; shift || fatal "Required positional argument: PRIVATE_KEYS_DIR"
|
||||
pkdir="${1%/}"; shift || fatal "Required positional argument: PUBLIC_KEYS_DIR"
|
||||
|
||||
while (( $# > 0 )); do
|
||||
local arg; arg="$1"; shift
|
||||
case "${arg}" in
|
||||
-h | -help | --help | help) usage; exit 0;;
|
||||
*) fatal "Unknown option ${arg}";;
|
||||
esac
|
||||
done
|
||||
|
||||
if test -e "${pkdir}"; then
|
||||
fatal "PUBLIC_KEYS_DIR \"${pkdir}\" already exists"
|
||||
fi
|
||||
|
||||
frag "
|
||||
mkdir -p $(enquote "${pkdir}")
|
||||
wg pubkey < $(enquote "${skdir}"/wgsk) > $(enquote "${pkdir}/wgpk")
|
||||
cp $(enquote "${skdir}"/pqpk) $(enquote "${pkdir}/pqpk")"
|
||||
}
|
||||
|
||||
exchange() {
|
||||
usagestack+=("PRIVATE_KEYS_DIR" "[dev <device>]" "[listen <ip>:<port>]" "[peer PUBLIC_KEYS_DIR [endpoint <ip>:<port>] [persistent-keepalive <interval>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...]]...")
|
||||
local skdir dev lport
|
||||
dev="${project_name}0"
|
||||
skdir="${1%/}"; shift || fatal "Required positional argument: PRIVATE_KEYS_DIR"
|
||||
|
||||
while (( $# > 0 )); do
|
||||
local arg; arg="$1"; shift
|
||||
case "${arg}" in
|
||||
dev) dev="${1}"; shift || fatal "dev option requires parameter";;
|
||||
peer) set -- "peer" "$@"; break;; # Parsed down below
|
||||
listen)
|
||||
local listen; listen="${1}";
|
||||
lip="${listen%:*}";
|
||||
lport="${listen/*:/}";
|
||||
if [[ "$lip" = "$lport" ]]; then
|
||||
lip="[0::0]"
|
||||
fi
|
||||
shift;;
|
||||
-h | -help | --help | help) usage; return 0;;
|
||||
*) fatal "Unknown option ${arg}";;
|
||||
esac
|
||||
done
|
||||
|
||||
if (( $# == 0 )); then
|
||||
fatal "Needs at least one peer specified"
|
||||
fi
|
||||
|
||||
frag "
|
||||
# Create the Wireguard interface
|
||||
ip link add dev $(enquote "${dev}") type wireguard || true"
|
||||
|
||||
cleanup "
|
||||
ip link del dev $(enquote "${dev}") || true"
|
||||
|
||||
frag "
|
||||
ip link set dev $(enquote "${dev}") up"
|
||||
|
||||
frag "
|
||||
# Deploy the classic wireguard private key
|
||||
wg set $(enquote "${dev}") private-key $(enquote "${skdir}/wgsk")"
|
||||
|
||||
|
||||
if test -n "${lport}"; then
|
||||
frag_append "listen-port $(enquote "$(( lport + 1 ))")"
|
||||
fi
|
||||
|
||||
frag "
|
||||
# Launch the post quantum wireguard exchange daemon
|
||||
$(enquote "${binary}") exchange"
|
||||
|
||||
if (( verbose == 1 )); then
|
||||
frag_append "verbose"
|
||||
fi
|
||||
|
||||
frag_append_esc " private-key $(enquote "${skdir}/pqsk")"
|
||||
frag_append_esc " public-key $(enquote "${skdir}/pqpk")"
|
||||
|
||||
if test -n "${lport}"; then
|
||||
frag_append_esc " listen $(enquote "${lip}:${lport}")"
|
||||
fi
|
||||
|
||||
usagestack+=("peer" "PUBLIC_KEYS_DIR endpoint IP:PORT")
|
||||
|
||||
while (( $# > 0 )); do
|
||||
shift; # Skip "peer" argument
|
||||
|
||||
local peerdir ip port keepalive allowedips
|
||||
peerdir="${1%/}"; shift || fatal "Required peer argument: PUBLIC_KEYS_DIR"
|
||||
|
||||
while (( $# > 0 )); do
|
||||
local arg; arg="$1"; shift
|
||||
case "${arg}" in
|
||||
peer) set -- "peer" "$@"; break;; # Next peer
|
||||
endpoint) ip="${1%:*}"; port="${1/*:/}"; shift;;
|
||||
persistent-keepalive) keepalive="${1}"; shift;;
|
||||
allowed-ips) allowedips="${1}"; shift;;
|
||||
-h | -help | --help | help) usage; return 0;;
|
||||
*) fatal "Unknown option ${arg}";;
|
||||
esac
|
||||
done
|
||||
|
||||
# Public key
|
||||
frag_append_esc " peer public-key $(enquote "${peerdir}/pqpk")"
|
||||
|
||||
# PSK
|
||||
local pskfile; pskfile="${peerdir}/psk"
|
||||
if test -f "${pskfile}"; then
|
||||
frag_append_esc " preshared-key $(enquote "${pskfile}")"
|
||||
fi
|
||||
|
||||
|
||||
if test -n "${ip}"; then
|
||||
frag_append_esc " endpoint $(enquote "${ip}:${port}")"
|
||||
fi
|
||||
|
||||
frag_append_esc " wireguard $(enquote "${dev}") $(enquote "$(cat "${peerdir}/wgpk")")"
|
||||
|
||||
if test -n "${ip}"; then
|
||||
frag_append_esc " endpoint $(enquote "${ip}:$(( port + 1 ))")"
|
||||
fi
|
||||
|
||||
if test -n "${keepalive}"; then
|
||||
frag_append_esc " persistent-keepalive $(enquote "${keepalive}")"
|
||||
fi
|
||||
|
||||
if test -n "${allowedips}"; then
|
||||
frag_append_esc " allowed-ips $(enquote "${allowedips}")"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
find_rosenpass_binary() {
|
||||
local binary; binary=""
|
||||
if [[ -n "${gitdir}" ]]; then
|
||||
# If rp is run from the git repo, use the newest build artifact
|
||||
binary=$(
|
||||
find "${gitdir}/result/bin/${project_name}" \
|
||||
"${gitdir}"/target/{release,debug}/"${project_name}" \
|
||||
-printf "%T@ %p\n" 2>/dev/null \
|
||||
| sort -nr \
|
||||
| awk 'NR==1 { print($2) }'
|
||||
)
|
||||
elif [[ -n "${nixdir}" ]]; then
|
||||
# If rp is run from nix, use the nix-installed rosenpass version
|
||||
binary="${nixdir}/bin/${project_name}"
|
||||
fi
|
||||
|
||||
if [[ -z "${binary}" ]]; then
|
||||
binary="${project_name}"
|
||||
fi
|
||||
|
||||
echo "${binary}"
|
||||
}
|
||||
|
||||
main() {
|
||||
formatting_init
|
||||
cleanup_init
|
||||
usage_init
|
||||
frag_init
|
||||
|
||||
project_name="rosenpass"
|
||||
verbose=0
|
||||
scriptdir="$(dirname "${script}")"
|
||||
gitdir="$(git -C "${scriptdir}" rev-parse --show-toplevel 2>/dev/null)" || true
|
||||
nixdir="$(readlink -f result/bin/rp | grep -Pio '^/nix/store/[^/]+(?=/bin/[^/]+)')" || true
|
||||
binary="$(find_rosenpass_binary)"
|
||||
|
||||
# Parse command
|
||||
|
||||
usagestack+=("[explain]" "[verbose]" "genkey|pubkey|exchange" "[ARGS]...")
|
||||
|
||||
local cmd
|
||||
while (( $# > 0 )); do
|
||||
local arg; arg="$1"; shift
|
||||
case "${arg}" in
|
||||
genkey|pubkey|exchange) cmd="${arg}"; break;;
|
||||
explain) explain=1;;
|
||||
verbose) verbose=1;;
|
||||
-h | -help | --help | help) usage; return 0 ;;
|
||||
*) fatal "Unknown command ${arg}";;
|
||||
esac
|
||||
done
|
||||
|
||||
test -n "${cmd}" || fatal "No command supplied"
|
||||
usagestack=("${script}")
|
||||
|
||||
# Execute command
|
||||
|
||||
usagestack+=("${cmd}")
|
||||
"${cmd}" "$@"
|
||||
usagestack=("${script}")
|
||||
|
||||
# Apply transaction
|
||||
|
||||
frag_apply
|
||||
}
|
||||
|
||||
script="$0"
|
||||
main "$@"
|
||||
13
rp/Cargo.toml
Normal file
13
rp/Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "rp"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["wucke13 <wucke13@gmail.com>", "Karolin Varner <karo@cupdev.net>"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "Build post-quantum-secure VPNs with WireGuard!"
|
||||
homepage = "https://rosenpass.eu/"
|
||||
repository = "https://github.com/rosenpass/rosenpass"
|
||||
readme = "../readme.md"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.1.8", features = ["derive"] }
|
||||
55
rp/src/main.rs
Normal file
55
rp/src/main.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
|
||||
// Usage: ../rp-old [explain] [verbose] genkey|pubkey|exchange [ARGS]...
|
||||
|
||||
/// Simple program to greet a person
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Cli {
|
||||
/// Explain what is done
|
||||
#[arg(short, long)]
|
||||
explain: bool,
|
||||
|
||||
/// Be verbose about what's going on
|
||||
#[arg(short, long)]
|
||||
verbose: bool,
|
||||
|
||||
#[command(subcommand)]
|
||||
command: Command,
|
||||
}
|
||||
|
||||
/// Doc comment
|
||||
#[derive(Subcommand, Debug)]
|
||||
// #[command(PARENT CMD ATTRIBUTE)]
|
||||
enum Command {
|
||||
/// Generate a keypair
|
||||
// --- Requirements ---
|
||||
// requires wireguard
|
||||
// should not exist before
|
||||
// should be dir after
|
||||
// should contain three files after pqpk, pqsk, wgsk
|
||||
Genkey {
|
||||
private_keys_dir: PathBuf,
|
||||
},
|
||||
|
||||
/// Generate public keys
|
||||
// --- Requirements ---
|
||||
// requires wireguard
|
||||
// requires private_keys_dir to exist
|
||||
// should create public_keys_dir
|
||||
// should copy pqpk from private_ to public_keys_dir
|
||||
// should generate wgpk to public_keys_dir
|
||||
Pubkey {
|
||||
private_keys_dir: PathBuf,
|
||||
public_keys_dir: PathBuf,
|
||||
},
|
||||
|
||||
Exchange {},
|
||||
}
|
||||
fn main() {
|
||||
let args = Cli::parse();
|
||||
|
||||
println!("{args:#?}");
|
||||
}
|
||||
Reference in New Issue
Block a user