Skip to content

Commit b30c138

Browse files
committed
Enable sha1 AArch64 extension on Linux
The feature gate is specific to glibc on Linux, using getauxval() to check the CPU flags, so it’s currently not used on other systems. Patches welcome. :) Enables RustCrypto/asm-hashes#10
1 parent 18a2865 commit b30c138

File tree

3 files changed

+34
-8
lines changed

3 files changed

+34
-8
lines changed

sha1/src/aarch64.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// From sys/auxv.h
2+
const AT_HWCAP: u64 = 16;
3+
const HWCAP_SHA1: u64 = 32;
4+
extern {
5+
fn getauxval(type_: u64) -> u64;
6+
}
7+
8+
pub fn sha1_supported() -> bool {
9+
let hwcaps: u64 = unsafe { getauxval(AT_HWCAP) };
10+
(hwcaps & HWCAP_SHA1) != 0
11+
}

sha1/src/consts.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22

33
pub const STATE_LEN: usize = 5;
44

5-
#[cfg(not(feature = "asm"))]
5+
#[cfg(any(not(feature = "asm"), all(target_arch = "aarch64", target_os = "linux")))]
66
pub const BLOCK_LEN: usize = 16;
77

8-
#[cfg(not(feature = "asm"))]
8+
#[cfg(any(not(feature = "asm"), all(target_arch = "aarch64", target_os = "linux")))]
99
pub const K0: u32 = 0x5A827999u32;
10-
#[cfg(not(feature = "asm"))]
10+
#[cfg(any(not(feature = "asm"), all(target_arch = "aarch64", target_os = "linux")))]
1111
pub const K1: u32 = 0x6ED9EBA1u32;
12-
#[cfg(not(feature = "asm"))]
12+
#[cfg(any(not(feature = "asm"), all(target_arch = "aarch64", target_os = "linux")))]
1313
pub const K2: u32 = 0x8F1BBCDCu32;
14-
#[cfg(not(feature = "asm"))]
14+
#[cfg(any(not(feature = "asm"), all(target_arch = "aarch64", target_os = "linux")))]
1515
pub const K3: u32 = 0xCA62C1D6u32;
1616

1717
pub const H: [u32; STATE_LEN] = [

sha1/src/lib.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,34 @@ extern crate block_buffer;
3333
#[macro_use] pub extern crate digest;
3434
#[cfg(feature = "std")]
3535
extern crate std;
36-
#[cfg(not(feature = "asm"))]
36+
#[cfg(any(not(feature = "asm"), all(target_arch = "aarch64", target_os = "linux")))]
3737
extern crate fake_simd as simd;
3838

3939
#[cfg(feature = "asm")]
4040
extern crate sha1_asm;
41-
#[cfg(feature = "asm")]
41+
#[cfg(all(feature = "asm", not(all(target_arch = "aarch64", target_os = "linux"))))]
4242
#[inline(always)]
4343
fn compress(state: &mut [u32; 5], block: &GenericArray<u8, U64>) {
4444
let block: &[u8; 64] = unsafe { core::mem::transmute(block) };
4545
sha1_asm::compress(state, block);
4646
}
47+
#[cfg(all(feature = "asm", target_arch = "aarch64", target_os = "linux"))]
48+
mod aarch64;
49+
#[cfg(all(feature = "asm", target_arch = "aarch64", target_os = "linux"))]
50+
#[inline(always)]
51+
fn compress(state: &mut [u32; 5], block: &GenericArray<u8, U64>) {
52+
// TODO: Replace this platform-specific call with is_aarch64_feature_detected!("sha1") once
53+
// that macro is stabilised and https://github.com/rust-lang/rfcs/pull/2725 is implemented
54+
// to let us use it on no_std.
55+
if aarch64::sha1_supported() {
56+
let block: &[u8; 64] = unsafe { core::mem::transmute(block) };
57+
sha1_asm::compress(state, block);
58+
} else {
59+
utils::compress(state, block);
60+
}
61+
}
4762

48-
#[cfg(not(feature = "asm"))]
63+
#[cfg(any(not(feature = "asm"), all(target_arch = "aarch64", target_os = "linux")))]
4964
mod utils;
5065
#[cfg(not(feature = "asm"))]
5166
use utils::compress;

0 commit comments

Comments
 (0)