diff options
| -rw-r--r-- | cryptfs/cryptfs.go | 15 | ||||
| -rw-r--r-- | cryptfs/cryptfs_content.go | 3 | ||||
| -rw-r--r-- | cryptfs/openssl_aead.go | 93 | ||||
| -rw-r--r-- | frontend/fe_fs.go | 4 | ||||
| -rw-r--r-- | main.go | 3 | 
5 files changed, 110 insertions, 8 deletions
| diff --git a/cryptfs/cryptfs.go b/cryptfs/cryptfs.go index 9ec511a..40a9024 100644 --- a/cryptfs/cryptfs.go +++ b/cryptfs/cryptfs.go @@ -20,21 +20,26 @@ type CryptFS struct {  	cipherBS uint64  } -func NewCryptFS(key [16]byte) *CryptFS { +func NewCryptFS(key [16]byte, useOpenssl bool) *CryptFS {  	b, err := aes.NewCipher(key[:])  	if err != nil {  		panic(err)  	} -	g, err := cipher.NewGCM(b) -	if err != nil { -		panic(err) +	var gcm cipher.AEAD +	if useOpenssl { +		gcm = opensslGCM{key} +	} else { +		gcm, err = cipher.NewGCM(b) +		if err != nil { +			panic(err) +		}  	}  	return &CryptFS{  		blockCipher: b, -		gcm: g, +		gcm: gcm,  		plainBS: DEFAULT_PLAINBS,  		cipherBS: DEFAULT_PLAINBS + NONCE_LEN + AUTH_TAG_LEN,  	} diff --git a/cryptfs/cryptfs_content.go b/cryptfs/cryptfs_content.go index 512bca9..4658529 100644 --- a/cryptfs/cryptfs_content.go +++ b/cryptfs/cryptfs_content.go @@ -49,8 +49,11 @@ func (be *CryptFS) DecryptBlock(ciphertext []byte) ([]byte, error) {  	// Decrypt  	var plaintext []byte +  	plaintext, err := be.gcm.Open(plaintext, nonce, ciphertext, nil) +  	if err != nil { +		Warn.Printf("DecryptBlock: %s\n", err.Error())  		return nil, err  	} diff --git a/cryptfs/openssl_aead.go b/cryptfs/openssl_aead.go new file mode 100644 index 0000000..02f50d8 --- /dev/null +++ b/cryptfs/openssl_aead.go @@ -0,0 +1,93 @@ +package cryptfs + +// Implements cipher.AEAD with OpenSSL backend + +import ( +	"bytes" +	"github.com/spacemonkeygo/openssl" +) + +type opensslGCM struct { +	key [16]byte +} + +func (be opensslGCM) Overhead() int { +	return AUTH_TAG_LEN +} + +func (be opensslGCM) NonceSize() int { +	return NONCE_LEN +} + +// Seal encrypts and authenticates plaintext, authenticates the +// additional data and appends the result to dst, returning the updated +// slice. The nonce must be NonceSize() bytes long and unique for all +// time, for a given key. +// +// The plaintext and dst may alias exactly or not at all. +func (be opensslGCM) Seal(dst, nonce, plaintext, data []byte) []byte { + +	cipherBuf := bytes.NewBuffer(dst) + +	ectx, err := openssl.NewGCMEncryptionCipherCtx(128, nil, be.key[:], nonce[:]) +	if err != nil { +		panic(err) +	} +	part, err := ectx.EncryptUpdate(plaintext) +	if err != nil { +		panic(err) +	} +	cipherBuf.Write(part) +	part, err = ectx.EncryptFinal() +	if err != nil { +		panic(err) +	} +	cipherBuf.Write(part) +	part, err = ectx.GetTag() +	if err != nil { +		panic(err) +	} +	cipherBuf.Write(part) + +	return cipherBuf.Bytes() +} + +// Open decrypts and authenticates ciphertext, authenticates the +// additional data and, if successful, appends the resulting plaintext +// to dst, returning the updated slice. The nonce must be NonceSize() +// bytes long and both it and the additional data must match the +// value passed to Seal. +// +// The ciphertext and dst may alias exactly or not at all. +func (be opensslGCM) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) { + +	if len(data) > 0 { +		panic("Extra data is not supported") +	} + +	l := len(ciphertext) +	tag := ciphertext[l-AUTH_TAG_LEN:l] +	ciphertext = ciphertext[0:l-AUTH_TAG_LEN] +	plainBuf := bytes.NewBuffer(dst) + +	dctx, err := openssl.NewGCMDecryptionCipherCtx(128, nil, be.key[:], nonce[:]) +	if err != nil { +		return nil, err +	} +	part, err := dctx.DecryptUpdate(ciphertext) +	if err != nil { +		return nil, err +	} +	plainBuf.Write(part) +	err = dctx.SetTag(tag) +	if err != nil { +		return nil, err +	} +	part, err = dctx.DecryptFinal() +	if err != nil { +		return nil, err +	} +	plainBuf.Write(part) + +	return plainBuf.Bytes(), nil +} diff --git a/frontend/fe_fs.go b/frontend/fe_fs.go index 012d7f0..4d49194 100644 --- a/frontend/fe_fs.go +++ b/frontend/fe_fs.go @@ -27,14 +27,14 @@ type nullTracer struct {}  func (nullTracer) Trace(op cluefs.FsOperTracer) {} -func NewFS(key [16]byte, backing string) *FS { +func NewFS(key [16]byte, backing string, useOpenssl bool) *FS {  	var nt nullTracer  	clfs, err := cluefs.NewClueFS(backing, nt)  	if err != nil {  		panic(err)  	}  	return &FS { -		CryptFS: cryptfs.NewCryptFS(key), +		CryptFS: cryptfs.NewCryptFS(key, useOpenssl),  		ClueFS: clfs,  		backing: backing,  	} @@ -11,6 +11,7 @@ import (  const (  	PROGRAM_NAME = "gocryptfs" +	USE_OPENSSL = true  )  func main() { @@ -22,7 +23,7 @@ func main() {  	// Create the file system object  	var key [16]byte -	cfs := frontend.NewFS(key, conf.GetShadowDir()) +	cfs := frontend.NewFS(key, conf.GetShadowDir(), USE_OPENSSL)  	// Mount the file system  	mountOpts := []fuse.MountOption{ | 
