]> Cypherpunks repositories - gostls13.git/commitdiff
internal/cpu: add ARM64.HasSHA3
authorFilippo Valsorda <filippo@golang.org>
Mon, 30 Sep 2024 14:52:50 +0000 (16:52 +0200)
committerFilippo Valsorda <filippo@golang.org>
Wed, 21 May 2025 20:47:32 +0000 (13:47 -0700)
For #69536

Change-Id: If237226ba03e282443b4fc90484968c903198cb1
Reviewed-on: https://go-review.googlesource.com/c/go/+/616715
Reviewed-by: Junyang Shao <shaojunyang@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
src/internal/cpu/cpu.go
src/internal/cpu/cpu_arm64.go
src/internal/cpu/cpu_arm64_darwin.go
src/internal/cpu/cpu_arm64_hwcap.go

index e07463f87025250d9fb436a3115d3e187937c178..760dc0b469d83d355ef0cc020d5309870db8da07 100644 (file)
@@ -70,6 +70,7 @@ var ARM64 struct {
        HasSHA1    bool
        HasSHA2    bool
        HasSHA512  bool
+       HasSHA3    bool
        HasCRC32   bool
        HasATOMICS bool
        HasCPUID   bool
index 1365991e783492a397ec99bbca06ca2f182cc0a8..7709966d5706bba359acb58660392df98fab9026 100644 (file)
@@ -16,6 +16,7 @@ func doinit() {
                {Name: "sha1", Feature: &ARM64.HasSHA1},
                {Name: "sha2", Feature: &ARM64.HasSHA2},
                {Name: "sha512", Feature: &ARM64.HasSHA512},
+               {Name: "sha3", Feature: &ARM64.HasSHA3},
                {Name: "crc32", Feature: &ARM64.HasCRC32},
                {Name: "atomics", Feature: &ARM64.HasATOMICS},
                {Name: "cpuid", Feature: &ARM64.HasCPUID},
@@ -38,6 +39,7 @@ func extractBits(data uint64, start, end uint) uint {
 
 func parseARM64SystemRegisters(isar0, pfr0 uint64) {
        // ID_AA64ISAR0_EL1
+       // https://developer.arm.com/documentation/ddi0601/2025-03/AArch64-Registers/ID-AA64ISAR0-EL1--AArch64-Instruction-Set-Attribute-Register-0
        switch extractBits(isar0, 4, 7) {
        case 1:
                ARM64.HasAES = true
@@ -69,6 +71,11 @@ func parseARM64SystemRegisters(isar0, pfr0 uint64) {
                ARM64.HasATOMICS = true
        }
 
+       switch extractBits(isar0, 32, 35) {
+       case 1:
+               ARM64.HasSHA3 = true
+       }
+
        switch extractBits(pfr0, 48, 51) {
        case 1:
                ARM64.HasDIT = true
index 57cf631e891b0acc040a3a35aaa6aa5174ec49eb..28b47d60e8aecfe5d568dc404359051dc3d98be2 100644 (file)
@@ -9,15 +9,21 @@ package cpu
 import _ "unsafe" // for linkname
 
 func osInit() {
+       // macOS 12 moved these to the hw.optional.arm tree, but as of Go 1.24 we
+       // still support macOS 11. See [Determine Encryption Capabilities].
+       //
+       // [Determine Encryption Capabilities]: https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#3918855
        ARM64.HasATOMICS = sysctlEnabled([]byte("hw.optional.armv8_1_atomics\x00"))
        ARM64.HasCRC32 = sysctlEnabled([]byte("hw.optional.armv8_crc32\x00"))
        ARM64.HasSHA512 = sysctlEnabled([]byte("hw.optional.armv8_2_sha512\x00"))
+       ARM64.HasSHA3 = sysctlEnabled([]byte("hw.optional.armv8_2_sha3\x00"))
+
        ARM64.HasDIT = sysctlEnabled([]byte("hw.optional.arm.FEAT_DIT\x00"))
 
-       // There are no hw.optional sysctl values for the below features on Mac OS 11.0
-       // to detect their supported state dynamically. Assume the CPU features that
-       // Apple Silicon M1 supports to be available as a minimal set of features
-       // to all Go programs running on darwin/arm64.
+       // There are no hw.optional sysctl values for the below features on macOS 11
+       // to detect their supported state dynamically (although they are available
+       // in the hw.optional.arm tree on macOS 12). Assume the CPU features that
+       // Apple Silicon M1 supports to be available on all future iterations.
        ARM64.HasAES = true
        ARM64.HasPMULL = true
        ARM64.HasSHA1 = true
index e6711ae275a0f2e5ab50fc67d19acbbdfe710544..b6cc1f4d988877085d4402db4919840d9110c46a 100644 (file)
@@ -22,6 +22,7 @@ import _ "unsafe" // for linkname
 var HWCap uint
 
 // HWCAP bits. These are exposed by Linux.
+// See arch/arm64/include/uapi/asm/hwcap.h.
 const (
        hwcap_AES     = 1 << 3
        hwcap_PMULL   = 1 << 4
@@ -30,18 +31,21 @@ const (
        hwcap_CRC32   = 1 << 7
        hwcap_ATOMICS = 1 << 8
        hwcap_CPUID   = 1 << 11
+       hwcap_SHA3    = 1 << 17
        hwcap_SHA512  = 1 << 21
        hwcap_DIT     = 1 << 24
 )
 
 func hwcapInit(os string) {
        // HWCap was populated by the runtime from the auxiliary vector.
+       // See https://docs.kernel.org/arch/arm64/elf_hwcaps.html.
        // Use HWCap information since reading aarch64 system registers
        // is not supported in user space on older linux kernels.
        ARM64.HasAES = isSet(HWCap, hwcap_AES)
        ARM64.HasPMULL = isSet(HWCap, hwcap_PMULL)
        ARM64.HasSHA1 = isSet(HWCap, hwcap_SHA1)
        ARM64.HasSHA2 = isSet(HWCap, hwcap_SHA2)
+       ARM64.HasSHA3 = isSet(HWCap, hwcap_SHA3)
        ARM64.HasCRC32 = isSet(HWCap, hwcap_CRC32)
        ARM64.HasCPUID = isSet(HWCap, hwcap_CPUID)
        ARM64.HasSHA512 = isSet(HWCap, hwcap_SHA512)