Skip to content

Commit 8091d05

Browse files
authored
Merge pull request #299 from AkihiroSuda/aesni
sshutil: prioritize [email protected] when AES acceleration is available (roughly 60% faster on Intel Mac)
2 parents 7e8016a + 483264f commit 8091d05

File tree

4 files changed

+81
-0
lines changed

4 files changed

+81
-0
lines changed

pkg/sshutil/sshutil.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,18 @@ func CommonArgs(useDotSSH bool) ([]string, error) {
158158
"-o", "IdentitiesOnly=yes",
159159
"-F", "/dev/null",
160160
)
161+
162+
// By default, `ssh` choose [email protected], even when AES accelerator is available.
163+
// (OpenSSH_8.1p1, macOS 11.6, MacBookPro 2020, Core i7-1068NG7)
164+
//
165+
// We prioritize AES algorithms when AES accelerator is available.
166+
if aesAccelerated {
167+
logrus.Debugf("AES accelerator seems available, prioritizing [email protected] and [email protected]")
168+
args = append(args, "-o", "Ciphers=^[email protected],[email protected]")
169+
} else {
170+
logrus.Debugf("AES accelerator does not seem available, prioritizing [email protected]")
171+
args = append(args, "-o", "Ciphers=^[email protected]")
172+
}
161173
return args, nil
162174
}
163175

@@ -182,3 +194,8 @@ func SSHArgs(instDir string, useDotSSH bool) ([]string, error) {
182194
)
183195
return args, nil
184196
}
197+
198+
// aesAccelerated is set to true when AES acceleration is available.
199+
//
200+
// Available on almost all modern Intel/AMD processors.
201+
var aesAccelerated = detectAESAcceleration()

pkg/sshutil/sshutil_darwin.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package sshutil
2+
3+
import (
4+
"fmt"
5+
"runtime"
6+
"strings"
7+
"syscall"
8+
9+
"github.com/sirupsen/logrus"
10+
)
11+
12+
func detectAESAcceleration() bool {
13+
switch runtime.GOARCH {
14+
case "amd64":
15+
const fallback = true
16+
features, err := syscall.Sysctl("machdep.cpu.features") // not available on M1
17+
if err != nil {
18+
err = fmt.Errorf("failed to read sysctl \"machdep.cpu.features\": %w", err)
19+
logrus.WithError(err).Warnf("failed to detect whether AES accelerator is available, assuming %v", fallback)
20+
return fallback
21+
}
22+
return strings.Contains(features, "AES ")
23+
default:
24+
// According to https://gist.github.com/voluntas/fd279c7b4e71f9950cfd4a5ab90b722b ,
25+
// aes-128-gcm is faster than chacha20-poly1305 on Apple M1.
26+
return true
27+
}
28+
}

pkg/sshutil/sshutil_linux.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package sshutil
2+
3+
import (
4+
"os"
5+
"runtime"
6+
"strings"
7+
8+
"github.com/sirupsen/logrus"
9+
)
10+
11+
func detectAESAcceleration() bool {
12+
const fallback = runtime.GOARCH == "amd64"
13+
cpuinfo, err := os.ReadFile("/proc/cpuinfo")
14+
if err != nil {
15+
logrus.WithError(err).Warnf("failed to detect whether AES accelerator is available, assuming %v", fallback)
16+
return fallback
17+
}
18+
// Checking "aes " should be enough for x86_64 and aarch64
19+
return strings.Contains(string(cpuinfo), "aes ")
20+
}

pkg/sshutil/sshutil_others.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//go:build !darwin && !linux
2+
// +build !darwin,!linux
3+
4+
package sshutil
5+
6+
import (
7+
"runtime"
8+
9+
"github.com/sirupsen/logrus"
10+
)
11+
12+
func detectAESAcceleration() bool {
13+
const fallback = runtime.GOARCH == "amd64"
14+
logrus.WithError(err).Warnf("cannot detect whether AES accelerator is available, assuming %v", fallback)
15+
return fallback
16+
}

0 commit comments

Comments
 (0)