Skip to content

Commit

Permalink
Use "-openssl=auto" by default
Browse files Browse the repository at this point in the history
Go GCM is faster than OpenSSL if the CPU has AES instructions
and you are running Go 1.6+.

See #23 for details.
  • Loading branch information
rfjakob committed May 11, 2016
1 parent 384342f commit 58fa5b2
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 4 deletions.
6 changes: 4 additions & 2 deletions Documentation/MANPAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,10 @@ continue be printed to stdout and stderr.
used internally for daemonization.

**-openssl bool**
: Use OpenSSL instead of built-in Go crypto (default true). Using
built-in crypto is 4x slower.
: Use OpenSSL instead of built-in Go crypto (default "auto"). Using
built-in crypto is 4x slower unless you CPU has AES instructions and
you are using Go 1.6+. In mode "auto", gocrypts chooses the faster
option.

**-passwd**
: Change password
Expand Down
9 changes: 9 additions & 0 deletions internal/stupidgcm/prefer_go1.5.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// +build !go1.6
// = go 1.5 or lower

package stupidgcm

func PreferOpenSSL() bool {
// OpenSSL is always faster than Go GCM on old Go versions.
return true
}
31 changes: 31 additions & 0 deletions internal/stupidgcm/prefer_go1.6.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// +build go1.6
// = go 1.6 or higher

package stupidgcm

import (
"fmt"
"io/ioutil"
"regexp"
"runtime"
)

// PreferOpenSSL tells us if OpenSSL is faster than Go GCM on this machine.
// Go GCM is fastern when the CPU has AES instructions and Go is v1.6 or higher.
//
// See https://github.com/rfjakob/gocryptfs/issues/23#issuecomment-218286502
// for benchmarks.
func PreferOpenSSL() bool {
runtime.G
ci, err := ioutil.ReadFile("/proc/cpuinfo")
if err != nil {
fmt.Println(err)
return true
}
match, err := regexp.Match("(?m)^flags.*\baes\b", ci)
if err != nil {
fmt.Println(err)
return true
}
return match
}
10 changes: 10 additions & 0 deletions internal/stupidgcm/stupidgcm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"crypto/cipher"
"crypto/rand"
"encoding/hex"
"fmt"
"testing"
)

Expand All @@ -26,6 +27,15 @@ func randBytes(n int) []byte {
return b
}

func TestPreferOpenSSL(t *testing.T) {
h := PreferOpenSSL()
p := "Go GCM"
if h {
p = "OpenSSL"
}
fmt.Printf("PreferOpenSSL=%v, gocryptfs will prefer %s\n", h, p)
}

// TestEncryptDecrypt encrypts and decrypts using both stupidgcm and Go's built-in
// GCM implemenatation and verifies that the results are identical.
func TestEncryptDecrypt(t *testing.T) {
Expand Down
18 changes: 16 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"path/filepath"
"runtime"
"runtime/pprof"
"strconv"
"syscall"
"time"

Expand All @@ -25,6 +26,7 @@ import (
"github.com/rfjakob/gocryptfs/internal/cryptocore"
"github.com/rfjakob/gocryptfs/internal/fusefrontend"
"github.com/rfjakob/gocryptfs/internal/nametransform"
"github.com/rfjakob/gocryptfs/internal/stupidgcm"
"github.com/rfjakob/gocryptfs/internal/toggledlog"
)

Expand Down Expand Up @@ -149,14 +151,15 @@ func main() {
setupColors()

// Parse command line arguments
var opensslAuto string
flagSet = flag.NewFlagSet(toggledlog.ProgramName, flag.ExitOnError)
flagSet.Usage = usageText
flagSet.BoolVar(&args.debug, "d", false, "")
flagSet.BoolVar(&args.debug, "debug", false, "Enable debug output")
flagSet.BoolVar(&args.fusedebug, "fusedebug", false, "Enable fuse library debug output")
flagSet.BoolVar(&args.init, "init", false, "Initialize encrypted directory")
flagSet.BoolVar(&args.zerokey, "zerokey", false, "Use all-zero dummy master key")
flagSet.BoolVar(&args.openssl, "openssl", true, "Use OpenSSL instead of built-in Go crypto")
flagSet.StringVar(&opensslAuto, "openssl", "auto", "Use OpenSSL instead of built-in Go crypto")
flagSet.BoolVar(&args.passwd, "passwd", false, "Change password")
flagSet.BoolVar(&args.foreground, "f", false, "Stay in the foreground")
flagSet.BoolVar(&args.version, "version", false, "Print version and exit")
Expand All @@ -180,6 +183,17 @@ func main() {
"Setting this to a lower value speeds up mounting but makes the password susceptible to brute-force attacks")
flagSet.Parse(os.Args[1:])

// "-openssl" needs some post-processing
if opensslAuto == "auto" {
args.openssl = stupidgcm.PreferOpenSSL()
} else {
args.openssl, err = strconv.ParseBool(opensslAuto)
if err != nil {
fmt.Printf(colorRed+"Invalid \"-openssl\" setting: %v\n"+colorReset, err)
os.Exit(ERREXIT_USAGE)
}
}

// Fork a child into the background if "-f" is not set AND we are mounting a filesystem
if !args.foreground && flagSet.NArg() == 2 {
forkChild() // does not return
Expand Down Expand Up @@ -255,7 +269,7 @@ func main() {
}
// "-openssl"
if args.openssl == false {
toggledlog.Info.Printf("Openssl disabled")
toggledlog.Info.Printf("OpenSSL disabled, using Go GCM")
}
// Operation flags: init, passwd or mount
// "-init"
Expand Down

0 comments on commit 58fa5b2

Please sign in to comment.