diff options
-rw-r--r-- | Cargo.lock | 155 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/handshake/macs.rs | 135 | ||||
-rw-r--r-- | src/handshake/noise.rs | 59 | ||||
-rw-r--r-- | src/main.rs | 7 |
5 files changed, 294 insertions, 64 deletions
@@ -1,6 +1,11 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] +name = "adler32" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "autocfg" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -37,6 +42,11 @@ version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "cfg-if" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "clear_on_drop" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -53,6 +63,14 @@ dependencies = [ ] [[package]] +name = "crc32fast" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "crypto-mac" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -82,13 +100,19 @@ dependencies = [ ] [[package]] -name = "fuchsia-cprng" -version = "0.1.1" +name = "filetime" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] -name = "gcc" -version = "0.3.55" +name = "fuchsia-cprng" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -119,45 +143,54 @@ version = "0.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "opaque-debug" -version = "0.2.2" +name = "libflate" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rle-decode-fast 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] -name = "proc-macro2" -version = "0.4.30" +name = "libsodium-sys" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", + "libflate 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "quote" -version = "0.6.13" +name = "opaque-debug" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] -name = "rand" -version = "0.3.23" +name = "pkg-config" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "proc-macro2" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "rand" -version = "0.4.6" +name = "quote" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -270,21 +303,24 @@ version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "rust-crypto" -version = "0.2.36" +name = "rle-decode-fast" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] -name = "rustc-serialize" -version = "0.3.24" +name = "sodiumoxide" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", + "libsodium-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "spin" @@ -323,13 +359,19 @@ dependencies = [ ] [[package]] -name = "time" -version = "0.1.42" +name = "take_mut" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "tar" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "filetime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -343,6 +385,11 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "vcpkg" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "winapi" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -372,7 +419,7 @@ dependencies = [ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "sodiumoxide 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "x25519-dalek 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -390,6 +437,14 @@ dependencies = [ ] [[package]] +name = "xattr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "zerocopy" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -409,28 +464,32 @@ dependencies = [ ] [metadata] +"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" "checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf" "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" "checksum blake2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91721a6330935673395a0607df4d49a9cb90ae12d259f1b3e0a3f6e1d486872e" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" "checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2" +"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" "checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" "checksum curve25519-dalek 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e1f8a6fc0376eb52dc18af94915cc04dfdf8353746c0e8c550ae683a0815e5c1" "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" +"checksum filetime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "450537dc346f0c4d738dda31e790da1da5d4bd12145aad4da0d03d713cb3794f" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" "checksum libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)" = "3262021842bf00fe07dbd6cf34ff25c99d7a7ebef8deea84db72be3ea3bb0aff" +"checksum libflate 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "90c6f86f4b0caa347206f916f8b687b51d77c6ef8ff18d52dd007491fd580529" +"checksum libsodium-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "de29595a79ddae2612ad0f27793a0b86cdf05a12f94ad5b87674540cc568171e" "checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409" +"checksum pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c1d2cfa5a714db3b5f24f0915e74fcdf91d09d496ba61329705dda7774d2af" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" -"checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" -"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" @@ -443,19 +502,23 @@ dependencies = [ "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +"checksum rle-decode-fast 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" +"checksum serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5626ac617da2f2d9c48af5515a21d5a480dbd151e01bb1c355e26a3e68113" +"checksum sodiumoxide 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31532969f87f66ea5667b203fdee70aec8ddbe25aac69d243daff58c01688152" "checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" "checksum subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01dca13cf6c3b179864ab3292bd794e757618d35a7766b7c46050c614ba00829" "checksum syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)" = "eadc09306ca51a40555dd6fc2b415538e9e18bc9f870e47b1a524a79fe2dcf5e" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" -"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" +"checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" +"checksum tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)" = "b3196bfbffbba3e57481b6ea32249fbaf590396a52505a2615adbb79d9d826d3" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95" "checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum x25519-dalek 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4aca1ba6bec2719576bd20dfe5b24d9359552e616d10bff257e50cd85f745d17" +"checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" "checksum zerocopy 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "56ae60eda58b25c5c4f5398e2144f72dc1881e50142e232b64e1ba8664d1ce38" "checksum zerocopy-derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "746f425452bf1e4b74c78d594d5c6f51f8c978e57ba5c236a04ba1aecfc384a7" @@ -11,11 +11,11 @@ spin = "0.5.0" rand = "0.6.5" blake2 = "0.8.0" hmac = "0.7.1" -rust-crypto = "^0.2" generic-array = "0.12.3" zerocopy = "0.2.7" byteorder = "1.3.1" digest = "0.8.0" +sodiumoxide = "0.2.2" [dependencies.x25519-dalek] version = "^0.5" diff --git a/src/handshake/macs.rs b/src/handshake/macs.rs index 99c83ac..36ae1b8 100644 --- a/src/handshake/macs.rs +++ b/src/handshake/macs.rs @@ -1,9 +1,17 @@ use std::time::{Duration, Instant}; +use rand::rngs::OsRng; +use rand::CryptoRng; +use rand::RngCore; + +use spin::Mutex; + use blake2::Blake2s; use subtle::ConstantTimeEq; use x25519_dalek::PublicKey; +use sodiumoxide::crypto::aead::xchacha20poly1305_ietf; + use super::messages::{CookieReply, MacsFooter}; use super::types::HandshakeError; @@ -11,6 +19,7 @@ const LABEL_MAC1: &[u8] = b"mac1----"; const LABEL_COOKIE: &[u8] = b"cookie--"; const SIZE_COOKIE: usize = 16; +const SIZE_SECRET: usize = 32; const SIZE_MAC: usize = 16; // blake2s-mac128 const SECS_COOKIE_UPDATE: u64 = 120; @@ -41,6 +50,45 @@ macro_rules! MAC { }}; } +macro_rules! XSEAL { + ($key:expr, $nonce:expr, $ad:expr, $pt:expr, $ct:expr, $tag:expr) => {{ + let s_key = xchacha20poly1305_ietf::Key::from_slice($key).unwrap(); + let s_nonce = xchacha20poly1305_ietf::Nonce::from_slice($nonce).unwrap(); + + debug_assert_eq!($tag.len(), 16); + debug_assert_eq!($pt.len(), $ct.len()); + + $ct.copy_from_slice($pt); + let tag = xchacha20poly1305_ietf::seal_detached( + $ct, + if $ad.len() == 0 { None } else { Some($ad) }, + &s_nonce, + &s_key, + ); + $tag.copy_from_slice(tag.as_ref()); + }}; +} + +macro_rules! XOPEN { + ($key:expr, $nonce:expr, $ad:expr, $pt:expr, $ct:expr, $tag:expr) => {{ + let s_key = xchacha20poly1305_ietf::Key::from_slice($key).unwrap(); + let s_nonce = xchacha20poly1305_ietf::Nonce::from_slice($nonce).unwrap(); + let s_tag = xchacha20poly1305_ietf::Tag::from_slice($tag).unwrap(); + + debug_assert_eq!($pt.len(), $ct.len()); + + $pt.copy_from_slice($ct); + xchacha20poly1305_ietf::open_detached( + $pt, + if $ad.len() == 0 { None } else { Some($ad) }, + &s_tag, + &s_nonce, + &s_key, + ) + .map_err(|_| HandshakeError::DecryptionFailure) + }}; +} + struct Cookie { value: [u8; 16], birth: Instant, @@ -48,6 +96,7 @@ struct Cookie { pub struct Generator { mac1_key: [u8; 32], + cookie_key: [u8; 32], // xchacha20poly key for opening cookie response last_mac1: Option<[u8; 16]>, cookie: Option<Cookie>, } @@ -65,6 +114,7 @@ impl Generator { pub fn new(pk: PublicKey) -> Generator { Generator { mac1_key: HASH!(LABEL_MAC1, pk.as_bytes()).into(), + cookie_key: HASH!(LABEL_COOKIE, pk.as_bytes()).into(), last_mac1: None, cookie: None, } @@ -81,10 +131,19 @@ impl Generator { /// Can fail if the cookie reply fails to validate /// (either indicating that it is outdated or malformed) pub fn process(&mut self, reply: &CookieReply) -> Result<(), HandshakeError> { - unimplemented!("do the checks and decryption"); + let mac1 = self.last_mac1.ok_or(HandshakeError::InvalidState)?; + let mut tau = [0u8; SIZE_COOKIE]; + XOPEN!( + &self.cookie_key, // key + &reply.f_nonce, // nonce + &mac1, // ad + &mut tau, // pt + &reply.f_cookie, // ct + &reply.f_cookie_tag // tag + )?; self.cookie = Some(Cookie { birth: Instant::now(), - value: reply.f_cookie, + value: tau, }); Ok(()) } @@ -112,17 +171,68 @@ impl Generator { } } +struct Secret { + value: [u8; 32], + birth: Instant, +} + pub struct Validator { mac1_key: [u8; 32], + cookie_key: [u8; 32], // xchacha20poly key for sealing cookie response + secret: Mutex<Secret>, } impl Validator { pub fn new(pk: PublicKey) -> Validator { Validator { mac1_key: HASH!(LABEL_MAC1, pk.as_bytes()).into(), + cookie_key: HASH!(LABEL_COOKIE, pk.as_bytes()).into(), + secret: Mutex::new(Secret { + value: [0u8; SIZE_SECRET], + birth: Instant::now() - Duration::from_secs(2 * SECS_COOKIE_UPDATE), + }), } } + fn get_tau<T>(&self, rng: &mut T, addr: &[u8]) -> [u8; SIZE_COOKIE] + where + T: RngCore + CryptoRng, + { + let mut secret = self.secret.lock(); + + // check if current value is still valid + if secret.birth.elapsed() < Duration::from_secs(SECS_COOKIE_UPDATE) { + return MAC!(&secret.value, addr); + }; + + // generate new value + rng.fill_bytes(&mut secret.value); + secret.birth = Instant::now(); + MAC!(&secret.value, addr) + } + + fn create_cookie_reply<T>( + &mut self, + rng: &mut T, + receiver: u32, // receiver id of incoming message + src: &[u8], // source address of incoming message + macs: &MacsFooter, // footer of incoming message + msg: &mut CookieReply, // resulting cookie reply + ) where + T: RngCore + CryptoRng, + { + msg.f_receiver.set(receiver); + rng.fill_bytes(&mut msg.f_nonce); + XSEAL!( + &self.cookie_key, // key + &msg.f_nonce, // nonce + &macs.f_mac1, // ad + &self.get_tau(rng, src), // pt + &mut msg.f_cookie, // ct + &mut msg.f_cookie_tag // tag + ); + } + /// Check the mac1 field against the inner message /// /// # Arguments @@ -137,6 +247,27 @@ impl Validator { Ok(()) } } + + /// Check the mac2 field against the inner message + /// + /// # Arguments + /// + /// - inner: The inner message covered by the mac1 field + /// - src: Source address + /// - macs: The mac footer + pub fn check_mac2( + &self, + inner: &[u8], + src: &[u8], + macs: &MacsFooter, + ) -> Result<(), HandshakeError> { + let valid_mac1: bool = MAC!(&self.mac1_key, inner).ct_eq(&macs.f_mac1).into(); + if !valid_mac1 { + Err(HandshakeError::InvalidMac1) + } else { + Ok(()) + } + } } #[cfg(test)] diff --git a/src/handshake/noise.rs b/src/handshake/noise.rs index b0d492c..cf5238c 100644 --- a/src/handshake/noise.rs +++ b/src/handshake/noise.rs @@ -6,9 +6,8 @@ use x25519_dalek::StaticSecret; use blake2::Blake2s; use hmac::Hmac; -// AEAD -use crypto::aead::{AeadDecryptor, AeadEncryptor}; -use crypto::chacha20poly1305::ChaCha20Poly1305; +// AEAD (from libsodium) +use sodiumoxide::crypto::aead::chacha20poly1305; use rand::rngs::OsRng; @@ -99,20 +98,52 @@ macro_rules! KDF3 { } macro_rules! SEAL { - ($key:expr, $aead:expr, $pt:expr, $ct:expr, $tag:expr) => {{ - let mut aead = ChaCha20Poly1305::new($key, &ZERO_NONCE, $aead); - aead.encrypt($pt, $ct, $tag); + ($key:expr, $ad:expr, $pt:expr, $ct:expr, $tag:expr) => {{ + // create annoying nonce and key objects + let s_nonce = chacha20poly1305::Nonce::from_slice(&ZERO_NONCE).unwrap(); + let s_key = chacha20poly1305::Key::from_slice($key).unwrap(); + + // type annontate the ct and pt arguments + let pt: &[u8] = $pt; + let ct: &mut [u8] = $ct; + + // basic sanity checks + debug_assert_eq!(pt.len(), ct.len()); + debug_assert_eq!($tag.len(), chacha20poly1305::TAGBYTES); + + // encrypt + ct.copy_from_slice(pt); + let tag = chacha20poly1305::seal_detached( + ct, + if $ad.len() == 0 { None } else { Some($ad) }, + &s_nonce, + &s_key, + ); + $tag.copy_from_slice(tag.as_ref()); }}; } macro_rules! OPEN { - ($key:expr, $aead:expr, $pt:expr, $ct:expr, $tag:expr) => {{ - let mut aead = ChaCha20Poly1305::new($key, &ZERO_NONCE, $aead); - if !aead.decrypt($ct, $pt, $tag) { - Err(HandshakeError::DecryptionFailure) - } else { - Ok(()) - } + ($key:expr, $ad:expr, $pt:expr, $ct:expr, $tag:expr) => {{ + // create annoying nonce and key objects + let s_nonce = chacha20poly1305::Nonce::from_slice(&ZERO_NONCE).unwrap(); + let s_key = chacha20poly1305::Key::from_slice($key).unwrap(); + let s_tag = chacha20poly1305::Tag::from_slice($tag).unwrap(); + + // type annontate the ct and pt arguments + let pt: &mut [u8] = $pt; + let ct: &[u8] = $ct; + + // decrypt + pt.copy_from_slice(ct); + chacha20poly1305::open_detached( + pt, + if $ad.len() == 0 { None } else { Some($ad) }, + &s_tag, + &s_nonce, + &s_key, + ) + .map_err(|_| HandshakeError::DecryptionFailure) }}; } @@ -293,7 +324,7 @@ pub fn create_response<T: Copy>( ) -> Result<KeyPair, HandshakeError> { let mut rng = OsRng::new().unwrap(); let (receiver, eph_r_pk, hs, ck) = state; - + let mut rng = OsRng::new().unwrap(); msg.f_sender.set(sender); msg.f_receiver.set(receiver); diff --git a/src/main.rs b/src/main.rs index f408d49..26974a7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,12 @@ mod handshake; mod types; +use sodiumoxide; + use handshake::Device; use types::KeyPair; -fn main() {} +fn main() { + // choose optimal crypto implementations for platform + sodiumoxide::init().unwrap(); +} |