diff options
| author | Jakob Unterwurzacher | 2015-12-19 14:41:39 +0100 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2015-12-19 15:02:29 +0100 | 
| commit | 1caa9258685fa5fad8935d3bfcd0eac7d7f84f1e (patch) | |
| tree | abc1e46f269f9ef8f05d812e13fcdf2bae68d298 | |
| parent | 88826dc51d7919ef8b190c079955230e653323e2 (diff) | |
Increase GCM IV size from 96 to 128 bits
This pushes back the birthday bound for collisions to make it virtually
irrelevant.
| -rw-r--r-- | Documentation/MANPAGE.md | 5 | ||||
| -rw-r--r-- | Documentation/SECURITY.md | 2 | ||||
| -rw-r--r-- | Documentation/file-format.md | 32 | ||||
| -rw-r--r-- | cryptfs/address_translation.go | 4 | ||||
| -rw-r--r-- | cryptfs/config_file.go | 11 | ||||
| -rw-r--r-- | cryptfs/content_test.go | 6 | ||||
| -rw-r--r-- | cryptfs/cryptfs.go | 26 | ||||
| -rw-r--r-- | cryptfs/cryptfs_content.go | 8 | ||||
| -rw-r--r-- | cryptfs/names_test.go | 4 | ||||
| -rw-r--r-- | cryptfs/nonce.go | 11 | ||||
| -rw-r--r-- | cryptfs/openssl_aead.go | 7 | ||||
| -rw-r--r-- | integration_tests/example_filesystems/v0.7/AgD7i9tiAUp42SYjULQt1w== | bin | 0 -> 60 bytes | |||
| l--------- | integration_tests/example_filesystems/v0.7/FQnvM-qOnCYSnk368ugdWg== | 1 | ||||
| l--------- | integration_tests/example_filesystems/v0.7/Pvg7Oy_Ar8Ar93EZZQV_Lw== | 1 | ||||
| -rw-r--r-- | integration_tests/example_filesystems/v0.7/gocryptfs.conf | 16 | ||||
| -rw-r--r-- | integration_tests/example_filesystems/v0.7/gocryptfs.diriv | 1 | ||||
| -rw-r--r-- | integration_tests/example_filesystems_test.go | 35 | ||||
| -rw-r--r-- | main.go | 5 | ||||
| -rw-r--r-- | pathfs_frontend/args.go | 1 | ||||
| -rw-r--r-- | pathfs_frontend/file.go | 2 | ||||
| -rw-r--r-- | pathfs_frontend/fs.go | 2 | 
21 files changed, 141 insertions, 39 deletions
| diff --git a/Documentation/MANPAGE.md b/Documentation/MANPAGE.md index 446ce37..2e440b2 100644 --- a/Documentation/MANPAGE.md +++ b/Documentation/MANPAGE.md @@ -57,6 +57,11 @@ to mount the gocryptfs filesytem without user interaction.  **-fusedebug**  :	Enable fuse library debug output +**-gcmiv128** +:	Use an 128-bit IV for GCM encryption instead of Go's default of +96 bits (default true). This pushes back the birthday bound for IV +collisions far enough to make it irrelevant. +  **-init**  :	Initialize encrypted directory diff --git a/Documentation/SECURITY.md b/Documentation/SECURITY.md index dff2fab..a49994a 100644 --- a/Documentation/SECURITY.md +++ b/Documentation/SECURITY.md @@ -18,7 +18,7 @@ File Contents  All file contents are encrypted using AES-256-GCM (Galois/Counter Mode).  Files are segmented into 4KB blocks. Each block gets a fresh random -96 bit IV each time it is modified. A 128-bit authentication tag (GHASH) +128 bit IV each time it is modified. A 128-bit authentication tag (GHASH)  protects each block from modifications.  Each file has a header containing a random 128-bit file ID. The diff --git a/Documentation/file-format.md b/Documentation/file-format.md new file mode 100644 index 0000000..b0d4b55 --- /dev/null +++ b/Documentation/file-format.md @@ -0,0 +1,32 @@ +File Format +=========== + +Header + +	 2 bytes header version (big endian uint16, currently 2) +	16 bytes file id + +Data block + +	16 bytes GCM IV (nonce) +	1-4096 bytes encrypted data +	16 bytes GHASH + + +Example: 1-byte file +-------------------- + +	Header     18 bytes +	Data block 33 bytes + +Total: 51 bytes + + +Example: 5000-byte file +----------------------- + +	Header       18 bytes +	Data block 4128 bytes +	Data block  936 bytes + +Total: 5082 bytes diff --git a/cryptfs/address_translation.go b/cryptfs/address_translation.go index 147040c..b21cfc7 100644 --- a/cryptfs/address_translation.go +++ b/cryptfs/address_translation.go @@ -44,7 +44,7 @@ func (be *CryptFS) CipherSizeToPlainSize(cipherSize uint64) uint64 {  	blockNo := be.CipherOffToBlockNo(cipherSize - 1)  	blockCount := blockNo + 1 -	overhead := BLOCK_OVERHEAD*blockCount + HEADER_LEN +	overhead := be.BlockOverhead()*blockCount + HEADER_LEN  	return cipherSize - overhead  } @@ -56,7 +56,7 @@ func (be *CryptFS) PlainSizeToCipherSize(plainSize uint64) uint64 {  	blockNo := be.PlainOffToBlockNo(plainSize - 1)  	blockCount := blockNo + 1 -	overhead := BLOCK_OVERHEAD*blockCount + HEADER_LEN +	overhead := be.BlockOverhead()*blockCount + HEADER_LEN  	return plainSize + overhead  } diff --git a/cryptfs/config_file.go b/cryptfs/config_file.go index 48e5474..138426a 100644 --- a/cryptfs/config_file.go +++ b/cryptfs/config_file.go @@ -46,6 +46,7 @@ func CreateConfFile(filename string, password string, plaintextNames bool, logN  	cf.EncryptKey(key, password, logN)  	// Set feature flags +	cf.FeatureFlags = append(cf.FeatureFlags, FlagGCMIV128)  	if plaintextNames {  		cf.FeatureFlags = append(cf.FeatureFlags, FlagPlaintextNames)  	} else { @@ -94,7 +95,7 @@ func LoadConfFile(filename string, password string) ([]byte, *ConfFile, error) {  	// Unlock master key using password-based key  	// We use stock go GCM instead of OpenSSL here as speed is not important  	// and we get better error messages -	cfs := NewCryptFS(scryptHash, false, false) +	cfs := NewCryptFS(scryptHash, false, false, false)  	key, err := cfs.DecryptBlock(cf.EncryptedKey, 0, nil)  	if err != nil {  		Warn.Printf("failed to unlock master key: %s\n", err.Error()) @@ -115,7 +116,7 @@ func (cf *ConfFile) EncryptKey(key []byte, password string, logN int) {  	scryptHash := cf.ScryptObject.DeriveKey(password)  	// Lock master key using password-based key -	cfs := NewCryptFS(scryptHash, false, false) +	cfs := NewCryptFS(scryptHash, false, false, false)  	cf.EncryptedKey = cfs.EncryptBlock(key, 0, nil)  } @@ -155,16 +156,18 @@ func (cf *ConfFile) WriteFile() error {  const (  	// Understood Feature Flags. -	// Also teach isFeatureFlagKnown() about any additions +	// Also teach isFeatureFlagKnown() about any additions and +	// add it to CreateConfFile() if you want to have it enabled by default.  	FlagPlaintextNames = "PlaintextNames"  	FlagDirIV          = "DirIV"  	FlagEMENames       = "EMENames" +	FlagGCMIV128       = "GCMIV128"  )  // Verify that we understand a feature flag  func (cf *ConfFile) isFeatureFlagKnown(flag string) bool {  	switch flag { -	case FlagPlaintextNames, FlagDirIV, FlagEMENames: +	case FlagPlaintextNames, FlagDirIV, FlagEMENames, FlagGCMIV128:  		return true  	default:  		return false diff --git a/cryptfs/content_test.go b/cryptfs/content_test.go index 1b269bd..3efa959 100644 --- a/cryptfs/content_test.go +++ b/cryptfs/content_test.go @@ -21,7 +21,7 @@ func TestSplitRange(t *testing.T) {  		testRange{6654, 8945})  	key := make([]byte, KEY_LEN) -	f := NewCryptFS(key, true, false) +	f := NewCryptFS(key, true, false, true)  	for _, r := range ranges {  		parts := f.ExplodePlainRange(r.offset, r.length) @@ -48,7 +48,7 @@ func TestCiphertextRange(t *testing.T) {  		testRange{6654, 8945})  	key := make([]byte, KEY_LEN) -	f := NewCryptFS(key, true, false) +	f := NewCryptFS(key, true, false, true)  	for _, r := range ranges { @@ -70,7 +70,7 @@ func TestCiphertextRange(t *testing.T) {  func TestBlockNo(t *testing.T) {  	key := make([]byte, KEY_LEN) -	f := NewCryptFS(key, true, false) +	f := NewCryptFS(key, true, false, true)  	b := f.CipherOffToBlockNo(788)  	if b != 0 { diff --git a/cryptfs/cryptfs.go b/cryptfs/cryptfs.go index 58cca74..ae62045 100644 --- a/cryptfs/cryptfs.go +++ b/cryptfs/cryptfs.go @@ -11,9 +11,7 @@ import (  const (  	DEFAULT_PLAINBS = 4096  	KEY_LEN         = 32 // AES-256 -	NONCE_LEN       = 12  	AUTH_TAG_LEN    = 16 -	BLOCK_OVERHEAD  = NONCE_LEN + AUTH_TAG_LEN  	DIRIV_LEN       = 16 // identical to AES block size  	DIRIV_FILENAME  = "gocryptfs.diriv"  ) @@ -21,6 +19,8 @@ const (  type CryptFS struct {  	blockCipher cipher.Block  	gcm         cipher.AEAD +	gcmIVLen    int +	gcmIVGen    nonceGenerator  	plainBS     uint64  	cipherBS    uint64  	// Stores an all-zero block of size cipherBS @@ -29,7 +29,7 @@ type CryptFS struct {  	DirIVCacheEnc DirIVCache  } -func NewCryptFS(key []byte, useOpenssl bool, plaintextNames bool) *CryptFS { +func NewCryptFS(key []byte, useOpenssl bool, plaintextNames bool, GCMIV128 bool) *CryptFS {  	if len(key) != KEY_LEN {  		panic(fmt.Sprintf("Unsupported key length %d", len(key))) @@ -40,22 +40,31 @@ func NewCryptFS(key []byte, useOpenssl bool, plaintextNames bool) *CryptFS {  		panic(err)  	} +	// We want the IV size in bytes +	gcmIV := 96 / 8 +	if GCMIV128 { +		gcmIV = 128 / 8 +	} +  	var gcm cipher.AEAD  	if useOpenssl {  		gcm = opensslGCM{key}  	} else { -		gcm, err = cipher.NewGCM(b) +		gcm, err = cipher.NewGCMWithNonceSize(b, gcmIV)  		if err != nil {  			panic(err)  		}  	} -	cipherBS := DEFAULT_PLAINBS + NONCE_LEN + AUTH_TAG_LEN +	plainBS := DEFAULT_PLAINBS +	cipherBS := plainBS + gcmIV + AUTH_TAG_LEN  	return &CryptFS{  		blockCipher:  b,  		gcm:          gcm, -		plainBS:      DEFAULT_PLAINBS, +		gcmIVLen:     gcmIV, +		gcmIVGen:     nonceGenerator{nonceLen: gcmIV}, +		plainBS:      uint64(plainBS),  		cipherBS:     uint64(cipherBS),  		allZeroBlock: make([]byte, cipherBS),  	} @@ -65,3 +74,8 @@ func NewCryptFS(key []byte, useOpenssl bool, plaintextNames bool) *CryptFS {  func (be *CryptFS) PlainBS() uint64 {  	return be.plainBS  } + +// Per-block storage overhead +func (be *CryptFS) BlockOverhead() uint64 { +	return be.cipherBS - be.plainBS +} diff --git a/cryptfs/cryptfs_content.go b/cryptfs/cryptfs_content.go index 25293a7..9a79db4 100644 --- a/cryptfs/cryptfs_content.go +++ b/cryptfs/cryptfs_content.go @@ -59,15 +59,15 @@ func (be *CryptFS) DecryptBlock(ciphertext []byte, blockNo uint64, fileId []byte  		return make([]byte, be.plainBS), nil  	} -	if len(ciphertext) < NONCE_LEN { +	if len(ciphertext) < be.gcmIVLen {  		Warn.Printf("DecryptBlock: Block is too short: %d bytes\n", len(ciphertext))  		return nil, errors.New("Block is too short")  	}  	// Extract nonce -	nonce := ciphertext[:NONCE_LEN] +	nonce := ciphertext[:be.gcmIVLen]  	ciphertextOrig := ciphertext -	ciphertext = ciphertext[NONCE_LEN:] +	ciphertext = ciphertext[be.gcmIVLen:]  	// Decrypt  	var plaintext []byte @@ -94,7 +94,7 @@ func (be *CryptFS) EncryptBlock(plaintext []byte, blockNo uint64, fileID []byte)  	}  	// Get fresh nonce -	nonce := gcmNonce.Get() +	nonce := be.gcmIVGen.Get()  	// Authenticate block with block number and file ID  	aData := make([]byte, 8) diff --git a/cryptfs/names_test.go b/cryptfs/names_test.go index 6dffae3..0207f0a 100644 --- a/cryptfs/names_test.go +++ b/cryptfs/names_test.go @@ -12,7 +12,7 @@ func TestEncryptPathNoIV(t *testing.T) {  	s = append(s, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890")  	key := make([]byte, KEY_LEN) -	fs := NewCryptFS(key, true, false) +	fs := NewCryptFS(key, true, false, true)  	for _, n := range s {  		c := fs.EncryptPathNoIV(n) @@ -33,7 +33,7 @@ func TestPad16(t *testing.T) {  	s = append(s, []byte("12345678901234567abcdefg"))  	key := make([]byte, KEY_LEN) -	fs := NewCryptFS(key, true, false) +	fs := NewCryptFS(key, true, false, true)  	for i := range s {  		orig := s[i] diff --git a/cryptfs/nonce.go b/cryptfs/nonce.go index 3abfefa..be777fc 100644 --- a/cryptfs/nonce.go +++ b/cryptfs/nonce.go @@ -24,16 +24,15 @@ func RandUint64() uint64 {  	return binary.BigEndian.Uint64(b)  } -var gcmNonce nonce96 - -type nonce96 struct { +type nonceGenerator struct {  	lastNonce []byte +	nonceLen  int // bytes  }  // Get a random 96 bit nonce -func (n *nonce96) Get() []byte { -	nonce := RandBytes(12) -	Debug.Printf("nonce96.Get(): %s\n", hex.EncodeToString(nonce)) +func (n *nonceGenerator) Get() []byte { +	nonce := RandBytes(n.nonceLen) +	Debug.Printf("nonceGenerator.Get(): %s\n", hex.EncodeToString(nonce))  	if bytes.Equal(nonce, n.lastNonce) {  		m := fmt.Sprintf("Got the same nonce twice: %s. This should never happen!", hex.EncodeToString(nonce))  		panic(m) diff --git a/cryptfs/openssl_aead.go b/cryptfs/openssl_aead.go index c70bd1f..5d38d38 100644 --- a/cryptfs/openssl_aead.go +++ b/cryptfs/openssl_aead.go @@ -7,6 +7,7 @@ import (  	"github.com/spacemonkeygo/openssl"  ) +// Supports all nonce sizes  type opensslGCM struct {  	key []byte  } @@ -16,13 +17,13 @@ func (be opensslGCM) Overhead() int {  }  func (be opensslGCM) NonceSize() int { -	return NONCE_LEN +	// We support any nonce size +	return -1  }  // 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. +// slice. opensslGCM supports any nonce size.  func (be opensslGCM) Seal(dst, nonce, plaintext, data []byte) []byte {  	// Preallocate output buffer diff --git a/integration_tests/example_filesystems/v0.7/AgD7i9tiAUp42SYjULQt1w== b/integration_tests/example_filesystems/v0.7/AgD7i9tiAUp42SYjULQt1w==Binary files differ new file mode 100644 index 0000000..6c0d1e8 --- /dev/null +++ b/integration_tests/example_filesystems/v0.7/AgD7i9tiAUp42SYjULQt1w== diff --git a/integration_tests/example_filesystems/v0.7/FQnvM-qOnCYSnk368ugdWg== b/integration_tests/example_filesystems/v0.7/FQnvM-qOnCYSnk368ugdWg== new file mode 120000 index 0000000..2b7a4b4 --- /dev/null +++ b/integration_tests/example_filesystems/v0.7/FQnvM-qOnCYSnk368ugdWg== @@ -0,0 +1 @@ +cHxK1r_WYNd43oz_foCmzgt5jWrSvpiD-Ngy94L8LndrP9Kic-xlEg==
\ No newline at end of file diff --git a/integration_tests/example_filesystems/v0.7/Pvg7Oy_Ar8Ar93EZZQV_Lw== b/integration_tests/example_filesystems/v0.7/Pvg7Oy_Ar8Ar93EZZQV_Lw== new file mode 120000 index 0000000..e527253 --- /dev/null +++ b/integration_tests/example_filesystems/v0.7/Pvg7Oy_Ar8Ar93EZZQV_Lw== @@ -0,0 +1 @@ +cdrpE7F_WZBEDSu1DI2k880I-9dsPjhD8AU8faPjh4omHmDcdcHlyimF
\ No newline at end of file diff --git a/integration_tests/example_filesystems/v0.7/gocryptfs.conf b/integration_tests/example_filesystems/v0.7/gocryptfs.conf new file mode 100644 index 0000000..c2997f2 --- /dev/null +++ b/integration_tests/example_filesystems/v0.7/gocryptfs.conf @@ -0,0 +1,16 @@ +{ +	"EncryptedKey": "rjkwSNwi3nCUKMLaDttlYweHSDgyhbDx5sWv/a+h+cG1co5IXoXF9ZQSxXl1Qwm/XhY/dvTvnGZRREde", +	"ScryptObject": { +		"Salt": "mX6madEb9nbE+xgo840s9d2ro88f/5GuEiimQ+C7Z1I=", +		"N": 65536, +		"R": 8, +		"P": 1, +		"KeyLen": 32 +	}, +	"Version": 2, +	"FeatureFlags": [ +		"GCMIV128", +		"DirIV", +		"EMENames" +	] +}
\ No newline at end of file diff --git a/integration_tests/example_filesystems/v0.7/gocryptfs.diriv b/integration_tests/example_filesystems/v0.7/gocryptfs.diriv new file mode 100644 index 0000000..4606c90 --- /dev/null +++ b/integration_tests/example_filesystems/v0.7/gocryptfs.diriv @@ -0,0 +1 @@ +7vFT5ˣN
\ No newline at end of file diff --git a/integration_tests/example_filesystems_test.go b/integration_tests/example_filesystems_test.go index 5eb34e0..3beca60 100644 --- a/integration_tests/example_filesystems_test.go +++ b/integration_tests/example_filesystems_test.go @@ -60,7 +60,7 @@ func TestExampleFSv04(t *testing.T) {  	checkExampleFS(t, pDir)  	unmount(pDir)  	mount(cDir, pDir, "-masterkey", "74676e34-0b47c145-00dac61a-17a92316-"+ -		"bb57044c-e205b71f-65f4fdca-7cabd4b3", "-diriv=false", "-emenames=false") +		"bb57044c-e205b71f-65f4fdca-7cabd4b3", "-diriv=false", "-emenames=false", "-gcmiv128=false")  	checkExampleFS(t, pDir)  	unmount(pDir)  	err = os.Remove(pDir) @@ -82,7 +82,7 @@ func TestExampleFSv05(t *testing.T) {  	checkExampleFS(t, pDir)  	unmount(pDir)  	mount(cDir, pDir, "-masterkey", "199eae55-36bff4af-83b9a3a2-4fa16f65-"+ -		"1549ccdb-2d08d1f0-b1b26965-1b61f896", "-emenames=false") +		"1549ccdb-2d08d1f0-b1b26965-1b61f896", "-emenames=false", "-gcmiv128=false")  	checkExampleFS(t, pDir)  	unmount(pDir)  	err = os.Remove(pDir) @@ -104,7 +104,7 @@ func TestExampleFSv06(t *testing.T) {  	checkExampleFS(t, pDir)  	unmount(pDir)  	mount(cDir, pDir, "-masterkey", "7bc8deb0-5fc894ef-a093da43-61561a81-"+ -		"0e8dee83-fdc056a4-937c37dd-9df5c520") +		"0e8dee83-fdc056a4-937c37dd-9df5c520", "-gcmiv128=false")  	checkExampleFS(t, pDir)  	unmount(pDir)  	err = os.Remove(pDir) @@ -113,8 +113,10 @@ func TestExampleFSv06(t *testing.T) {  	}  } -// Test example_filesystems/v0.6 +// Test example_filesystems/v0.6-plaintextnames  // with password mount and -masterkey mount +// v0.6 changed the file name handling a lot, hence the explicit test case for +// plaintextnames.  func TestExampleFSv06PlaintextNames(t *testing.T) {  	pDir := tmpDir + "TestExampleFsV06PlaintextNames/"  	cDir := "example_filesystems/v0.6-plaintextnames" @@ -126,7 +128,30 @@ func TestExampleFSv06PlaintextNames(t *testing.T) {  	checkExampleFS(t, pDir)  	unmount(pDir)  	mount(cDir, pDir, "-masterkey", "f4690202-595e4593-64c4f7e0-4dddd7d1-"+ -		"303147f9-0ca8aea2-966341a7-52ea8ae9", "-plaintextnames") +		"303147f9-0ca8aea2-966341a7-52ea8ae9", "-plaintextnames", "-gcmiv128=false") +	checkExampleFS(t, pDir) +	unmount(pDir) +	err = os.Remove(pDir) +	if err != nil { +		t.Error(err) +	} +} + +// Test example_filesystems/v0.7 +// with password mount and -masterkey mount +// v0.7 adds 128 bit GCM IVs +func TestExampleFSv07(t *testing.T) { +	pDir := tmpDir + "TestExampleFsV07/" +	cDir := "example_filesystems/v0.7" +	err := os.Mkdir(pDir, 0777) +	if err != nil { +		t.Fatal(err) +	} +	mount(cDir, pDir, "-extpass", "echo test") +	checkExampleFS(t, pDir) +	unmount(pDir) +	mount(cDir, pDir, "-masterkey", "bee8d0c5-74ec49ff-24b8793d-91d488a9-"+ +		"6117c58b-357eafaa-162ce3cf-8a061a28")  	checkExampleFS(t, pDir)  	unmount(pDir)  	err = os.Remove(pDir) @@ -35,7 +35,7 @@ const (  type argContainer struct {  	debug, init, zerokey, fusedebug, openssl, passwd, foreground, version, -	plaintextnames, quiet, diriv, emenames bool +	plaintextnames, quiet, diriv, emenames, gcmiv128 bool  	masterkey, mountpoint, cipherdir, cpuprofile, config, extpass string  	notifypid, scryptn                                            int  } @@ -149,6 +149,7 @@ func main() {  	flagSet.BoolVar(&args.quiet, "q", false, "Quiet - silence informational messages")  	flagSet.BoolVar(&args.diriv, "diriv", true, "Use per-directory file name IV")  	flagSet.BoolVar(&args.emenames, "emenames", true, "Use EME filename encryption. This option implies diriv.") +	flagSet.BoolVar(&args.gcmiv128, "gcmiv128", true, "Use an 128-bit IV for GCM encryption instead of Go's default of 96 bits")  	flagSet.StringVar(&args.masterkey, "masterkey", "", "Mount with explicit master key")  	flagSet.StringVar(&args.cpuprofile, "cpuprofile", "", "Write cpu profile to specified file")  	flagSet.StringVar(&args.config, "config", "", "Use specified config file instead of CIPHERDIR/gocryptfs.conf") @@ -293,6 +294,7 @@ func pathfsFrontend(key []byte, args argContainer, confFile *cryptfs.ConfFile) *  		PlaintextNames: args.plaintextnames,  		DirIV:          args.diriv,  		EMENames:       args.emenames, +		GCMIV128:       args.gcmiv128,  	}  	// confFile is nil when "-zerokey" or "-masterkey" was used  	if confFile != nil { @@ -300,6 +302,7 @@ func pathfsFrontend(key []byte, args argContainer, confFile *cryptfs.ConfFile) *  		frontendArgs.PlaintextNames = confFile.IsFeatureFlagSet(cryptfs.FlagPlaintextNames)  		frontendArgs.DirIV = confFile.IsFeatureFlagSet(cryptfs.FlagDirIV)  		frontendArgs.EMENames = confFile.IsFeatureFlagSet(cryptfs.FlagEMENames) +		frontendArgs.GCMIV128 = confFile.IsFeatureFlagSet(cryptfs.FlagGCMIV128)  	}  	// EMENames implies DirIV, both on the command line and in the config file.  	if frontendArgs.EMENames { diff --git a/pathfs_frontend/args.go b/pathfs_frontend/args.go index fb0b81f..91f9ba7 100644 --- a/pathfs_frontend/args.go +++ b/pathfs_frontend/args.go @@ -8,4 +8,5 @@ type Args struct {  	PlaintextNames bool  	DirIV          bool  	EMENames       bool +	GCMIV128       bool  } diff --git a/pathfs_frontend/file.go b/pathfs_frontend/file.go index 1f71bfb..d38a37b 100644 --- a/pathfs_frontend/file.go +++ b/pathfs_frontend/file.go @@ -266,7 +266,7 @@ func (f *file) doWrite(data []byte, off int64) (uint32, fuse.Status) {  		blockOffset, blockLen := b.CiphertextRange()  		blockData = f.cfs.EncryptBlock(blockData, b.BlockNo, f.header.Id)  		cryptfs.Debug.Printf("ino%d: Writing %d bytes to block #%d, md5=%s\n", -			f.ino, len(blockData)-cryptfs.BLOCK_OVERHEAD, b.BlockNo, cryptfs.Debug.Md5sum(blockData)) +			f.ino, uint64(len(blockData))-f.cfs.BlockOverhead(), b.BlockNo, cryptfs.Debug.Md5sum(blockData))  		// Prevent partially written (=corrupt) blocks by preallocating the space beforehand  		f.fdLock.Lock() diff --git a/pathfs_frontend/fs.go b/pathfs_frontend/fs.go index e930228..324020d 100644 --- a/pathfs_frontend/fs.go +++ b/pathfs_frontend/fs.go @@ -29,7 +29,7 @@ type FS struct {  // Encrypted FUSE overlay filesystem  func NewFS(args Args) *FS {  	return &FS{ -		CryptFS:    cryptfs.NewCryptFS(args.Masterkey, args.OpenSSL, args.PlaintextNames), +		CryptFS:    cryptfs.NewCryptFS(args.Masterkey, args.OpenSSL, args.PlaintextNames, args.GCMIV128),  		FileSystem: pathfs.NewLoopbackFileSystem(args.Cipherdir),  		args:       args,  	} | 
