aboutsummaryrefslogtreecommitdiff
path: root/internal/pathiv
diff options
context:
space:
mode:
Diffstat (limited to 'internal/pathiv')
-rw-r--r--internal/pathiv/pathiv.go13
-rw-r--r--internal/pathiv/pathiv_test.go28
2 files changed, 41 insertions, 0 deletions
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))
+ }
+}