Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rust cleanup ctd... #379

Merged
merged 27 commits into from
Mar 21, 2023
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9c86bcc
fix rust hazmat sha2 streaming
franziskuskiefer Jan 27, 2023
1a47e67
sha2 streaming mutability
franziskuskiefer Jan 28, 2023
3ce5eed
add hmac and hkdf
franziskuskiefer Feb 3, 2023
d46bb9e
hkdf hmac reorg
franziskuskiefer Feb 7, 2023
a2bb38b
add errors to hkdf
franziskuskiefer Feb 8, 2023
fdf311e
Merge branch 'main' into franziskus/rust-cleanup-4
franziskuskiefer Feb 9, 2023
56c49d1
add sha384 hkdf
franziskuskiefer Feb 9, 2023
8308ae9
Create devcontainer.json
franziskuskiefer Feb 9, 2023
ab5faf0
fix simd256
franziskuskiefer Feb 9, 2023
f849fa7
Apply suggestions from code review
franziskuskiefer Feb 10, 2023
1b41e33
don't panic in hkdf
franziskuskiefer Feb 10, 2023
df3cefc
add build.rs to Rust library
franziskuskiefer Feb 10, 2023
62527ea
remove config.toml
franziskuskiefer Feb 10, 2023
1c2357f
Merge branch 'main' into franziskus/rust-cleanup-5
franziskuskiefer Feb 17, 2023
0f3e65c
Merge branch 'main' into franziskus/rust-cleanup-5
franziskuskiefer Feb 23, 2023
8799561
Merge branch 'main' into franziskus/rust-cleanup-5
franziskuskiefer Feb 23, 2023
109efb1
use streaming for sha2 oneshot
franziskuskiefer Feb 23, 2023
969d924
add drbg to hazma api
franziskuskiefer Feb 24, 2023
fd92d69
Merge branch 'main' into franziskus/rust-cleanup-5
franziskuskiefer Mar 2, 2023
2640dde
more hazmat apis
franziskuskiefer Mar 4, 2023
f069c94
errors
franziskuskiefer Mar 9, 2023
4bedebd
fixup vale x25519
franziskuskiefer Mar 9, 2023
aec65b9
wip
franziskuskiefer Mar 9, 2023
b67fd5b
aesgcm hazmat
franziskuskiefer Mar 9, 2023
3e43f89
Merge branch 'main' into franziskus/rust-cleanup-5
franziskuskiefer Mar 20, 2023
64fdfcf
review (wip)
franziskuskiefer Mar 20, 2023
6d1ba85
review
franziskuskiefer Mar 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions rust/.cargo/config.toml

This file was deleted.

83 changes: 83 additions & 0 deletions rust/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn simd128_support() -> bool {
std::arch::is_x86_feature_detected!("sse2")
&& std::arch::is_x86_feature_detected!("sse3")
&& std::arch::is_x86_feature_detected!("sse4.1")
&& std::arch::is_x86_feature_detected!("avx")
}

#[cfg(target_arch = "aarch64")]
fn simd128_support() -> bool {
true
}

#[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64")))]
fn simd128_support() -> bool {
// XXX: Check for z14 or z15
false
}

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn simd256_support() -> bool {
std::arch::is_x86_feature_detected!("avx2")
}

#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
fn simd256_support() -> bool {
// XXX: Check for z14 or z15
false
}

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn bmi2_adx_support() -> bool {
std::arch::is_x86_feature_detected!("bmi2") && std::arch::is_x86_feature_detected!("adx")
}

#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
fn bmi2_adx_support() -> bool {
false
}

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn sha_ni_support() -> bool {
std::arch::is_x86_feature_detected!("sha")
}

#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
fn sha_ni_support() -> bool {
false
}

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn aes_ni_support() -> bool {
// FIXME: std::arch::is_x86_feature_detected!("movbe") is not supported yet
duesee marked this conversation as resolved.
Show resolved Hide resolved
// we assume here that it is supported :|
std::arch::is_x86_feature_detected!("avx")
&& std::arch::is_x86_feature_detected!("sse")
&& std::arch::is_x86_feature_detected!("aes")
&& std::arch::is_x86_feature_detected!("pclmulqdq")
}

#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
fn aes_ni_support() -> bool {
false
}

fn main() {
if simd128_support() {
println!("cargo:rustc-cfg=simd128");
}
if simd256_support() {
println!("cargo:rustc-cfg=simd256");
}
if bmi2_adx_support() {
println!("cargo:rustc-cfg=bmi2");
println!("cargo:rustc-cfg=adx");
}
if sha_ni_support() {
println!("cargo:rustc-cfg=sha_ni");
}
if aes_ni_support() {
println!("cargo:rustc-cfg=aes_ni");
}
}
4 changes: 4 additions & 0 deletions rust/hacl-star-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,15 @@ fn create_bindings(include_path: &Path, home_dir: &Path) {
.allowlist_function("Hacl_Curve25519_.*")
.allowlist_function("Hacl_HKDF_.*")
.allowlist_function("Hacl_HMAC_.*")
.allowlist_function("Hacl_HMAC_DRBG_.*")
.allowlist_function("Hacl_Bignum64_.*")
.allowlist_function("Hacl_Ed25519_.*")
.allowlist_var("EverCrypt_Error_.*")
.allowlist_var("Spec_.*")
.allowlist_type("Spec_.*")
.allowlist_type("Hacl_Streaming_SHA2_state.*")
.allowlist_type("Hacl_Streaming_SHA3_state.*")
.allowlist_type("Hacl_HMAC_DRBG_.*")
// Block everything we don't need or define ourselves.
.blocklist_type("EverCrypt_AEAD_state_s.*")
// These functions currently use FFI-unsafe u128
Expand Down
230 changes: 230 additions & 0 deletions rust/hacl-star-sys/src/bindings/bindings.rs

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions rust/hacl-star-sys/wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
#include "hacl/EverCrypt_HKDF.h"
#include "hacl/EverCrypt_HMAC.h"
#include "hacl/EverCrypt_Hash.h"
#include "hacl/Hacl_Bignum64.h"
#include "hacl/Hacl_HKDF.h"
#include "hacl/Hacl_HMAC.h"
#include "hacl/Hacl_HMAC_DRBG.h"
#include "hacl/Hacl_Hash_Blake2.h"
#include "hacl/Hacl_Hash_SHA2.h"
#include "hacl/Hacl_Streaming_SHA2.h"
#include "hacl/Hacl_Hash_SHA3.h"
#include "hacl/Hacl_P256.h"
#include "hacl/Hacl_RSAPSS.h"
#include "hacl/Hacl_Hash_SHA3.h"
#include "hacl/Hacl_Spec.h"
#include "hacl/Hacl_Streaming_SHA2.h"
38 changes: 37 additions & 1 deletion rust/src/hazmat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@
//! | simd128 | - | SSE2, SSE3, SSE4.1 | - | NEON | z14 |
//! | simd256 | - | AVX, AVX2 | - | - | - |

#[cfg(aes_ni)]
pub mod aesgcm;
pub mod blake2;
pub mod chacha20_poly1305;
pub mod curve25519;
pub mod drbg;
pub mod ed25519;
pub mod hkdf;
pub mod hmac;
pub mod p256;
Expand All @@ -25,7 +29,39 @@ pub mod sha3;
/// Unified error type.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Error {
Chacha20Poly1305(chacha20_poly1305::Error),
ChaCha20Poly1305(chacha20_poly1305::Error),
Curve25519(curve25519::Error),
P256(p256::Error),
Ed25519(ed25519::Error),
Hkdf(hkdf::Error),
}

impl Into<Error> for chacha20_poly1305::Error {
duesee marked this conversation as resolved.
Show resolved Hide resolved
fn into(self) -> Error {
Error::ChaCha20Poly1305(self)
}
}

impl Into<Error> for curve25519::Error {
fn into(self) -> Error {
Error::Curve25519(self)
}
}

impl Into<Error> for p256::Error {
fn into(self) -> Error {
Error::P256(self)
}
}

impl Into<Error> for hkdf::Error {
fn into(self) -> Error {
Error::Hkdf(self)
}
}

impl Into<Error> for ed25519::Error {
fn into(self) -> Error {
Error::Ed25519(self)
}
}
126 changes: 126 additions & 0 deletions rust/src/hazmat/aesgcm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
use hacl_star_sys::{
EverCrypt_AEAD_create_in, EverCrypt_AEAD_decrypt, EverCrypt_AEAD_encrypt,
EverCrypt_AEAD_state_s, EverCrypt_AutoConfig2_init, Spec_Agile_AEAD_AES128_GCM,
Spec_Agile_AEAD_AES256_GCM,
};

pub type Aes128Key = [u8; 16];
pub type Aes256Key = [u8; 32];
pub type Iv = [u8; 12];
pub type Tag = [u8; 16];

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Error {
duesee marked this conversation as resolved.
Show resolved Hide resolved
UnsupportedHardware,
EncryptionError,
InvalidCiphertext,
}

pub fn hardware_support() -> Result<(), Error> {
duesee marked this conversation as resolved.
Show resolved Hide resolved
unsafe {
EverCrypt_AutoConfig2_init();
if hacl_star_sys::EverCrypt_AutoConfig2_has_aesni()
&& hacl_star_sys::EverCrypt_AutoConfig2_has_pclmulqdq()
&& hacl_star_sys::EverCrypt_AutoConfig2_has_avx()
&& hacl_star_sys::EverCrypt_AutoConfig2_has_sse()
&& hacl_star_sys::EverCrypt_AutoConfig2_has_movbe()
{
Ok(())
} else {
Err(Error::UnsupportedHardware)
}
}
}

macro_rules! implement {
($name:ident, $name_dec:ident, $alg:expr, $keytype:ty) => {
#[must_use]
pub fn $name(
key: &$keytype,
msg_ctxt: &mut [u8],
iv: Iv,
aad: &[u8],
) -> Result<Tag, Error> {
let mut tag = Tag::default();
let ok = unsafe {
hardware_support()?;
duesee marked this conversation as resolved.
Show resolved Hide resolved

let mut state_ptr: *mut EverCrypt_AEAD_state_s = std::ptr::null_mut();
let e = EverCrypt_AEAD_create_in($alg as u8, &mut state_ptr, key.as_ptr() as _);
if e != 0 {
return Err(Error::EncryptionError);
}
EverCrypt_AEAD_encrypt(
state_ptr,
iv.as_ptr() as _,
iv.len().try_into().map_err(|_| Error::EncryptionError)?,
aad.as_ptr() as _,
aad.len().try_into().map_err(|_| Error::EncryptionError)?,
msg_ctxt.as_ptr() as _,
msg_ctxt
.len()
.try_into()
.map_err(|_| Error::EncryptionError)?,
msg_ctxt.as_mut_ptr(),
tag.as_mut_ptr(),
)
};
if ok == 0 {
Ok(tag)
} else {
Err(Error::EncryptionError)
}
}

#[must_use]
pub fn $name_dec(
key: &$keytype,
payload: &mut [u8],
iv: Iv,
aad: &[u8],
tag: &Tag,
) -> Result<(), Error> {
let ok = unsafe {
hardware_support()?;
duesee marked this conversation as resolved.
Show resolved Hide resolved

let mut state_ptr: *mut EverCrypt_AEAD_state_s = std::ptr::null_mut();
let e = EverCrypt_AEAD_create_in($alg as u8, &mut state_ptr, key.as_ptr() as _);
if e != 0 {
return Err(Error::EncryptionError);
}
EverCrypt_AEAD_decrypt(
state_ptr,
iv.as_ptr() as _,
iv.len().try_into().map_err(|_| Error::EncryptionError)?,
aad.as_ptr() as _,
aad.len().try_into().map_err(|_| Error::EncryptionError)?,
payload.as_ptr() as _,
payload
.len()
.try_into()
.map_err(|_| Error::EncryptionError)?,
tag.as_ptr() as _,
payload.as_mut_ptr(),
)
};
if ok == 0 {
Ok(())
} else {
Err(Error::InvalidCiphertext)
}
}
};
}

implement!(
encrypt_128,
decrypt_128,
Spec_Agile_AEAD_AES128_GCM,
Aes128Key
);
implement!(
encrypt_256,
decrypt_256,
Spec_Agile_AEAD_AES256_GCM,
Aes256Key
);
3 changes: 2 additions & 1 deletion rust/src/hazmat/curve25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ pub fn secret_to_public(private_key: &[u8; 32]) -> [u8; 32] {
}

#[cfg(all(bmi2, adx, target_arch = "x86_64"))]
mod vale {
pub mod vale {
use super::Error;
use hacl_star_sys::Hacl_Curve25519_64_ecdh;

/// Compute the ECDH with the `private_key` and `public_key`.
Expand Down
87 changes: 87 additions & 0 deletions rust/src/hazmat/drbg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use hacl_star_sys::{
Hacl_HMAC_DRBG_create_in, Hacl_HMAC_DRBG_free, Hacl_HMAC_DRBG_generate,
Hacl_HMAC_DRBG_instantiate, Hacl_HMAC_DRBG_reseed, Hacl_HMAC_DRBG_state,
Spec_Hash_Definitions_SHA1, Spec_Hash_Definitions_SHA2_256, Spec_Hash_Definitions_SHA2_384,
Spec_Hash_Definitions_SHA2_512,
};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum Algorithm {
Sha1 = Spec_Hash_Definitions_SHA1 as u8,
Sha2_256 = Spec_Hash_Definitions_SHA2_256 as u8,
Sha2_384 = Spec_Hash_Definitions_SHA2_384 as u8,
Sha2_512 = Spec_Hash_Definitions_SHA2_512 as u8,
}

pub enum Error {
/// Unable to generate the requested randomness.
UnableToGenerate,
}

pub struct Drbg {
state: Hacl_HMAC_DRBG_state,
alg: Algorithm,
}

impl Drbg {
/// Create a new DRBG state with the given hash function.
/// This also initializes the DRBG state with the given entropy, nonce and
/// personalization string.
pub fn new(alg: Algorithm, entropy: &[u8], nonce: &[u8], personalization: &str) -> Self {
let state = unsafe { Hacl_HMAC_DRBG_create_in(alg as u8) };
unsafe {
Hacl_HMAC_DRBG_instantiate(
alg as u8,
state,
entropy.len().try_into().unwrap(),
duesee marked this conversation as resolved.
Show resolved Hide resolved
entropy.as_ptr() as _,
nonce.len().try_into().unwrap(),
nonce.as_ptr() as _,
personalization.len().try_into().unwrap(),
personalization.as_bytes().as_ptr() as _,
);
}
Self { state, alg }
}

/// Reseed the DRBG state.
///
/// It is very unlikely that you will need this function.
pub fn reseed(&mut self, entropy: &[u8], additional_input: &[u8]) {
unsafe {
Hacl_HMAC_DRBG_reseed(
self.alg as u8,
self.state,
entropy.len().try_into().unwrap(),
duesee marked this conversation as resolved.
Show resolved Hide resolved
entropy.as_ptr() as _,
additional_input.len().try_into().unwrap(),
additional_input.as_ptr() as _,
);
}
}

/// Generate random bytes.
pub fn generate(&mut self, output: &mut [u8], additional_input: &[u8]) -> Result<(), Error> {
if unsafe {
Hacl_HMAC_DRBG_generate(
self.alg as u8,
output.as_mut_ptr(),
self.state,
output.len().try_into().unwrap(),
additional_input.len().try_into().unwrap(),
additional_input.as_ptr() as _,
)
} {
Ok(())
} else {
Err(Error::UnableToGenerate)
}
}
}

impl Drop for Drbg {
fn drop(&mut self) {
unsafe { Hacl_HMAC_DRBG_free(self.alg as u8, self.state) };
}
}
Loading