From fffb189cb543f51e3db21be9c22d91d2cf3be363 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 11 Mar 2019 15:01:47 +0900 Subject: [PATCH] use ChaCha if one of the peers doesn't have AES hardware support --- crypto.go | 33 +++++++++++++++++++++++++++++---- go.mod | 2 +- package.json | 6 ++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/crypto.go b/crypto.go index 2b9cd52..c0ac657 100644 --- a/crypto.go +++ b/crypto.go @@ -13,6 +13,8 @@ import ( "math/big" "time" + "golang.org/x/sys/cpu" + crypto "github.com/libp2p/go-libp2p-crypto" ic "github.com/libp2p/go-libp2p-crypto" peer "github.com/libp2p/go-libp2p-peer" @@ -40,10 +42,11 @@ func NewIdentity(privKey ic.PrivKey) (*Identity, error) { } return &Identity{ config: tls.Config{ - MinVersion: tls.VersionTLS13, - InsecureSkipVerify: true, // This is not insecure here. We will verify the cert chain ourselves. - ClientAuth: tls.RequireAnyClientCert, - Certificates: []tls.Certificate{*cert}, + MinVersion: tls.VersionTLS13, + PreferServerCipherSuites: preferServerCipherSuites(), + InsecureSkipVerify: true, // This is not insecure here. We will verify the cert chain ourselves. + ClientAuth: tls.RequireAnyClientCert, + Certificates: []tls.Certificate{*cert}, VerifyPeerCertificate: func(_ [][]byte, _ [][]*x509.Certificate) error { panic("tls config not specialized for peer") }, @@ -194,3 +197,25 @@ func keyToCertificate(sk ic.PrivKey) (*tls.Certificate, error) { PrivateKey: certKey, }, nil } + +// We want nodes without AES hardware (e.g. ARM) support to always use ChaCha. +// Only if both nodes have AES hardware support (e.g. x86), AES should be used. +// x86->x86: AES, ARM->x86: ChaCha, x86->ARM: ChaCha and ARM->ARM: Chacha +// This function returns true if we don't have AES hardware support, and false otherwise. +// Thus, ARM servers will always use their own cipher suite preferences (ChaCha first), +// and x86 servers will aways use the client's cipher suite preferences. +func preferServerCipherSuites() bool { + // Copied from the Go TLS implementation. + + // Check the cpu flags for each platform that has optimized GCM implementations. + // Worst case, these variables will just all be false. + var ( + hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ + hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL + // 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) + + hasGCMAsm = hasGCMAsmAMD64 || hasGCMAsmARM64 || hasGCMAsmS390X + ) + return !hasGCMAsm +} diff --git a/go.mod b/go.mod index d1a70ad..30340cc 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 // indirect golang.org/x/net v0.0.0-20190310074541-c10a0554eabf // indirect golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 // indirect - golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa // indirect + golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 // indirect gopkg.in/yaml.v2 v2.2.2 // indirect ) diff --git a/package.json b/package.json index 2bc7d04..19d87a0 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,12 @@ "hash": "QmbyjEKtxXmZdiByBiNhfayzEuEPPBvuD2dLpHky8cHUvy", "name": "go-conn-security", "version": "0.1.20" + }, + { + "author": "marten-seemann", + "hash": "QmauyZ2BbYbcTJr1RudEsbQoKNgKkZi9pDZBJVyzw3uJD4", + "name": "cpu", + "version": "0.1.0" } ], "gxVersion": "0.12.1",