Skip to content

Commit bf0bc74

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 b30c138 commit bf0bc74

File tree

4 files changed

+37
-4
lines changed

4 files changed

+37
-4
lines changed

sha2/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_SHA2: u64 = 64;
4+
extern {
5+
fn getauxval(type_: u64) -> u64;
6+
}
7+
8+
pub fn sha2_supported() -> bool {
9+
let hwcaps: u64 = unsafe { getauxval(AT_HWCAP) };
10+
(hwcaps & HWCAP_SHA2) != 0
11+
}

sha2/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,12 @@ extern crate sha2_asm;
6767
extern crate std;
6868

6969
mod consts;
70-
#[cfg(not(feature = "asm"))]
70+
#[cfg(any(not(feature = "asm"), target_arch = "aarch64"))]
7171
mod sha256_utils;
72-
#[cfg(not(feature = "asm"))]
72+
#[cfg(any(not(feature = "asm"), target_arch = "aarch64"))]
7373
mod sha512_utils;
74+
#[cfg(all(feature = "asm", target_arch = "aarch64", target_os = "linux"))]
75+
mod aarch64;
7476
mod sha256;
7577
mod sha512;
7678

sha2/src/sha256.rs

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

27+
#[cfg(not(all(feature = "asm", target_arch = "aarch64", target_os = "linux")))]
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(all(feature = "asm", target_arch = "aarch64", not(target_os = "linux")))]
34+
pub fn process_block(&mut self, block: &Block) {
35+
let block = unsafe { &*(block.as_ptr() as *const [u8; 64]) };
36+
::sha256_utils::compress256(&mut self.h, block);
37+
}
38+
39+
#[cfg(all(feature = "asm", target_arch = "aarch64", target_os = "linux"))]
40+
pub fn process_block(&mut self, block: &Block) {
41+
let block = unsafe { &*(block.as_ptr() as *const [u8; 64]) };
42+
// TODO: Replace this platform-specific call with is_aarch64_feature_detected!("sha2") once
43+
// that macro is stabilised and https://github.com/rust-lang/rfcs/pull/2725 is implemented
44+
// to let us use it on no_std.
45+
if ::aarch64::sha2_supported() {
46+
compress256(&mut self.h, block);
47+
} else {
48+
::sha256_utils::compress256(&mut self.h, block);
49+
}
50+
}
3151
}
3252

3353
/// 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"), target_arch = "aarch64"))]
1010
use sha512_utils::compress512;
11-
#[cfg(feature = "asm")]
11+
#[cfg(all(feature = "asm", not(target_arch = "aarch64")))]
1212
use sha2_asm::compress512;
1313

1414
type BlockSize = U128;

0 commit comments

Comments
 (0)