From 60cc41f9e3d8558c2e45963acaaa2ba175c77337 Mon Sep 17 00:00:00 2001 From: Matt Johnston <matt@ucc.asn.au> Date: Sun, 11 Jun 2023 11:20:45 +0800 Subject: [PATCH] WIP dalek --- Cargo.toml | 8 +- embassy/demos/picow/Cargo.lock | 2 +- embassy/demos/std/Cargo.lock | 188 +++++++++++++++++++++++++++++---- src/kex.rs | 17 ++- 4 files changed, 186 insertions(+), 29 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 16ddef4..c146d9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,12 @@ cipher = { version = "0.4", features = ["zeroize"] } subtle = { version = "2.4", default-features = false } # ed25519/x25519 # fork allows hashing by parts (sign/verify from sshwire), and zeroize -salty = { version = "0.2", git = "https://github.com/mkj/salty", branch = "sunset" } +# salty = { version = "0.2", git = "https://github.com/mkj/salty", branch = "sunset" } +salty = { version = "0.2", path = "/home/matt/3rd/rs/salty" } +ed25519-dalek = { version = "1", default-features = false } +x25519-dalek = { version = "1", default-features = false } +curve25519-dalek = { version = "3", default-features = false, features = [ "u32_backend"]} + rsa = { version = "0.8", default-features = false, optional = true, features = ["sha2"] } # TODO: getrandom feature is a workaround for missing ssh-key dependency with rsa. fixed in pending 0.6 ssh-key = { version = "0.5", default-features = false, optional = true, features = ["getrandom"] } @@ -84,3 +89,4 @@ simplelog = { version = "0.12", features = ["test"] } [patch.crates-io] +curve25519-dalek = { path = "/home/matt/3rd/rs/crypto/curve25519-dalek" } diff --git a/embassy/demos/picow/Cargo.lock b/embassy/demos/picow/Cargo.lock index afd5804..42b0367 100644 --- a/embassy/demos/picow/Cargo.lock +++ b/embassy/demos/picow/Cargo.lock @@ -1551,8 +1551,8 @@ checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" [[package]] name = "salty" version = "0.2.0" -source = "git+https://github.com/mkj/salty?branch=sunset#24b9b1e3bb9cca873ed63ef379c552dbe55633e3" dependencies = [ + "defmt", "ed25519", "subtle", "zeroize", diff --git a/embassy/demos/std/Cargo.lock b/embassy/demos/std/Cargo.lock index a5e023f..76e991d 100644 --- a/embassy/demos/std/Cargo.lock +++ b/embassy/demos/std/Cargo.lock @@ -151,6 +151,15 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.6", +] + [[package]] name = "block-buffer" version = "0.10.3" @@ -262,6 +271,19 @@ dependencies = [ "cipher", ] +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + [[package]] name = "darling" version = "0.13.4" @@ -297,13 +319,54 @@ dependencies = [ "syn", ] +[[package]] +name = "defmt" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956673bd3cb347512bf988d1e8d89ac9a82b64f6eec54d3c01c3529dac019882" +dependencies = [ + "bitflags", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4abc4821bd84d3d8f49945ddb24d029be9385ed9b77c99bf2f6296847a6a9f0" +dependencies = [ + "defmt-parser", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "defmt-parser" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "269924c02afd7f94bc4cecbfa5c379f6ffcf9766b3408fe63d22c728654eccd0" +dependencies = [ + "thiserror", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.6", +] + [[package]] name = "digest" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "block-buffer", + "block-buffer 0.10.3", "crypto-common", "subtle", ] @@ -323,6 +386,18 @@ dependencies = [ "signature 1.6.4", ] +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "sha2 0.9.9", + "zeroize", +] + [[package]] name = "embassy-executor" version = "0.1.0" @@ -342,12 +417,12 @@ dependencies = [ [[package]] name = "embassy-futures" version = "0.1.0" -source = "git+https://github.com/embassy-rs/embassy?rev=3e730aa8b06401003202bf9e21a9c83ec6b21b0e#3e730aa8b06401003202bf9e21a9c83ec6b21b0e" +source = "git+https://github.com/embassy-rs/embassy?rev=1d34078fa11839f88dd2e47a9355c6b35755128f#1d34078fa11839f88dd2e47a9355c6b35755128f" [[package]] name = "embassy-hal-common" version = "0.1.0" -source = "git+https://github.com/embassy-rs/embassy?rev=3e730aa8b06401003202bf9e21a9c83ec6b21b0e#3e730aa8b06401003202bf9e21a9c83ec6b21b0e" +source = "git+https://github.com/embassy-rs/embassy?rev=1d34078fa11839f88dd2e47a9355c6b35755128f#1d34078fa11839f88dd2e47a9355c6b35755128f" dependencies = [ "num-traits", ] @@ -367,15 +442,15 @@ dependencies = [ [[package]] name = "embassy-net" version = "0.1.0" -source = "git+https://github.com/embassy-rs/embassy?rev=3e730aa8b06401003202bf9e21a9c83ec6b21b0e#3e730aa8b06401003202bf9e21a9c83ec6b21b0e" +source = "git+https://github.com/embassy-rs/embassy?rev=1d34078fa11839f88dd2e47a9355c6b35755128f#1d34078fa11839f88dd2e47a9355c6b35755128f" dependencies = [ "as-slice 0.2.1", "atomic-polyfill 1.0.1", "atomic-pool", "embassy-hal-common", "embassy-net-driver", - "embassy-sync 0.2.0 (git+https://github.com/embassy-rs/embassy?rev=3e730aa8b06401003202bf9e21a9c83ec6b21b0e)", - "embassy-time 0.1.1 (git+https://github.com/embassy-rs/embassy?rev=3e730aa8b06401003202bf9e21a9c83ec6b21b0e)", + "embassy-sync 0.2.0 (git+https://github.com/embassy-rs/embassy?rev=1d34078fa11839f88dd2e47a9355c6b35755128f)", + "embassy-time 0.1.1 (git+https://github.com/embassy-rs/embassy?rev=1d34078fa11839f88dd2e47a9355c6b35755128f)", "embedded-io", "embedded-nal-async", "futures", @@ -390,7 +465,7 @@ dependencies = [ [[package]] name = "embassy-net-driver" version = "0.1.0" -source = "git+https://github.com/embassy-rs/embassy?rev=3e730aa8b06401003202bf9e21a9c83ec6b21b0e#3e730aa8b06401003202bf9e21a9c83ec6b21b0e" +source = "git+https://github.com/embassy-rs/embassy?rev=1d34078fa11839f88dd2e47a9355c6b35755128f#1d34078fa11839f88dd2e47a9355c6b35755128f" [[package]] name = "embassy-sync" @@ -408,7 +483,7 @@ dependencies = [ [[package]] name = "embassy-sync" version = "0.2.0" -source = "git+https://github.com/embassy-rs/embassy?rev=3e730aa8b06401003202bf9e21a9c83ec6b21b0e#3e730aa8b06401003202bf9e21a9c83ec6b21b0e" +source = "git+https://github.com/embassy-rs/embassy?rev=1d34078fa11839f88dd2e47a9355c6b35755128f#1d34078fa11839f88dd2e47a9355c6b35755128f" dependencies = [ "cfg-if", "critical-section", @@ -435,7 +510,7 @@ dependencies = [ [[package]] name = "embassy-time" version = "0.1.1" -source = "git+https://github.com/embassy-rs/embassy?rev=3e730aa8b06401003202bf9e21a9c83ec6b21b0e#3e730aa8b06401003202bf9e21a9c83ec6b21b0e" +source = "git+https://github.com/embassy-rs/embassy?rev=1d34078fa11839f88dd2e47a9355c6b35755128f#1d34078fa11839f88dd2e47a9355c6b35755128f" dependencies = [ "atomic-polyfill 1.0.1", "cfg-if", @@ -688,7 +763,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.6", ] [[package]] @@ -849,6 +924,30 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6fa0831dd7cc608c38a5e323422a0077678fa5744aa2be4ad91c4ece8eec8d5" +[[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" @@ -873,9 +972,15 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "rand_core", + "rand_core 0.6.4", ] +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + [[package]] name = "rand_core" version = "0.6.4" @@ -914,8 +1019,8 @@ dependencies = [ [[package]] name = "salty" version = "0.2.0" -source = "git+https://github.com/mkj/salty?branch=sunset#24b9b1e3bb9cca873ed63ef379c552dbe55633e3" dependencies = [ + "defmt", "ed25519", "subtle", "zeroize", @@ -933,6 +1038,19 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + [[package]] name = "sha2" version = "0.10.6" @@ -941,7 +1059,7 @@ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.6", ] [[package]] @@ -1055,7 +1173,9 @@ dependencies = [ "chacha20", "cipher", "ctr", - "digest", + "curve25519-dalek", + "digest 0.10.6", + "ed25519-dalek", "embedded-io", "futures", "getrandom", @@ -1064,13 +1184,14 @@ dependencies = [ "log", "poly1305", "pretty-hex", - "rand_core", + "rand_core 0.6.4", "salty", - "sha2", + "sha2 0.10.6", "signature 2.0.0", "snafu", "subtle", "sunset-sshwire-derive", + "x25519-dalek", "zeroize", ] @@ -1089,7 +1210,7 @@ dependencies = [ "hmac", "log", "pretty-hex", - "sha2", + "sha2 0.10.6", "sunset", "sunset-embassy", "sunset-sshwire-derive", @@ -1114,7 +1235,7 @@ dependencies = [ "libc", "log", "rand", - "sha2", + "sha2 0.10.6", "static_cell", "sunset", "sunset-demo-embassy-common", @@ -1173,6 +1294,26 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "thiserror" +version = "1.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "typenum" version = "1.16.0" @@ -1328,6 +1469,17 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +[[package]] +name = "x25519-dalek" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" +dependencies = [ + "curve25519-dalek", + "rand_core 0.5.1", + "zeroize", +] + [[package]] name = "zeroize" version = "1.5.7" diff --git a/src/kex.rs b/src/kex.rs index 0918b84..9c49906 100644 --- a/src/kex.rs +++ b/src/kex.rs @@ -11,6 +11,7 @@ use core::fmt; use sha2::Sha256; use digest::Digest; use zeroize::{Zeroize, ZeroizeOnDrop}; +use rand_core::{RngCore, CryptoRng, OsRng}; use crate::*; use encrypt::{Cipher, Integ, Keys}; @@ -673,8 +674,8 @@ impl KexOutput { #[derive(ZeroizeOnDrop)] pub(crate) struct KexCurve25519 { // Initialised in `new()`, cleared after deriving the secret - ours: Option<salty::agreement::SecretKey>, - // TODO: it would be nice to avoid having to store this separately, but seems difficult + ours: Option<x25519_dalek::EphemeralSecret>, + // pubkey is relatively expensive to compute from the secret key pubkey: [u8; 32], } @@ -692,8 +693,8 @@ impl KexCurve25519 { let mut s = [0u8; 32]; random::fill_random(s.as_mut_slice())?; // TODO: check that pure random bytes are OK - let ours = salty::agreement::SecretKey::from_seed(&mut s); - let pubkey: salty::agreement::PublicKey = (&ours).into(); + let ours = x25519_dalek::EphemeralSecret::new(OsRng); + let pubkey = x25519_dalek::PublicKey::from(ours); let pubkey = pubkey.to_bytes(); Ok(KexCurve25519 { ours: Some(ours), pubkey }) } @@ -709,12 +710,10 @@ impl KexCurve25519 { } else { return Err(Error::bug()); }; - let ours = kex.ours.as_mut().trap()?; let theirs: [u8; 32] = theirs.try_into().map_err(|_| Error::BadKex)?; - let theirs = theirs.try_into().map_err(|_| Error::BadKex)?; - let shsec = ours.agree(&theirs); - kex.ours = None; - Ok(KexOutput::new(&shsec.to_bytes(), algos, kex_hash)) + let theirs = theirs.into(); + let shsec = kex.ours.take().trap()?.diffie_hellman(&theirs); + Ok(KexOutput::new(shsec.as_bytes(), algos, kex_hash)) } }