Skip to content

Commit

Permalink
Add CPU feature detection for FreeBSD/aarch64
Browse files Browse the repository at this point in the history
I agree to license my contributions to each file under the terms given
at the top of each file I changed.
  • Loading branch information
valpackett committed Aug 25, 2019
1 parent 03ffd88 commit 79fd0f8
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 4 deletions.
1 change: 1 addition & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const RING_SRCS: &[(&[&str], &str)] = &[
(&[], "third_party/fiat/curve25519.c"),

(&[X86_64, X86], "crypto/cpu-intel.c"),
(&[AARCH64], "crypto/cpu-aarch64.c"),

(&[X86], "crypto/fipsmodule/aes/asm/aes-586.pl"),
(&[X86], "crypto/fipsmodule/aes/asm/aesni-x86.pl"),
Expand Down
46 changes: 46 additions & 0 deletions crypto/cpu-aarch64.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2019 Greg V
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.


// Run-time feature detection for aarch64 on any OS that emulates the mrs instruction.
//
// On FreeBSD >= 12.0, Linux >= 4.11 and other operating systems, it is possible to use
// privileged system registers from userspace to check CPU feature support.
//
// For proper support of SoCs where different cores have different capabilities
// the OS has to always report only the features supported by all cores, like FreeBSD does.
//
// Only FreeBSD uses this right now.

#ifdef __FreeBSD__
#pragma GCC diagnostic ignored "-Wgnu-statement-expression"
#include <GFp/cpu.h>
#include <GFp/arm_arch.h>
#include <machine/armreg.h>

void GFp_mrs_setup(void) {
GFp_armcap_P = 0;

uint64_t id_aa64isar0 = READ_SPECIALREG(ID_AA64ISAR0_EL1);

if (ID_AA64ISAR0_AES(id_aa64isar0) >= ID_AA64ISAR0_AES_BASE)
GFp_armcap_P |= ARMV8_AES;

if (ID_AA64ISAR0_AES(id_aa64isar0) >= ID_AA64ISAR0_AES_PMULL)
GFp_armcap_P |= ARMV8_PMULL;

if (ID_AA64ISAR0_SHA2(id_aa64isar0) >= ID_AA64ISAR0_SHA2_BASE)
GFp_armcap_P |= ARMV8_SHA256;
}
#endif
6 changes: 6 additions & 0 deletions include/GFp/arm_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,13 @@
// ARMV7_NEON is true when a NEON unit is present in the current CPU.
#define ARMV7_NEON (1 << 0)

// ARMV8_AES indicates support for hardware AES instructions.
#define ARMV8_AES (1 << 2)

// ARMV8_SHA256 indicates support for hardware SHA-256 instructions.
#define ARMV8_SHA256 (1 << 4)

// ARMV8_PMULL indicates support for hardware polynomial multiply instructions.
#define ARMV8_PMULL (1 << 5)

#endif // OPENSSL_HEADER_ARM_ARCH_H
7 changes: 7 additions & 0 deletions include/GFp/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,11 @@
extern uint32_t GFp_ia32cap_P[4];
#endif

#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
// GFp_armcap_P contains feature flags when running on an ARM system.
//
// The flags are defined in <GFp/arm_arch.h>.
extern uint32_t GFp_armcap_P;
#endif

#endif // OPENSSL_HEADER_CPU_H
18 changes: 14 additions & 4 deletions src/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ pub(crate) fn features() -> Features {
{
arm::fuchsia_setup();
}

#[cfg(all(any(target_os = "freebsd"), target_arch = "aarch64"))]
{
extern "C" {
fn GFp_mrs_setup();
}
unsafe {
GFp_mrs_setup();
}
}
});
}

Expand Down Expand Up @@ -171,7 +181,7 @@ pub(crate) mod arm {
pub(crate) struct Feature {
#[cfg_attr(
not(all(
any(target_os = "android", target_os = "linux", target_os = "fuchsia"),
any(target_os = "android", all(target_os = "freebsd", target_arch = "aarch64"), target_os = "linux", target_os = "fuchsia"),
any(target_arch = "arm", target_arch = "aarch64")
)),
allow(dead_code)
Expand All @@ -191,15 +201,15 @@ pub(crate) mod arm {
}

#[cfg(all(
any(target_os = "android", target_os = "linux", target_os = "fuchsia"),
any(target_os = "android", all(target_os = "freebsd", target_arch = "aarch64"), target_os = "linux", target_os = "fuchsia"),
any(target_arch = "arm", target_arch = "aarch64")
))]
{
return self.mask == self.mask & unsafe { GFp_armcap_P };
}

#[cfg(not(all(
any(target_os = "android", target_os = "ios", target_os = "linux", target_os = "fuchsia"),
any(target_os = "android", all(target_os = "freebsd", target_arch = "aarch64"), target_os = "ios", target_os = "linux", target_os = "fuchsia"),
any(target_arch = "arm", target_arch = "aarch64")
)))]
{
Expand Down Expand Up @@ -231,7 +241,7 @@ pub(crate) mod arm {
};

#[cfg(all(
any(target_os = "android", target_os = "linux", target_os = "fuchsia"),
any(target_os = "android", all(target_os = "freebsd", target_arch = "aarch64"), target_os = "linux", target_os = "fuchsia"),
any(target_arch = "arm", target_arch = "aarch64")
))]
extern "C" {
Expand Down

0 comments on commit 79fd0f8

Please sign in to comment.