Skip to content

Commit

Permalink
fix: add support for darwin/arm64 (#7)
Browse files Browse the repository at this point in the history
This diff ensures we hardcode the capabilities of darwin/arm64.

While there, strive to make the packages naming slightly less confusing.

Reference issue: ooni/probe#2122.

Surpersedes (and draws from) #5.

Co-authored-by: ain ghazal ainghazal42@gmail.com

Co-authored-by: ain ghazal <ainghazal42@gmail.com>
  • Loading branch information
bassosimone and ainghazal authored Aug 18, 2022
1 parent 72b2086 commit d01c7ff
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 48 deletions.
6 changes: 3 additions & 3 deletions aes/cipher_asm.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ package aes
import (
"crypto/cipher"

"github.com/ooni/oocrypto/internal/cpuarm64"
"github.com/ooni/oocrypto/internal/cpuoverlay"
"github.com/ooni/oocrypto/internal/subtle"
"golang.org/x/sys/cpu"
)
Expand All @@ -29,8 +29,8 @@ type aesCipherAsm struct {
aesCipher
}

var supportsAES = cpu.X86.HasAES || cpuarm64.HasAES()
var supportsGFMUL = cpu.X86.HasPCLMULQDQ || cpuarm64.HasPMULL()
var supportsAES = cpu.X86.HasAES || cpuoverlay.Arm64HasAES()
var supportsGFMUL = cpu.X86.HasPCLMULQDQ || cpuoverlay.Arm64HasPMULL()

// aesCipherGCM implements crypto/cipher.gcmAble so that crypto/cipher.NewGCM
// will use the optimised implementation in aes_gcm.go when possible.
Expand Down
15 changes: 0 additions & 15 deletions internal/cpuarm64/cpuarm64_otherwise.go

This file was deleted.

22 changes: 0 additions & 22 deletions internal/cpuarm64/doc.go

This file was deleted.

22 changes: 22 additions & 0 deletions internal/cpuoverlay/cpoverlay_otherwise.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//go:build !arm64 || (!darwin && !android)

package cpuoverlay

import "golang.org/x/sys/cpu"

//
// This file is built when we're not on arm64 or we're on windows/arm64. In the
// former case, just returning false would do. In the latter case, the right thing
// to do is to return cpu.ARM64.HasXXX. Because cpu.ARM64.HasXXX are always false
// when not on arm64, we conflate these two cases in a single file.
//

// arm64HasAES returns whether the CPU supports AES.
func arm64HasAES() bool {
return cpu.ARM64.HasAES
}

// arm64HasPMULL returns whether the CPU supports PMULL.
func arm64HasPMULL() bool {
return cpu.ARM64.HasPMULL
}
44 changes: 44 additions & 0 deletions internal/cpuoverlay/cpuoverlay.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Package cpuoverlay is a logic overlay on top of x/sys/cpu that
// attempts to avoid cases in which x/sys/cpu is wrong.
//
// android/arm64
//
// The main problem that we want to solve is that on Android there are
// cases where reading /proc/self/auxv is not possible.
//
// This causes crypto/tls to not choose AES where it would otherwise
// be possible, in turn causing censorship. See also the
// https://github.com/ooni/probe/issues/1444 issue for more details.
//
// Ideally we would like to call getauxval(3) when initializing
// the runtime package. However, runtime cannot use CGO. Doing that
// leads to an import loop, so we cannot build.
//
// Until this is fixed in src/runtime, we call getauxval(3) here.
//
// darwin/arm64
//
// Additionally, we may use this package to solve other CPU issues. For
// example, x/sys/cpu does not currently know about darwin/arm64 features.
//
// Design
//
// This package contains GOOS/GOARCH-specific files with predicate
// functions returning the correct value in cases in which x/sys/cpu
// is wrong. You are expected to replace the code that normally
// lives inside src/crypto/tls and src/cryto/aes and that we have
// forked in this repository such that you call the predicates
// of this package as opposed to using directly x/sys/cpu values.
package cpuoverlay

// We dispatch to GOOS/GOARCH specific implementations

// Arm64HasAES returns whether the CPU supports AES.
func Arm64HasAES() bool {
return arm64HasAES()
}

// Arm64HasPMULL returns whether the CPU supports PMULL.
func Arm64HasPMULL() bool {
return arm64HasPMULL()
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build android && arm64
//go:build arm64 && android

// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
Expand All @@ -7,7 +7,13 @@
// This file is based on the diff available at
// https://go-review.googlesource.com/c/sys/+/197540/

package cpuarm64
package cpuoverlay

//
// On android/arm64 /proc/sys/auxv is not readable on most
// systems, therefore we need to call getauxval to load the
// correct values, otherwise we think there's no HW AES.
//

/*
#include <sys/auxv.h>
Expand Down Expand Up @@ -67,12 +73,12 @@ const (
hwcap_CPUID = 1 << 11
)

// HasAES returns whether the CPU supports AES.
func HasAES() bool {
// arm64HasAES returns whether the CPU supports AES.
func arm64HasAES() bool {
return (gethwcap() & hwcap_AES) != 0
}

// HasPMULL returns whether the CPU supports PMULL.
func HasPMULL() bool {
// arm64HasPMULL returns whether the CPU supports PMULL.
func arm64HasPMULL() bool {
return (gethwcap() & hwcap_PMULL) != 0
}
24 changes: 24 additions & 0 deletions internal/cpuoverlay/cpuoverlay_darwin_arm64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//go:build arm64 && darwin

package cpuoverlay

//
// As documented below, there's no support for detecting the
// capabilities of darwin/arm64 in x/sys/cpu so we're going to
// do what internal/cpu currently is doing, i.e., hardcoding
// true because we know M1 supports these HW capabilities.
//
// See https://github.com/ooni/probe/issues/2122
//
// See https://github.com/golang/go/issues/43046
//

// arm64HasAES returns whether the CPU supports AES.
func arm64HasAES() bool {
return true
}

// arm64HasPMULL returns whether the CPU supports PMULL.
func arm64HasPMULL() bool {
return true
}
4 changes: 2 additions & 2 deletions tls/cipher_suites.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (

"github.com/ooni/oocrypto/aes"
"github.com/ooni/oocrypto/internal/boring"
"github.com/ooni/oocrypto/internal/cpuarm64"
"github.com/ooni/oocrypto/internal/cpuoverlay"
"golang.org/x/crypto/chacha20poly1305"
"golang.org/x/sys/cpu"
)
Expand Down Expand Up @@ -357,7 +357,7 @@ var defaultCipherSuitesTLS13NoAES = []uint16{

var (
hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ
hasGCMAsmARM64 = cpuarm64.HasAES() && cpuarm64.HasPMULL()
hasGCMAsmARM64 = cpuoverlay.Arm64HasAES() && cpuoverlay.Arm64HasPMULL()
// Keep in sync with crypto/aes/cipher_s390x.go.
hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR &&
(cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)
Expand Down

0 comments on commit d01c7ff

Please sign in to comment.