From b573a58ad8ffbe7f41a04435a8321a62502bfc41 Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Mon, 10 Jun 2024 16:04:41 +0200 Subject: [PATCH 1/6] Pull out `libcrux::hkdf` module into its own crate --- Cargo.toml | 1 + libcrux-hkdf/Cargo.toml | 16 ++++ libcrux-hkdf/src/hacl_hkdf.rs | 137 ++++++++++++++++++++++++++++++++++ libcrux-hkdf/src/hkdf.rs | 75 +++++++++++++++++++ 4 files changed, 229 insertions(+) create mode 100644 libcrux-hkdf/Cargo.toml create mode 100644 libcrux-hkdf/src/hacl_hkdf.rs create mode 100644 libcrux-hkdf/src/hkdf.rs diff --git a/Cargo.toml b/Cargo.toml index 4505f7d11..ae5490f8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ members = [ "libcrux-sha3", "libcrux-ml-dsa", "libcrux-intrinsics", + "libcrux-hkdf", ] [workspace.package] diff --git a/libcrux-hkdf/Cargo.toml b/libcrux-hkdf/Cargo.toml new file mode 100644 index 000000000..65de2d0ca --- /dev/null +++ b/libcrux-hkdf/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "libcrux-hkdf" +version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +edition.workspace = true +repository.workspace = true +readme.workspace = true + +[lib] +path = "src/hkdf.rs" + +[dependencies] +libcrux-hacl = { version = "=0.0.2-pre.2", path = "../sys/hacl" } + diff --git a/libcrux-hkdf/src/hacl_hkdf.rs b/libcrux-hkdf/src/hacl_hkdf.rs new file mode 100644 index 000000000..346060e04 --- /dev/null +++ b/libcrux-hkdf/src/hacl_hkdf.rs @@ -0,0 +1,137 @@ +#![allow(dead_code)] + +/// HKDF Errors. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Error { + /// The requested output key material in expand was too large for the used + /// hash function. + OkmTooLarge, + /// At least one function argument has been too large to process. + ArgumentsTooLarge, +} + +macro_rules! impl_hkdf { + ($name:ident,$extract:ident,$expand:ident,$tag_len:literal) => { + pub mod $name { + use super::Error; + + /// HKDF extract using the `salt`, and the input key material `ikm`. + /// Returns the pre-key material in an array of tag length. + /// + /// Note that this function panics if `salt` or `ikm` is larger than 2**32 bytes. + pub fn extract(salt: &[u8], ikm: &[u8]) -> [u8; $tag_len] { + let mut prk = [0u8; $tag_len]; + unsafe { + libcrux_hacl::$extract( + prk.as_mut_ptr(), + salt.as_ptr() as _, + salt.len().try_into().unwrap(), + ikm.as_ptr() as _, + ikm.len().try_into().unwrap(), + ); + } + prk + } + + /// HKDF expand using the pre-key material `prk` and `info`. The output length + /// is defined through the result type. + /// Returns the key material in an array of length `okm_len` or + /// [`Error::OkmTooLarge`] if the requested `okm_len` is too large. + /// + /// Note that this function returns an [`Error::ArgumentsTooLarge`] + /// if `salt`, `ikm`, or `OKM_LEN` is larger than 2**32 bytes. + pub fn expand( + prk: &[u8], + info: &[u8], + ) -> Result<[u8; OKM_LEN], Error> { + if OKM_LEN > 255 * $tag_len { + // Output size is too large. HACL doesn't catch this. + return Err(Error::OkmTooLarge); + } + let mut okm = [0u8; OKM_LEN]; + unsafe { + libcrux_hacl::$expand( + okm.as_mut_ptr(), + prk.as_ptr() as _, + prk.len().try_into().map_err(|_| Error::ArgumentsTooLarge)?, + info.as_ptr() as _, + info.len() + .try_into() + .map_err(|_| Error::ArgumentsTooLarge)?, + OKM_LEN.try_into().map_err(|_| Error::ArgumentsTooLarge)?, + ); + } + Ok(okm) + } + + /// HKDF using the `salt`, input key material `ikm`, `info`. The output length + /// is defined through the result type. + /// Calls `extract` and `expand` with the given input. + /// + /// Returns the key material in an array of length `okm_len`. + pub fn hkdf( + salt: &[u8], + ikm: &[u8], + info: &[u8], + ) -> Result<[u8; OKM_LEN], Error> { + let prk = extract(salt, ikm); + expand(&prk, info) + } + + /// This module uses heap allocated vectors for cases where the output + /// length is not const. + pub mod vec { + use super::super::Error; + + /// HKDF expand using the pre-key material `prk` and `info`. The output length + /// is defined through the result type. + /// Returns the key material in an array of length `okm_len` or + /// [`Error::OkmTooLarge`] if the requested `okm_len` is too large. + /// + /// Note that this function returns an [`Error::ArgumentsTooLarge`] + /// if `salt`, `ikm`, or `OKM_LEN` is larger than 2**32 bytes. + pub fn expand(prk: &[u8], info: &[u8], okm_len: usize) -> Result, Error> { + if okm_len > 255 * $tag_len { + // Output size is too large. HACL doesn't catch this. + return Err(Error::OkmTooLarge); + } + let mut okm = vec![0u8; okm_len]; + unsafe { + libcrux_hacl::$expand( + okm.as_mut_ptr(), + prk.as_ptr() as _, + prk.len().try_into().map_err(|_| Error::ArgumentsTooLarge)?, + info.as_ptr() as _, + info.len() + .try_into() + .map_err(|_| Error::ArgumentsTooLarge)?, + okm_len.try_into().map_err(|_| Error::ArgumentsTooLarge)?, + ); + } + Ok(okm) + } + } + } + }; +} + +impl_hkdf!( + sha2_256, + Hacl_HKDF_extract_sha2_256, + Hacl_HKDF_expand_sha2_256, + 32 +); + +impl_hkdf!( + sha2_384, + Hacl_HKDF_extract_sha2_384, + Hacl_HKDF_expand_sha2_384, + 48 +); + +impl_hkdf!( + sha2_512, + Hacl_HKDF_extract_sha2_512, + Hacl_HKDF_expand_sha2_512, + 64 +); diff --git a/libcrux-hkdf/src/hkdf.rs b/libcrux-hkdf/src/hkdf.rs new file mode 100644 index 000000000..c3a9036fe --- /dev/null +++ b/libcrux-hkdf/src/hkdf.rs @@ -0,0 +1,75 @@ +//! HKDF +//! +//! This crate implements HKDF on SHA 1 and SHA 2 (except for SHA 224). + +pub(crate) mod hacl_hkdf; + +/// The HKDF algorithm defining the used hash function. +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum Algorithm { + Sha256, + Sha384, + Sha512, +} + +/// HKDF Errors +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Error { + OkmLengthTooLarge, +} + +/// HKDF extract using hash function `mode`, `salt`, and the input key material `ikm`. +/// Returns the pre-key material in a vector of tag length. +pub fn extract(alg: Algorithm, salt: impl AsRef<[u8]>, ikm: impl AsRef<[u8]>) -> Vec { + match alg { + Algorithm::Sha256 => { + crate::hacl_hkdf::sha2_256::extract(salt.as_ref(), ikm.as_ref()).into() + } + Algorithm::Sha384 => { + crate::hacl_hkdf::sha2_384::extract(salt.as_ref(), ikm.as_ref()).into() + } + Algorithm::Sha512 => { + crate::hacl_hkdf::sha2_512::extract(salt.as_ref(), ikm.as_ref()).into() + } + } +} + +/// HKDF expand using hash function `mode`, pre-key material `prk`, `info`, and output length `okm_len`. +/// Returns the key material in a vector of length `okm_len` or [`Error::OkmLengthTooLarge`] +/// if the requested output length is too large. +pub fn expand( + alg: Algorithm, + prk: impl AsRef<[u8]>, + info: impl AsRef<[u8]>, + okm_len: usize, +) -> Result, Error> { + match alg { + Algorithm::Sha256 => { + crate::hacl_hkdf::sha2_256::vec::expand(prk.as_ref(), info.as_ref(), okm_len) + .map_err(|_| Error::OkmLengthTooLarge) + } + Algorithm::Sha384 => { + crate::hacl_hkdf::sha2_384::vec::expand(prk.as_ref(), info.as_ref(), okm_len) + .map_err(|_| Error::OkmLengthTooLarge) + } + Algorithm::Sha512 => { + crate::hacl_hkdf::sha2_512::vec::expand(prk.as_ref(), info.as_ref(), okm_len) + .map_err(|_| Error::OkmLengthTooLarge) + } + } +} + +/// HKDF using hash function `mode`, `salt`, input key material `ikm`, `info`, and output length `okm_len`. +/// Calls `extract` and `expand` with the given input. +/// Returns the key material in a vector of length `okm_len` or [`Error::OkmLengthTooLarge`] +/// if the requested output length is too large. +pub fn hkdf( + mode: Algorithm, + salt: &[u8], + ikm: &[u8], + info: &[u8], + okm_len: usize, +) -> Result, Error> { + let prk = extract(mode, salt, ikm); + expand(mode, prk, info, okm_len) +} From c4aff0770029ded67fd0f83d04660ad74736f143 Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Mon, 10 Jun 2024 16:05:27 +0200 Subject: [PATCH 2/6] Re-export `libcrux-hkdf` crate API in `libcrux` --- Cargo.toml | 1 + src/hacl.rs | 8 --- src/hacl/hkdf.rs | 137 ----------------------------------------------- src/hkdf.rs | 74 ++----------------------- 4 files changed, 6 insertions(+), 214 deletions(-) delete mode 100644 src/hacl/hkdf.rs diff --git a/Cargo.toml b/Cargo.toml index ae5490f8e..fdf5c3597 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,7 @@ libcrux-platform = { version = "=0.0.2-pre.2", path = "sys/platform" } [dependencies] libcrux-hacl = { version = "=0.0.2-pre.2", path = "sys/hacl" } libcrux-platform = { version = "=0.0.2-pre.2", path = "sys/platform" } +libcrux-hkdf = { version = "=0.0.2-pre.2", path = "libcrux-hkdf" } rand = { version = "0.8" } log = { version = "0.4", optional = true } # WASM API diff --git a/src/hacl.rs b/src/hacl.rs index c3f315684..df1f748c9 100644 --- a/src/hacl.rs +++ b/src/hacl.rs @@ -16,7 +16,6 @@ pub(crate) mod curve25519; #[cfg(not(target_arch = "wasm32"))] pub(crate) mod drbg; pub(crate) mod ed25519; -pub(crate) mod hkdf; pub(crate) mod hmac; pub(crate) mod p256; pub(crate) mod sha2; @@ -29,7 +28,6 @@ pub enum Error { Curve25519(curve25519::Error), P256(p256::Error), Ed25519(ed25519::Error), - Hkdf(hkdf::Error), } impl From for Error { @@ -50,12 +48,6 @@ impl From for Error { } } -impl From for Error { - fn from(val: hkdf::Error) -> Self { - Error::Hkdf(val) - } -} - impl From for Error { fn from(val: ed25519::Error) -> Self { Error::Ed25519(val) diff --git a/src/hacl/hkdf.rs b/src/hacl/hkdf.rs deleted file mode 100644 index 346060e04..000000000 --- a/src/hacl/hkdf.rs +++ /dev/null @@ -1,137 +0,0 @@ -#![allow(dead_code)] - -/// HKDF Errors. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Error { - /// The requested output key material in expand was too large for the used - /// hash function. - OkmTooLarge, - /// At least one function argument has been too large to process. - ArgumentsTooLarge, -} - -macro_rules! impl_hkdf { - ($name:ident,$extract:ident,$expand:ident,$tag_len:literal) => { - pub mod $name { - use super::Error; - - /// HKDF extract using the `salt`, and the input key material `ikm`. - /// Returns the pre-key material in an array of tag length. - /// - /// Note that this function panics if `salt` or `ikm` is larger than 2**32 bytes. - pub fn extract(salt: &[u8], ikm: &[u8]) -> [u8; $tag_len] { - let mut prk = [0u8; $tag_len]; - unsafe { - libcrux_hacl::$extract( - prk.as_mut_ptr(), - salt.as_ptr() as _, - salt.len().try_into().unwrap(), - ikm.as_ptr() as _, - ikm.len().try_into().unwrap(), - ); - } - prk - } - - /// HKDF expand using the pre-key material `prk` and `info`. The output length - /// is defined through the result type. - /// Returns the key material in an array of length `okm_len` or - /// [`Error::OkmTooLarge`] if the requested `okm_len` is too large. - /// - /// Note that this function returns an [`Error::ArgumentsTooLarge`] - /// if `salt`, `ikm`, or `OKM_LEN` is larger than 2**32 bytes. - pub fn expand( - prk: &[u8], - info: &[u8], - ) -> Result<[u8; OKM_LEN], Error> { - if OKM_LEN > 255 * $tag_len { - // Output size is too large. HACL doesn't catch this. - return Err(Error::OkmTooLarge); - } - let mut okm = [0u8; OKM_LEN]; - unsafe { - libcrux_hacl::$expand( - okm.as_mut_ptr(), - prk.as_ptr() as _, - prk.len().try_into().map_err(|_| Error::ArgumentsTooLarge)?, - info.as_ptr() as _, - info.len() - .try_into() - .map_err(|_| Error::ArgumentsTooLarge)?, - OKM_LEN.try_into().map_err(|_| Error::ArgumentsTooLarge)?, - ); - } - Ok(okm) - } - - /// HKDF using the `salt`, input key material `ikm`, `info`. The output length - /// is defined through the result type. - /// Calls `extract` and `expand` with the given input. - /// - /// Returns the key material in an array of length `okm_len`. - pub fn hkdf( - salt: &[u8], - ikm: &[u8], - info: &[u8], - ) -> Result<[u8; OKM_LEN], Error> { - let prk = extract(salt, ikm); - expand(&prk, info) - } - - /// This module uses heap allocated vectors for cases where the output - /// length is not const. - pub mod vec { - use super::super::Error; - - /// HKDF expand using the pre-key material `prk` and `info`. The output length - /// is defined through the result type. - /// Returns the key material in an array of length `okm_len` or - /// [`Error::OkmTooLarge`] if the requested `okm_len` is too large. - /// - /// Note that this function returns an [`Error::ArgumentsTooLarge`] - /// if `salt`, `ikm`, or `OKM_LEN` is larger than 2**32 bytes. - pub fn expand(prk: &[u8], info: &[u8], okm_len: usize) -> Result, Error> { - if okm_len > 255 * $tag_len { - // Output size is too large. HACL doesn't catch this. - return Err(Error::OkmTooLarge); - } - let mut okm = vec![0u8; okm_len]; - unsafe { - libcrux_hacl::$expand( - okm.as_mut_ptr(), - prk.as_ptr() as _, - prk.len().try_into().map_err(|_| Error::ArgumentsTooLarge)?, - info.as_ptr() as _, - info.len() - .try_into() - .map_err(|_| Error::ArgumentsTooLarge)?, - okm_len.try_into().map_err(|_| Error::ArgumentsTooLarge)?, - ); - } - Ok(okm) - } - } - } - }; -} - -impl_hkdf!( - sha2_256, - Hacl_HKDF_extract_sha2_256, - Hacl_HKDF_expand_sha2_256, - 32 -); - -impl_hkdf!( - sha2_384, - Hacl_HKDF_extract_sha2_384, - Hacl_HKDF_expand_sha2_384, - 48 -); - -impl_hkdf!( - sha2_512, - Hacl_HKDF_extract_sha2_512, - Hacl_HKDF_expand_sha2_512, - 64 -); diff --git a/src/hkdf.rs b/src/hkdf.rs index 7093bf19f..c23d89cd8 100644 --- a/src/hkdf.rs +++ b/src/hkdf.rs @@ -2,72 +2,8 @@ //! //! This module implements HKDF on SHA 1 and SHA 2 (except for SHA 224). -/// The HKDF algorithm defining the used hash function. -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum Algorithm { - Sha256, - Sha384, - Sha512, -} - -/// HKDF Errors -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Error { - OkmLengthTooLarge, -} - -/// HKDF extract using hash function `mode`, `salt`, and the input key material `ikm`. -/// Returns the pre-key material in a vector of tag length. -pub fn extract(alg: Algorithm, salt: impl AsRef<[u8]>, ikm: impl AsRef<[u8]>) -> Vec { - match alg { - Algorithm::Sha256 => { - crate::hacl::hkdf::sha2_256::extract(salt.as_ref(), ikm.as_ref()).into() - } - Algorithm::Sha384 => { - crate::hacl::hkdf::sha2_384::extract(salt.as_ref(), ikm.as_ref()).into() - } - Algorithm::Sha512 => { - crate::hacl::hkdf::sha2_512::extract(salt.as_ref(), ikm.as_ref()).into() - } - } -} - -/// HKDF expand using hash function `mode`, pre-key material `prk`, `info`, and output length `okm_len`. -/// Returns the key material in a vector of length `okm_len` or [`Error::OkmLengthTooLarge`] -/// if the requested output length is too large. -pub fn expand( - alg: Algorithm, - prk: impl AsRef<[u8]>, - info: impl AsRef<[u8]>, - okm_len: usize, -) -> Result, Error> { - match alg { - Algorithm::Sha256 => { - crate::hacl::hkdf::sha2_256::vec::expand(prk.as_ref(), info.as_ref(), okm_len) - .map_err(|_| Error::OkmLengthTooLarge) - } - Algorithm::Sha384 => { - crate::hacl::hkdf::sha2_384::vec::expand(prk.as_ref(), info.as_ref(), okm_len) - .map_err(|_| Error::OkmLengthTooLarge) - } - Algorithm::Sha512 => { - crate::hacl::hkdf::sha2_512::vec::expand(prk.as_ref(), info.as_ref(), okm_len) - .map_err(|_| Error::OkmLengthTooLarge) - } - } -} - -/// HKDF using hash function `mode`, `salt`, input key material `ikm`, `info`, and output length `okm_len`. -/// Calls `extract` and `expand` with the given input. -/// Returns the key material in a vector of length `okm_len` or [`Error::OkmLengthTooLarge`] -/// if the requested output length is too large. -pub fn hkdf( - mode: Algorithm, - salt: &[u8], - ikm: &[u8], - info: &[u8], - okm_len: usize, -) -> Result, Error> { - let prk = extract(mode, salt, ikm); - expand(mode, prk, info, okm_len) -} +pub use libcrux_hkdf::expand; +pub use libcrux_hkdf::extract; +pub use libcrux_hkdf::hkdf; +pub use libcrux_hkdf::Algorithm; +pub use libcrux_hkdf::Error; From f4c22d162f8a62177119a290b9ae170b6ae7e8a8 Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Mon, 10 Jun 2024 16:10:28 +0200 Subject: [PATCH 3/6] Pull out `libcrux::hmac` module into its own crate --- Cargo.toml | 1 + libcrux-hmac/Cargo.toml | 16 ++++++++++ libcrux-hmac/src/hacl_hmac.rs | 30 +++++++++++++++++++ libcrux-hmac/src/hmac.rs | 56 +++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 libcrux-hmac/Cargo.toml create mode 100644 libcrux-hmac/src/hacl_hmac.rs create mode 100644 libcrux-hmac/src/hmac.rs diff --git a/Cargo.toml b/Cargo.toml index fdf5c3597..d2baf0bcc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ members = [ "libcrux-sha3", "libcrux-ml-dsa", "libcrux-intrinsics", + "libcrux-hmac", "libcrux-hkdf", ] diff --git a/libcrux-hmac/Cargo.toml b/libcrux-hmac/Cargo.toml new file mode 100644 index 000000000..3e86f6e4b --- /dev/null +++ b/libcrux-hmac/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "libcrux-hmac" +version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +edition.workspace = true +repository.workspace = true +readme.workspace = true + +[lib] +path = "src/hmac.rs" + +[dependencies] +libcrux-hkdf = { version = "=0.0.2-pre.2", path = "../libcrux-hkdf" } +libcrux-hacl = { version = "=0.0.2-pre.2", path = "../sys/hacl" } diff --git a/libcrux-hmac/src/hacl_hmac.rs b/libcrux-hmac/src/hacl_hmac.rs new file mode 100644 index 000000000..65136aa26 --- /dev/null +++ b/libcrux-hmac/src/hacl_hmac.rs @@ -0,0 +1,30 @@ +use libcrux_hacl::{ + Hacl_HMAC_compute_sha1, Hacl_HMAC_compute_sha2_256, Hacl_HMAC_compute_sha2_384, + Hacl_HMAC_compute_sha2_512, +}; + +macro_rules! impl_hmac { + ($name:ident,$fun:expr,$tag_len:literal) => { + /// Compute HMAC. + /// + /// Note that this function panics if `key` or `data` is larger than 2**32 bytes. + pub fn $name(key: &[u8], data: &[u8]) -> [u8; $tag_len] { + let mut dst = [0u8; $tag_len]; + unsafe { + $fun( + dst.as_mut_ptr(), + key.as_ptr() as _, + key.len().try_into().unwrap(), + data.as_ptr() as _, + data.len().try_into().unwrap(), + ) + } + dst + } + }; +} + +impl_hmac!(sha1, Hacl_HMAC_compute_sha1, 20); +impl_hmac!(sha2_256, Hacl_HMAC_compute_sha2_256, 32); +impl_hmac!(sha2_384, Hacl_HMAC_compute_sha2_384, 48); +impl_hmac!(sha2_512, Hacl_HMAC_compute_sha2_512, 64); diff --git a/libcrux-hmac/src/hmac.rs b/libcrux-hmac/src/hmac.rs new file mode 100644 index 000000000..3eea90a22 --- /dev/null +++ b/libcrux-hmac/src/hmac.rs @@ -0,0 +1,56 @@ +//! HMAC +//! +//! This crate implements HMAC on SHA 1 and SHA 2 (except for SHA 224). + +use libcrux_hkdf as hkdf; +pub(crate) mod hacl_hmac; + +/// The HMAC algorithm defining the used hash function. +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum Algorithm { + Sha1, + // Not implemented + // Sha224 + Sha256, + Sha384, + Sha512, +} + +impl From for Algorithm { + fn from(value: hkdf::Algorithm) -> Self { + match value { + hkdf::Algorithm::Sha256 => Self::Sha256, + hkdf::Algorithm::Sha384 => Self::Sha384, + hkdf::Algorithm::Sha512 => Self::Sha512, + } + } +} + +/// Get the tag size for a given algorithm. +pub const fn tag_size(alg: Algorithm) -> usize { + match alg { + Algorithm::Sha1 => 20, + Algorithm::Sha256 => 32, + Algorithm::Sha384 => 48, + Algorithm::Sha512 => 64, + } +} + +/// Compute the HMAC value with the given `alg` and `key` on `data` with an +/// output tag length of `tag_length`. +/// Returns a vector of length `tag_length`. +pub fn hmac(alg: Algorithm, key: &[u8], data: &[u8], tag_length: Option) -> Vec { + let native_tag_length = tag_size(alg); + let tag_length = match tag_length { + Some(v) => v, + None => native_tag_length, + }; + let mut dst: Vec<_> = match alg { + Algorithm::Sha1 => crate::hacl_hmac::sha1(key, data).into(), + Algorithm::Sha256 => crate::hacl_hmac::sha2_256(key, data).into(), + Algorithm::Sha384 => crate::hacl_hmac::sha2_384(key, data).into(), + Algorithm::Sha512 => crate::hacl_hmac::sha2_512(key, data).into(), + }; + dst.truncate(tag_length); + dst +} From 2a52558c2d1f382c74700a40696d19973b62bd46 Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Mon, 10 Jun 2024 16:10:57 +0200 Subject: [PATCH 4/6] Re-export the `libcrux-hmac` crate API in `libcrux` --- Cargo.toml | 1 + src/hacl.rs | 1 - src/hacl/hmac.rs | 30 --------------------------- src/hmac.rs | 54 +++--------------------------------------------- 4 files changed, 4 insertions(+), 82 deletions(-) delete mode 100644 src/hacl/hmac.rs diff --git a/Cargo.toml b/Cargo.toml index d2baf0bcc..30e7e1f9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,7 @@ libcrux-platform = { version = "=0.0.2-pre.2", path = "sys/platform" } libcrux-hacl = { version = "=0.0.2-pre.2", path = "sys/hacl" } libcrux-platform = { version = "=0.0.2-pre.2", path = "sys/platform" } libcrux-hkdf = { version = "=0.0.2-pre.2", path = "libcrux-hkdf" } +libcrux-hmac = { version = "=0.0.2-pre.2", path = "libcrux-hmac" } rand = { version = "0.8" } log = { version = "0.4", optional = true } # WASM API diff --git a/src/hacl.rs b/src/hacl.rs index df1f748c9..a5a45b308 100644 --- a/src/hacl.rs +++ b/src/hacl.rs @@ -16,7 +16,6 @@ pub(crate) mod curve25519; #[cfg(not(target_arch = "wasm32"))] pub(crate) mod drbg; pub(crate) mod ed25519; -pub(crate) mod hmac; pub(crate) mod p256; pub(crate) mod sha2; pub(crate) mod sha3; diff --git a/src/hacl/hmac.rs b/src/hacl/hmac.rs deleted file mode 100644 index 65136aa26..000000000 --- a/src/hacl/hmac.rs +++ /dev/null @@ -1,30 +0,0 @@ -use libcrux_hacl::{ - Hacl_HMAC_compute_sha1, Hacl_HMAC_compute_sha2_256, Hacl_HMAC_compute_sha2_384, - Hacl_HMAC_compute_sha2_512, -}; - -macro_rules! impl_hmac { - ($name:ident,$fun:expr,$tag_len:literal) => { - /// Compute HMAC. - /// - /// Note that this function panics if `key` or `data` is larger than 2**32 bytes. - pub fn $name(key: &[u8], data: &[u8]) -> [u8; $tag_len] { - let mut dst = [0u8; $tag_len]; - unsafe { - $fun( - dst.as_mut_ptr(), - key.as_ptr() as _, - key.len().try_into().unwrap(), - data.as_ptr() as _, - data.len().try_into().unwrap(), - ) - } - dst - } - }; -} - -impl_hmac!(sha1, Hacl_HMAC_compute_sha1, 20); -impl_hmac!(sha2_256, Hacl_HMAC_compute_sha2_256, 32); -impl_hmac!(sha2_384, Hacl_HMAC_compute_sha2_384, 48); -impl_hmac!(sha2_512, Hacl_HMAC_compute_sha2_512, 64); diff --git a/src/hmac.rs b/src/hmac.rs index 8461f687a..c68e6190a 100644 --- a/src/hmac.rs +++ b/src/hmac.rs @@ -2,54 +2,6 @@ //! //! This module implements HMAC on SHA 1 and SHA 2 (except for SHA 224). -use crate::hkdf; - -/// The HMAC algorithm defining the used hash function. -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum Algorithm { - Sha1, - // Not implemented - // Sha224 - Sha256, - Sha384, - Sha512, -} - -impl From for Algorithm { - fn from(value: hkdf::Algorithm) -> Self { - match value { - hkdf::Algorithm::Sha256 => Self::Sha256, - hkdf::Algorithm::Sha384 => Self::Sha384, - hkdf::Algorithm::Sha512 => Self::Sha512, - } - } -} - -/// Get the tag size for a given algorithm. -pub const fn tag_size(alg: Algorithm) -> usize { - match alg { - Algorithm::Sha1 => 20, - Algorithm::Sha256 => 32, - Algorithm::Sha384 => 48, - Algorithm::Sha512 => 64, - } -} - -/// Compute the HMAC value with the given `alg` and `key` on `data` with an -/// output tag length of `tag_length`. -/// Returns a vector of length `tag_length`. -pub fn hmac(alg: Algorithm, key: &[u8], data: &[u8], tag_length: Option) -> Vec { - let native_tag_length = tag_size(alg); - let tag_length = match tag_length { - Some(v) => v, - None => native_tag_length, - }; - let mut dst: Vec<_> = match alg { - Algorithm::Sha1 => crate::hacl::hmac::sha1(key, data).into(), - Algorithm::Sha256 => crate::hacl::hmac::sha2_256(key, data).into(), - Algorithm::Sha384 => crate::hacl::hmac::sha2_384(key, data).into(), - Algorithm::Sha512 => crate::hacl::hmac::sha2_512(key, data).into(), - }; - dst.truncate(tag_length); - dst -} +pub use libcrux_hmac::Algorithm; +pub use libcrux_hmac::tag_size; +pub use libcrux_hmac::hmac; From 3fe64a1da2531e2fb8bd0847f2097e23247bf825 Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Mon, 10 Jun 2024 16:12:13 +0200 Subject: [PATCH 5/6] Formatting --- src/hmac.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hmac.rs b/src/hmac.rs index c68e6190a..5734662fe 100644 --- a/src/hmac.rs +++ b/src/hmac.rs @@ -2,6 +2,6 @@ //! //! This module implements HMAC on SHA 1 and SHA 2 (except for SHA 224). -pub use libcrux_hmac::Algorithm; -pub use libcrux_hmac::tag_size; pub use libcrux_hmac::hmac; +pub use libcrux_hmac::tag_size; +pub use libcrux_hmac::Algorithm; From 42a37b5c467595503dc37d9e2ccd2feb76818065 Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Mon, 10 Jun 2024 16:17:36 +0200 Subject: [PATCH 6/6] Incorporate `libcrux-hkdf` Errors in `libcrux::hacl::Error` type --- src/hacl.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/hacl.rs b/src/hacl.rs index a5a45b308..e0091f25d 100644 --- a/src/hacl.rs +++ b/src/hacl.rs @@ -27,6 +27,7 @@ pub enum Error { Curve25519(curve25519::Error), P256(p256::Error), Ed25519(ed25519::Error), + Hkdf(libcrux_hkdf::Error), } impl From for Error { @@ -47,6 +48,12 @@ impl From for Error { } } +impl From for Error { + fn from(val: libcrux_hkdf::Error) -> Self { + Error::Hkdf(val) + } +} + impl From for Error { fn from(val: ed25519::Error) -> Self { Error::Ed25519(val)