diff options
| author | Jakob Unterwurzacher | 2017-05-28 20:43:48 +0200 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2017-05-30 17:04:46 +0200 | 
| commit | 9a217ce786581ee7ec18b27e46f0096763c85f9e (patch) | |
| tree | 973b358e56e0df5a7749f8d714748b0c0710aaca | |
| parent | e43eb36da3e72cd0f59ac978cf76a94fa87ca7cd (diff) | |
pathiv: move block IV algorithm into this package
This was implemented in fusefrontend_reverse, but we need it
in fusefrontend as well. Move the algorithm into pathiv.BlockIV().
| -rw-r--r-- | internal/fusefrontend_reverse/rfile.go | 10 | ||||
| -rw-r--r-- | internal/pathiv/pathiv.go | 13 | ||||
| -rw-r--r-- | internal/pathiv/pathiv_test.go | 28 | 
3 files changed, 43 insertions, 8 deletions
| diff --git a/internal/fusefrontend_reverse/rfile.go b/internal/fusefrontend_reverse/rfile.go index 530547a..742d697 100644 --- a/internal/fusefrontend_reverse/rfile.go +++ b/internal/fusefrontend_reverse/rfile.go @@ -2,7 +2,6 @@ package fusefrontend_reverse  import (  	"bytes" -	"encoding/binary"  	"io"  	"os"  	"syscall" @@ -95,18 +94,13 @@ func (rf *reverseFile) GetAttr(*fuse.Attr) fuse.Status {  // encryptBlocks - encrypt "plaintext" into a number of ciphertext blocks.  // "plaintext" must already be block-aligned.  func (rf *reverseFile) encryptBlocks(plaintext []byte, firstBlockNo uint64, fileID []byte, block0IV []byte) []byte { -	nonce := make([]byte, len(block0IV)) -	copy(nonce, block0IV) -	block0IVlow := binary.BigEndian.Uint64(block0IV[8:]) -	nonceLow := nonce[8:] -  	inBuf := bytes.NewBuffer(plaintext)  	var outBuf bytes.Buffer  	bs := int(rf.contentEnc.PlainBS())  	for blockNo := firstBlockNo; inBuf.Len() > 0; blockNo++ { -		binary.BigEndian.PutUint64(nonceLow, block0IVlow+blockNo)  		inBlock := inBuf.Next(bs) -		outBlock := rf.contentEnc.EncryptBlockNonce(inBlock, blockNo, fileID, nonce) +		iv := pathiv.BlockIV(block0IV, blockNo) +		outBlock := rf.contentEnc.EncryptBlockNonce(inBlock, blockNo, fileID, iv)  		outBuf.Write(outBlock)  	}  	return outBuf.Bytes() diff --git a/internal/pathiv/pathiv.go b/internal/pathiv/pathiv.go index aa11b75..08042e9 100644 --- a/internal/pathiv/pathiv.go +++ b/internal/pathiv/pathiv.go @@ -2,6 +2,7 @@ package pathiv  import (  	"crypto/sha256" +	"encoding/binary"  	"github.com/rfjakob/gocryptfs/internal/nametransform"  ) @@ -42,3 +43,15 @@ func DeriveFile(path string) (fileIVs FileIVs) {  	fileIVs.Block0IV = Derive(path, PurposeBlock0IV)  	return fileIVs  } + +// BlockIV returns the block IV for block number "blockNo". "block0iv" is the block +// IV of block #0. +func BlockIV(block0iv []byte, blockNo uint64) []byte { +	iv := make([]byte, len(block0iv)) +	copy(iv, block0iv) +	// Add blockNo to one half of the iv +	lowBytes := iv[8:] +	lowInt := binary.BigEndian.Uint64(lowBytes) +	binary.BigEndian.PutUint64(lowBytes, lowInt+blockNo) +	return iv +} diff --git a/internal/pathiv/pathiv_test.go b/internal/pathiv/pathiv_test.go new file mode 100644 index 0000000..0cecba1 --- /dev/null +++ b/internal/pathiv/pathiv_test.go @@ -0,0 +1,28 @@ +package pathiv + +import ( +	"bytes" +	"encoding/hex" +	"testing" +) + +// TestBlockIV makes sure we don't change the block iv derivation algorithm "BlockIV()" +// inadvertedly. +func TestBlockIV(t *testing.T) { +	b0 := make([]byte, 16) +	b0x := BlockIV(b0, 0) +	if !bytes.Equal(b0, b0x) { +		t.Errorf("b0x should be equal to b0") +	} +	b27 := BlockIV(b0, 0x27) +	expected, _ := hex.DecodeString("00000000000000000000000000000027") +	if !bytes.Equal(b27, expected) { +		t.Error() +	} +	bff := bytes.Repeat([]byte{0xff}, 16) +	b28 := BlockIV(bff, 0x28) +	expected, _ = hex.DecodeString("ffffffffffffffff0000000000000027") +	if !bytes.Equal(b28, expected) { +		t.Errorf("\nhave=%s\nwant=%s", hex.EncodeToString(b28), hex.EncodeToString(expected)) +	} +} | 
