Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add support for darwin/arm64 #7

Merged
merged 4 commits into from
Aug 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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