diff options
-rw-r--r-- | cryptfs/cryptfs.go | 7 | ||||
-rw-r--r-- | cryptfs/cryptfs_content.go | 9 |
2 files changed, 15 insertions, 1 deletions
diff --git a/cryptfs/cryptfs.go b/cryptfs/cryptfs.go index 6380a92..71ec996 100644 --- a/cryptfs/cryptfs.go +++ b/cryptfs/cryptfs.go @@ -20,6 +20,8 @@ type CryptFS struct { gcm cipher.AEAD plainBS uint64 cipherBS uint64 + // Stores an all-zero block of size cipherBS + allZeroBlock []byte } func NewCryptFS(key []byte, useOpenssl bool) *CryptFS { @@ -45,11 +47,14 @@ func NewCryptFS(key []byte, useOpenssl bool) *CryptFS { } } + cipherBS := DEFAULT_PLAINBS + NONCE_LEN + AUTH_TAG_LEN + return &CryptFS{ blockCipher: b, gcm: gcm, plainBS: DEFAULT_PLAINBS, - cipherBS: DEFAULT_PLAINBS + NONCE_LEN + AUTH_TAG_LEN, + cipherBS: uint64(cipherBS), + allZeroBlock: make([]byte, cipherBS), } } diff --git a/cryptfs/cryptfs_content.go b/cryptfs/cryptfs_content.go index 0494b69..e42011a 100644 --- a/cryptfs/cryptfs_content.go +++ b/cryptfs/cryptfs_content.go @@ -32,6 +32,9 @@ func (be *CryptFS) DecryptBlocks(ciphertext []byte) ([]byte, error) { } // DecryptBlock - Verify and decrypt GCM block +// +// Corner case: A full-sized block of all-zero ciphertext bytes is translated +// to an all-zero plaintext block, i.e. file hole passtrough. func (be *CryptFS) DecryptBlock(ciphertext []byte) ([]byte, error) { // Empty block? @@ -39,6 +42,12 @@ func (be *CryptFS) DecryptBlock(ciphertext []byte) ([]byte, error) { return ciphertext, nil } + // All-zero block? + if bytes.Equal(ciphertext, be.allZeroBlock) { + Debug.Printf("DecryptBlock: file hole encountered\n") + return make([]byte, be.plainBS), nil + } + if len(ciphertext) < NONCE_LEN { Warn.Printf("decryptBlock: Block is too short: %d bytes\n", len(ciphertext)) return nil, errors.New("Block is too short") |