summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cryptfs/cryptfs.go7
-rw-r--r--cryptfs/cryptfs_content.go9
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")