Skip to content

Add x86 intrinsics support for sha1 and sha2 #167

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

Merged
merged 15 commits into from
Jun 15, 2020
Merged
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 9 additions & 4 deletions sha1/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ name = "sha1"
digest = "0.9"
block-buffer = "0.9"
opaque-debug = "0.3"
cfg-if = "0.1"
sha1-asm = { version = "0.4", optional = true }

[target.'cfg(any(target_arch = "x86", target_arch = "x86_64"))'.dependencies]
cpuid-bool = "0.1"

[target.'cfg(all(target_arch = "aarch64", target_os = "linux"))'.dependencies]
libc = { version = "0.2.68", optional = true }

[dev-dependencies]
Expand All @@ -28,8 +34,7 @@ hex-literal = "0.2"
[features]
default = ["std"]
std = ["digest/std"]
asm = ["sha1-asm"]
asm = ["sha1-asm", "libc"]

# TODO: Remove this feature once is_aarch64_feature_detected!() is stabilised.
# Only used on AArch64 Linux systems, when built without the crypto target_feature.
asm-aarch64 = ["asm", "libc"]
# DEPRECATED: use `asm` instead
asm-aarch64 = ["asm"]
8 changes: 0 additions & 8 deletions sha1/src/aarch64.rs

This file was deleted.

32 changes: 32 additions & 0 deletions sha1/src/compress.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use digest::consts::U64;
use digest::generic_array::GenericArray;

cfg_if::cfg_if! {
if #[cfg(all(feature = "asm", target_arch = "aarch64", target_os = "linux"))] {
mod soft;
mod aarch64;
use aarch64::compress as compress_inner;
} else if #[cfg(all(feature = "asm", any(target_arch = "x86", target_arch = "x86_64")))] {
// TODO: replace after sha1-asm rework
fn compress_inner(state: &mut [u32; 5], blocks: &[[u8; 64]]) {
for block in blocks {
sha1_asm::compress(state, block);
}
}
} else if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
mod soft;
mod x86;
use x86::compress as compress_inner;
} else {
mod soft;
use soft::compress as compress_inner;
}
}

pub fn compress(state: &mut [u32; 5], blocks: &[GenericArray<u8, U64>]) {
// SAFETY: GenericArray<u8, U64> and [u8; 64] have
// exactly the same memory layout
#[allow(unsafe_code)]
let blocks: &[[u8; 64]] = unsafe { &*(blocks as *const _ as *const [[u8; 64]]) };
compress_inner(state, blocks);
}
21 changes: 21 additions & 0 deletions sha1/src/compress/aarch64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#![cfg(feature = "asm-aarch64")]
use libc::{getauxval, AT_HWCAP, HWCAP_SHA1};

fn sha1_supported() -> bool {
#[allow(unsafe_code)]
let hwcaps: u64 = unsafe { getauxval(AT_HWCAP) };
(hwcaps & HWCAP_SHA1) != 0
}

pub fn compress(state: &mut [u32; 5], blocks: &[u8; 64]) {
// TODO: Replace this platform-specific call with is_aarch64_feature_detected!("sha1") once
// that macro is stabilised and https://github.com/rust-lang/rfcs/pull/2725 is implemented
// to let us use it on no_std.
if sha1_supported() {
for block in blocks {
sha1_asm::compress(state, block);
}
} else {
super::soft::compress(state, blocks);
}
}
Loading