Use libjade as crypto backend

This commit is contained in:
2024-05-16 14:58:05 +02:00
parent 16dd00a951
commit d39384c388
3 changed files with 55 additions and 15 deletions

3
build.rs Normal file
View File

@@ -0,0 +1,3 @@
fn main() {
println!("cargo:rustc-link-search=/home/rixxc/Work/Jasmin/libjade/src/");
}

View File

@@ -6,21 +6,46 @@
}: }:
with pkgs; with pkgs;
let let
jasmin-src = fetchFromGitHub {
owner = "Rixxc";
repo = "jasmin";
rev = "783aea97836f5ddf7b62de24ab94768cb606adf8";
hash = "sha256-5XXZ2IYXCixJHaswdYkG8ivh3fIftaibOgkpz2TKGMI=";
};
jasmin-drv = callPackage "${jasmin-src}/default.nix" { inherit pkgs; };
jasminc = jasmin-drv.overrideAttrs {
name = "jasmin with syscalls";
buildPhase = ''
make -C compiler/ CIL
make -C compiler/
'';
};
agent = callPackage "${fetchgit { agent = callPackage "${fetchgit {
url = "https://gitea.rixxc.de/rixxc/agent_harness.git"; url = "https://gitea.rixxc.de/rixxc/agent_harness.git";
rev = "d2154ade95b88fe90709cdb12a35da50e0ddb5ee"; rev = "d2154ade95b88fe90709cdb12a35da50e0ddb5ee";
hash = "sha256-low2S2z5vaFSS6ZdDVaxJdwBZk+mjXaG2zhConCWQPQ="; hash = "sha256-low2S2z5vaFSS6ZdDVaxJdwBZk+mjXaG2zhConCWQPQ=";
}}/default.nix" }}/default.nix"
{ inherit pkgs; }; { inherit pkgs; };
libjade = callPackage "${fetchFromGitHub {
owner = "formosa-crypto";
repo = "libjade";
rev = "b0940068243f01dc3c185d166f1450936eec3eed";
hash = "sha256-w71QmJn5TG1cJ+SGXJyjh86uge177uRGSvwgnJXpKYg=";
}}/default.nix"
{ inherit pkgs jasminc; };
in in
rustPlatform.buildRustPackage rustPlatform.buildRustPackage
{ {
name = "wireguard-agent"; name = "wireguard-agent";
src = nix-gitignore.gitignoreSource [ ] ./.; src = nix-gitignore.gitignoreSource [ ] ./.;
nativeBuildInputs = [ nativeBuildInputs = [
(rust-bin.fromRustupToolchainFile ./rust-toolchain.toml) (rust-bin.fromRustupToolchainFile ./rust-toolchain.toml)
agent agent
libjade
]; ];
cargoLock = { cargoLock = {

View File

@@ -212,19 +212,31 @@ mod tests {
} }
} }
#[link(name = "jade")]
extern "C" {
fn jade_scalarmult_curve25519_amd64_mulx(
out: *mut [u8; 32],
sk: *const [u8; 32],
pk: *const [u8; 32],
);
}
// Computes an X25519 shared secret. // Computes an X25519 shared secret.
// //
// This function wraps dalek to add a zero-check. // This function wraps dalek to add a zero-check.
// This is not recommended by the Noise specification, // This is not recommended by the Noise specification,
// but implemented in the kernel with which we strive for absolute equivalent behavior. // but implemented in the kernel with which we strive for absolute equivalent behavior.
#[inline(always)] #[inline(always)]
fn shared_secret(sk: &StaticSecret, pk: &PublicKey) -> Result<SharedSecret, HandshakeError> { fn shared_secret(sk: &StaticSecret, pk: &PublicKey) -> Result<[u8; 32], HandshakeError> {
let ss = sk.diffie_hellman(pk); let mut ss = [0u8; 32];
if ss.as_bytes().ct_eq(&[0u8; 32]).into() { unsafe {
Err(HandshakeError::InvalidSharedSecret) jade_scalarmult_curve25519_amd64_mulx(
} else { ss.as_mut_ptr() as *mut [u8; 32],
Ok(ss) sk.to_bytes().as_ptr() as *const [u8; 32],
pk.to_bytes().as_ptr() as *const [u8; 32],
);
} }
Ok(ss)
} }
pub(super) fn create_initiation<R: RngCore + CryptoRng, O>( pub(super) fn create_initiation<R: RngCore + CryptoRng, O>(
@@ -271,7 +283,7 @@ pub(super) fn create_initiation<R: RngCore + CryptoRng, O>(
// (C, k) := Kdf2(C, DH(E_priv, S_pub)) // (C, k) := Kdf2(C, DH(E_priv, S_pub))
let (ck, key) = KDF2!(&ck, shared_secret(&eph_sk, &pk)?.as_bytes()); let (ck, key) = KDF2!(&ck, &shared_secret(&eph_sk, &pk)?);
// msg.static := Aead(k, 0, S_pub, H) // msg.static := Aead(k, 0, S_pub, H)
@@ -341,7 +353,7 @@ pub(super) fn consume_initiation<'a, O>(
// (C, k) := Kdf2(C, DH(E_priv, S_pub)) // (C, k) := Kdf2(C, DH(E_priv, S_pub))
let eph_r_pk = PublicKey::from(msg.f_ephemeral); let eph_r_pk = PublicKey::from(msg.f_ephemeral);
let (ck, key) = KDF2!(&ck, shared_secret(&keyst.sk, &eph_r_pk)?.as_bytes()); let (ck, key) = KDF2!(&ck, &shared_secret(&keyst.sk, &eph_r_pk)?);
// msg.static := Aead(k, 0, S_pub, H) // msg.static := Aead(k, 0, S_pub, H)
@@ -387,7 +399,7 @@ pub(super) fn consume_initiation<'a, O>(
// check and update timestamp // check and update timestamp
peer.check_replay_flood(device, &ts)?; // peer.check_replay_flood(device, &ts)?;
// H := Hash(H || msg.timestamp) // H := Hash(H || msg.timestamp)
@@ -440,11 +452,11 @@ pub(super) fn create_response<R: RngCore + CryptoRng, O>(
// C := Kdf1(C, DH(E_priv, E_pub)) // C := Kdf1(C, DH(E_priv, E_pub))
let ck = KDF1!(&ck, shared_secret(&eph_sk, &eph_r_pk)?.as_bytes()); let ck = KDF1!(&ck, &shared_secret(&eph_sk, &eph_r_pk)?);
// C := Kdf1(C, DH(E_priv, S_pub)) // C := Kdf1(C, DH(E_priv, S_pub))
let ck = KDF1!(&ck, shared_secret(&eph_sk, &pk)?.as_bytes()); let ck = KDF1!(&ck, &shared_secret(&eph_sk, &pk)?);
// (C, tau, k) := Kdf3(C, Q) // (C, tau, k) := Kdf3(C, Q)
@@ -522,11 +534,11 @@ pub(super) fn consume_response<'a, O>(
// C := Kdf1(C, DH(E_priv, E_pub)) // C := Kdf1(C, DH(E_priv, E_pub))
let eph_r_pk = PublicKey::from(msg.f_ephemeral); let eph_r_pk = PublicKey::from(msg.f_ephemeral);
let ck = KDF1!(&ck, shared_secret(&eph_sk, &eph_r_pk)?.as_bytes()); let ck = KDF1!(&ck, &shared_secret(&eph_sk, &eph_r_pk)?);
// C := Kdf1(C, DH(E_priv, S_pub)) // C := Kdf1(C, DH(E_priv, S_pub))
let ck = KDF1!(&ck, shared_secret(&keyst.sk, &eph_r_pk)?.as_bytes()); let ck = KDF1!(&ck, &shared_secret(&keyst.sk, &eph_r_pk)?);
// (C, tau, k) := Kdf3(C, Q) // (C, tau, k) := Kdf3(C, Q)