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") | 
