Skip to content

Commit 51f8a40

Browse files
committed
Enable sha2 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. :) The sha2 extension only provides SHA-256 instructions, so keep using the plain Rust implementation for SHA-512 until someone adds sha512 extension assembly (I have no computer to test that with).
1 parent 698179e commit 51f8a40

File tree

5 files changed

+45
-4
lines changed

5 files changed

+45
-4
lines changed

sha2/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ block-buffer = "0.7"
1515
fake-simd = "0.1"
1616
opaque-debug = "0.2"
1717
sha2-asm = { version="0.5", optional=true }
18+
libc = { version = "0.2", optional = true }
1819

1920
[dev-dependencies]
2021
digest = { version = "0.8", features = ["dev"] }
@@ -25,5 +26,9 @@ default = ["std"]
2526
std = ["digest/std"]
2627
asm = ["sha2-asm"]
2728

29+
# TODO: Remove this feature once is_aarch64_feature_detected!() is stabilised.
30+
# Only used on AArch64 Linux systems.
31+
asm-aarch64 = ["asm", "libc"]
32+
2833
[badges]
2934
travis-ci = { repository = "RustCrypto/hashes" }

sha2/src/aarch64.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// TODO: Add those to the libc crate.
2+
const AT_HWCAP: u64 = 16;
3+
const HWCAP_SHA2: u64 = 64;
4+
5+
#[inline(always)]
6+
pub fn sha2_supported() -> bool {
7+
let hwcaps: u64 = unsafe { ::libc::getauxval(AT_HWCAP) };
8+
(hwcaps & HWCAP_SHA2) != 0
9+
}

sha2/src/lib.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@
5757
#![no_std]
5858
#![doc(html_logo_url =
5959
"https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")]
60+
61+
// Give relevant error messages if the user tries to enable AArch64 asm on unsupported platforms.
62+
#[cfg(all(feature = "asm-aarch64", target_arch = "aarch64", not(target_os = "linux")))]
63+
compile_error!("Your OS isn’t yet supported for runtime-checking of AArch64 features.");
64+
#[cfg(all(feature = "asm-aarch64", target_os = "linux", not(target_arch = "aarch64")))]
65+
compile_error!("Enable the \"asm\" feature instead of \"asm-aarch64\" on non-AArch64 Linux systems.");
66+
#[cfg(all(not(feature = "asm-aarch64"), feature = "asm", target_arch = "aarch64", target_os = "linux"))]
67+
compile_error!("Enable the \"asm-aarch64\" feature on AArch64 if you want to use asm.");
68+
6069
extern crate block_buffer;
6170
extern crate fake_simd as simd;
6271
#[macro_use] extern crate opaque_debug;
@@ -65,12 +74,16 @@ extern crate fake_simd as simd;
6574
extern crate sha2_asm;
6675
#[cfg(feature = "std")]
6776
extern crate std;
77+
#[cfg(feature = "asm-aarch64")]
78+
extern crate libc;
6879

6980
mod consts;
70-
#[cfg(not(feature = "asm"))]
81+
#[cfg(any(not(feature = "asm"), feature = "asm-aarch64"))]
7182
mod sha256_utils;
72-
#[cfg(not(feature = "asm"))]
83+
#[cfg(any(not(feature = "asm"), feature = "asm-aarch64"))]
7384
mod sha512_utils;
85+
#[cfg(feature = "asm-aarch64")]
86+
mod aarch64;
7487
mod sha256;
7588
mod sha512;
7689

sha2/src/sha256.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,24 @@ struct Engine256State {
2424
impl Engine256State {
2525
fn new(h: &[u32; STATE_LEN]) -> Engine256State { Engine256State { h: *h } }
2626

27+
#[cfg(not(feature = "asm-aarch64"))]
2728
pub fn process_block(&mut self, block: &Block) {
2829
let block = unsafe { &*(block.as_ptr() as *const [u8; 64]) };
2930
compress256(&mut self.h, block);
3031
}
32+
33+
#[cfg(feature = "asm-aarch64")]
34+
pub fn process_block(&mut self, block: &Block) {
35+
let block = unsafe { &*(block.as_ptr() as *const [u8; 64]) };
36+
// TODO: Replace this platform-specific call with is_aarch64_feature_detected!("sha2") once
37+
// that macro is stabilised and https://github.com/rust-lang/rfcs/pull/2725 is implemented
38+
// to let us use it on no_std.
39+
if ::aarch64::sha2_supported() {
40+
compress256(&mut self.h, block);
41+
} else {
42+
::sha256_utils::compress256(&mut self.h, block);
43+
}
44+
}
3145
}
3246

3347
/// A structure that keeps track of the state of the Sha-256 operation and

sha2/src/sha512.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ use block_buffer::byteorder::{BE, ByteOrder};
66

77
use consts::{STATE_LEN, H384, H512, H512_TRUNC_224, H512_TRUNC_256};
88

9-
#[cfg(not(feature = "asm"))]
9+
#[cfg(any(not(feature = "asm"), feature = "asm-aarch64"))]
1010
use sha512_utils::compress512;
11-
#[cfg(feature = "asm")]
11+
#[cfg(all(feature = "asm", not(feature = "asm-aarch64")))]
1212
use sha2_asm::compress512;
1313

1414
type BlockSize = U128;

0 commit comments

Comments
 (0)