From 1caa9258685fa5fad8935d3bfcd0eac7d7f84f1e Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sat, 19 Dec 2015 14:41:39 +0100 Subject: [PATCH] Increase GCM IV size from 96 to 128 bits This pushes back the birthday bound for collisions to make it virtually irrelevant. --- Documentation/MANPAGE.md | 5 +++ Documentation/SECURITY.md | 2 +- Documentation/file-format.md | 32 ++++++++++++++++ cryptfs/address_translation.go | 4 +- cryptfs/config_file.go | 11 ++++-- cryptfs/content_test.go | 6 +-- cryptfs/cryptfs.go | 26 ++++++++++--- cryptfs/cryptfs_content.go | 8 ++-- cryptfs/names_test.go | 4 +- cryptfs/nonce.go | 11 +++--- cryptfs/openssl_aead.go | 7 ++-- .../v0.7/AgD7i9tiAUp42SYjULQt1w== | Bin 0 -> 60 bytes .../v0.7/FQnvM-qOnCYSnk368ugdWg== | 1 + .../v0.7/Pvg7Oy_Ar8Ar93EZZQV_Lw== | 1 + .../example_filesystems/v0.7/gocryptfs.conf | 16 ++++++++ .../example_filesystems/v0.7/gocryptfs.diriv | 1 + integration_tests/example_filesystems_test.go | 35 +++++++++++++++--- main.go | 5 ++- pathfs_frontend/args.go | 1 + pathfs_frontend/file.go | 2 +- pathfs_frontend/fs.go | 2 +- 21 files changed, 141 insertions(+), 39 deletions(-) create mode 100644 Documentation/file-format.md create mode 100644 integration_tests/example_filesystems/v0.7/AgD7i9tiAUp42SYjULQt1w== create mode 120000 integration_tests/example_filesystems/v0.7/FQnvM-qOnCYSnk368ugdWg== create mode 120000 integration_tests/example_filesystems/v0.7/Pvg7Oy_Ar8Ar93EZZQV_Lw== create mode 100644 integration_tests/example_filesystems/v0.7/gocryptfs.conf create mode 100644 integration_tests/example_filesystems/v0.7/gocryptfs.diriv 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== new file mode 100644 index 0000000000000000000000000000000000000000..6c0d1e80394467e091084ad5ef210506dbe582bb GIT binary patch literal 60 zcmV-C0K@+P0uahfgJe|}{TpaL9!obFY|7=1Q;y?1@(i*D( literal 0 HcmV?d00001 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) diff --git a/main.go b/main.go index 49b13d1..7013f07 100644 --- a/main.go +++ b/main.go @@ -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, }