summaryrefslogtreecommitdiff
path: root/cryptfs
diff options
context:
space:
mode:
authorJakob Unterwurzacher2015-11-27 00:03:10 +0100
committerJakob Unterwurzacher2015-11-27 00:03:10 +0100
commitdecfc1ab798055234e16a2e9c0782f56ae50669b (patch)
treebdff27eb861a17399b66e28883abfd2624b184c1 /cryptfs
parentfe2fcf6c162a8370670fd1262b90925bf321f199 (diff)
diriv: Convert filename encryption users to diriv
Diffstat (limited to 'cryptfs')
-rw-r--r--cryptfs/cryptfs_names.go48
-rw-r--r--cryptfs/names_diriv.go69
-rw-r--r--cryptfs/names_test.go4
3 files changed, 88 insertions, 33 deletions
diff --git a/cryptfs/cryptfs_names.go b/cryptfs/cryptfs_names.go
index 1282f53..37a769f 100644
--- a/cryptfs/cryptfs_names.go
+++ b/cryptfs/cryptfs_names.go
@@ -12,15 +12,15 @@ import (
)
const (
- ENCRYPT = true
- DECRYPT = false
+ OpEncrypt = iota
+ OpDecrypt
)
-// DecryptName - decrypt filename
-func (be *CryptFS) decryptName(cipherName string) (string, error) {
+// DecryptName - decrypt base64-encoded encrypted filename "cipherName"
+func (be *CryptFS) decryptName(cipherName string, iv []byte) (string, error) {
// Make sure relative symlinks still work after encryption
- // by passing these trough unchanged
+ // by passing these through unchanged
if cipherName == "." || cipherName == ".." {
return cipherName, nil
}
@@ -34,7 +34,6 @@ func (be *CryptFS) decryptName(cipherName string) (string, error) {
return "", fmt.Errorf("Decoded length %d is not a multiple of the AES block size", len(bin))
}
- iv := make([]byte, aes.BlockSize) // TODO ?
cbc := cipher.NewCBCDecrypter(be.blockCipher, iv)
cbc.CryptBlocks(bin, bin)
@@ -48,7 +47,7 @@ func (be *CryptFS) decryptName(cipherName string) (string, error) {
}
// EncryptName - encrypt filename
-func (be *CryptFS) encryptName(plainName string) string {
+func (be *CryptFS) encryptName(plainName string, iv []byte) string {
// Make sure relative symlinks still work after encryption
// by passing these trough unchanged
@@ -59,7 +58,6 @@ func (be *CryptFS) encryptName(plainName string) string {
bin := []byte(plainName)
bin = be.pad16(bin)
- iv := make([]byte, 16) // TODO ?
cbc := cipher.NewCBCEncrypter(be.blockCipher, iv)
cbc.CryptBlocks(bin, bin)
@@ -67,9 +65,10 @@ func (be *CryptFS) encryptName(plainName string) string {
return cipherName64
}
-// TranslatePath - encrypt or decrypt path. Just splits the string on "/"
-// and hands the parts to EncryptName() / DecryptName()
-func (be *CryptFS) translatePath(path string, op bool) (string, error) {
+
+// TranslatePathZeroIV - encrypt or decrypt path using CBC with a constant all-zero IV.
+// Just splits the string on "/" and hands the parts to encryptName() / decryptName()
+func (be *CryptFS) TranslatePathZeroIV(path string, op int) (string, error) {
var err error
// Empty string means root directory
@@ -77,6 +76,8 @@ func (be *CryptFS) translatePath(path string, op bool) (string, error) {
return path, err
}
+ zeroIV := make([]byte, DIRIV_LEN)
+
// Run operation on each path component
var translatedParts []string
parts := strings.Split(path, "/")
@@ -88,10 +89,10 @@ func (be *CryptFS) translatePath(path string, op bool) (string, error) {
continue
}
var newPart string
- if op == ENCRYPT {
- newPart = be.encryptName(part)
+ if op == OpEncrypt {
+ newPart = be.encryptName(part, zeroIV)
} else {
- newPart, err = be.decryptName(part)
+ newPart, err = be.decryptName(part, zeroIV)
if err != nil {
return "", err
}
@@ -102,23 +103,6 @@ func (be *CryptFS) translatePath(path string, op bool) (string, error) {
return strings.Join(translatedParts, "/"), err
}
-// EncryptPath - encrypt filename or path. Just hands it to translatePath().
-func (be *CryptFS) EncryptPath(path string) string {
- if be.plaintextNames {
- return path
- }
- newPath, _ := be.translatePath(path, ENCRYPT)
- return newPath
-}
-
-// DecryptPath - decrypt filename or path. Just hands it to translatePath().
-func (be *CryptFS) DecryptPath(path string) (string, error) {
- if be.plaintextNames {
- return path, nil
- }
- return be.translatePath(path, DECRYPT)
-}
-
// pad16 - pad filename to 16 byte blocks using standard PKCS#7 padding
// https://tools.ietf.org/html/rfc5652#section-6.3
func (be *CryptFS) pad16(orig []byte) (padded []byte) {
@@ -171,3 +155,5 @@ func (be *CryptFS) unPad16(orig []byte) ([]byte, error) {
}
return orig[0:newLen], nil
}
+
+
diff --git a/cryptfs/names_diriv.go b/cryptfs/names_diriv.go
new file mode 100644
index 0000000..c9debab
--- /dev/null
+++ b/cryptfs/names_diriv.go
@@ -0,0 +1,69 @@
+package cryptfs
+
+import (
+ "path/filepath"
+ "io/ioutil"
+ "fmt"
+ "strings"
+)
+
+// readDirIV - read the "gocryptfs.diriv" file from "dir" (absolute path)
+func (be *CryptFS) readDirIV(dir string) (iv []byte, err error) {
+ ivfile := filepath.Join(dir, DIRIV_FILENAME)
+ iv, err = ioutil.ReadFile(ivfile)
+ if err != nil {
+ Warn.Printf("readDirIV: %v\n", err)
+ return nil, err
+ }
+ if len(iv) != DIRIV_LEN {
+ return nil, fmt.Errorf("readDirIV: Invalid length %d\n", len(iv))
+ }
+ return iv, nil
+}
+
+// EncryptPathDirIV - encrypt path using CBC with DirIV
+func (be *CryptFS) EncryptPathDirIV(plainPath string, rootDir string) (string, error) {
+ if be.plaintextNames {
+ return plainPath, nil
+ }
+ // Empty string means root directory
+ if plainPath == "" {
+ return plainPath, nil
+ }
+ var wd = rootDir
+ var encryptedNames []string
+ plainNames := strings.Split(plainPath, "/")
+ for _, plainName := range plainNames {
+ iv, err := be.readDirIV(wd)
+ if err != nil {
+ return "", err
+ }
+ encryptedName := be.encryptName(plainName, iv)
+ encryptedNames = append(encryptedNames, encryptedName)
+ wd = filepath.Join(wd, encryptedName)
+ }
+ return filepath.Join(encryptedNames...), nil
+}
+
+// DecryptPathDirIV - encrypt path using CBC with DirIV
+func (be *CryptFS) DecryptPathDirIV(encryptedPath string, rootDir string) (string, error) {
+ if be.plaintextNames {
+ return encryptedPath, nil
+ }
+ var wd = rootDir
+ var plainNames []string
+ encryptedNames := strings.Split(encryptedPath, "/")
+ for _, encryptedName := range encryptedNames {
+ iv, err := be.readDirIV(wd)
+ if err != nil {
+ return "", err
+ }
+ plainName, err := be.decryptName(encryptedName, iv)
+ if err != nil {
+ return "", err
+ }
+ plainNames = append(plainNames, plainName)
+ wd = filepath.Join(wd, encryptedName)
+ }
+ return filepath.Join(plainNames...), nil
+}
diff --git a/cryptfs/names_test.go b/cryptfs/names_test.go
index ccf08df..1ad3391 100644
--- a/cryptfs/names_test.go
+++ b/cryptfs/names_test.go
@@ -15,8 +15,8 @@ func TestTranslatePath(t *testing.T) {
fs := NewCryptFS(key, true, false)
for _, n := range s {
- c := fs.EncryptPath(n)
- d, err := fs.DecryptPath(c)
+ c, err := fs.TranslatePathZeroIV(n, OpEncrypt)
+ d, err := fs.TranslatePathZeroIV(c, OpDecrypt)
if err != nil {
t.Errorf("Got error from DecryptName: %s", err)
}