From b6203683fc968ad47de6839221fa862feca72f95 Mon Sep 17 00:00:00 2001 From: Karolin Varner Date: Sat, 20 Jan 2024 13:08:18 +0100 Subject: [PATCH] feat: Migrate away from sodium blake2b towards the rust crypto implementation --- Cargo.lock | 30 ++++++++++++++ Cargo.toml | 1 + ciphers/Cargo.toml | 1 + ciphers/src/subtle/blake2b.rs | 42 ++++++++++++++++++++ ciphers/src/subtle/incorrect_hmac_blake2b.rs | 8 ++-- ciphers/src/subtle/mod.rs | 1 + 6 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 ciphers/src/subtle/blake2b.rs diff --git a/Cargo.lock b/Cargo.lock index 83d6c72..48b8cd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -224,6 +224,24 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "build-deps" version = "0.1.4" @@ -554,6 +572,17 @@ dependencies = [ "syn", ] +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + [[package]] name = "doc-comment" version = "0.3.3" @@ -1305,6 +1334,7 @@ name = "rosenpass-ciphers" version = "0.1.0" dependencies = [ "anyhow", + "blake2", "chacha20poly1305", "rosenpass-constant-time", "rosenpass-oqs", diff --git a/Cargo.toml b/Cargo.toml index 0f7e311..7bb09ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,4 +60,5 @@ anyhow = { version = "1.0.75", features = ["backtrace", "std"] } mio = { version = "0.8.9", features = ["net", "os-poll"] } libsodium-sys-stable= { version = "1.20.4", features = ["use-pkg-config"] } oqs-sys = { version = "0.8", default-features = false, features = ['classic_mceliece', 'kyber'] } +blake2 = "0.10.6" chacha20poly1305 = { version = "0.10.1", default-features = false, features = [ "std", "heapless" ] } diff --git a/ciphers/Cargo.toml b/ciphers/Cargo.toml index 3589ce4..f7abd52 100644 --- a/ciphers/Cargo.toml +++ b/ciphers/Cargo.toml @@ -20,3 +20,4 @@ rosenpass-util = { workspace = true } static_assertions = { workspace = true } zeroize = { workspace = true } chacha20poly1305 = { workspace = true } +blake2 = { workspace = true } diff --git a/ciphers/src/subtle/blake2b.rs b/ciphers/src/subtle/blake2b.rs new file mode 100644 index 0000000..38f9497 --- /dev/null +++ b/ciphers/src/subtle/blake2b.rs @@ -0,0 +1,42 @@ +use zeroize::Zeroizing; + +use blake2::Blake2bMac; +use blake2::digest::{OutputSizeUser, Mac, FixedOutput}; +use blake2::digest::crypto_common::KeySizeUser; +use blake2::digest::crypto_common::generic_array::GenericArray; +use blake2::digest::crypto_common::typenum::U32; + +use rosenpass_to::{with_destination, To, ops::copy_slice}; +use rosenpass_util::typenum2const; + +type Impl = Blake2bMac; + +type KeyLen = ::KeySize; +type OutLen = ::OutputSize; + +const KEY_LEN : usize = typenum2const! { KeyLen }; +const OUT_LEN : usize = typenum2const! { OutLen }; + +pub const KEY_MIN: usize = KEY_LEN; +pub const KEY_MAX: usize = KEY_LEN; +pub const OUT_MIN: usize = OUT_LEN; +pub const OUT_MAX: usize = OUT_LEN; + +#[inline] +pub fn hash<'a>(key: &'a [u8], data: &'a [u8]) -> impl To<[u8], anyhow::Result<()>> + 'a { + with_destination(|out: &mut [u8]| { + let mut h = Impl::new_from_slice(key)?; + h.update(data); + + // Jesus christ, blake2 crate, your usage of GenericArray might be nice and fancy + // but it introduces a ton of complexity. This cost me half an hour just to figure + // out the right way to use the imports while allowing for zeroization. + // An API based on slices might actually be simpler. + let mut tmp = Zeroizing::new([0u8; OUT_LEN]); + let mut tmp = GenericArray::from_mut_slice(tmp.as_mut()); + h.finalize_into(&mut tmp); + copy_slice(tmp.as_ref()).to(out); + + Ok(()) + }) +} diff --git a/ciphers/src/subtle/incorrect_hmac_blake2b.rs b/ciphers/src/subtle/incorrect_hmac_blake2b.rs index 802859a..a558be3 100644 --- a/ciphers/src/subtle/incorrect_hmac_blake2b.rs +++ b/ciphers/src/subtle/incorrect_hmac_blake2b.rs @@ -1,9 +1,11 @@ use anyhow::ensure; -use rosenpass_constant_time::xor; -use rosenpass_sodium::hash::blake2b; -use rosenpass_to::{ops::copy_slice, with_destination, To}; use zeroize::Zeroizing; +use rosenpass_constant_time::xor; +use rosenpass_to::{ops::copy_slice, with_destination, To}; + +use crate::subtle::blake2b; + pub const KEY_LEN: usize = 32; pub const KEY_MIN: usize = KEY_LEN; pub const KEY_MAX: usize = KEY_LEN; diff --git a/ciphers/src/subtle/mod.rs b/ciphers/src/subtle/mod.rs index 782272b..b6cbe5f 100644 --- a/ciphers/src/subtle/mod.rs +++ b/ciphers/src/subtle/mod.rs @@ -1,3 +1,4 @@ pub mod incorrect_hmac_blake2b; pub mod chacha20poly1305_ietf; pub mod xchacha20poly1305_ietf; +pub mod blake2b;