From 7bbf6ad6eae47974b1162af13915785a541b9bb9 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 25 Sep 2016 11:20:10 +0200 Subject: reverse: derive file ID and block IVs from file paths --- internal/fusefrontend_reverse/reverse_diriv.go | 9 +++--- internal/fusefrontend_reverse/reverse_longnames.go | 2 +- internal/fusefrontend_reverse/rfile.go | 34 +++++++++++++--------- internal/fusefrontend_reverse/rfs.go | 12 ++------ internal/fusefrontend_reverse/rpath.go | 2 +- 5 files changed, 29 insertions(+), 30 deletions(-) (limited to 'internal/fusefrontend_reverse') diff --git a/internal/fusefrontend_reverse/reverse_diriv.go b/internal/fusefrontend_reverse/reverse_diriv.go index df3a4d1..88d0680 100644 --- a/internal/fusefrontend_reverse/reverse_diriv.go +++ b/internal/fusefrontend_reverse/reverse_diriv.go @@ -9,10 +9,9 @@ import ( "github.com/rfjakob/gocryptfs/internal/nametransform" ) -// deriveDirIV derives the DirIV from the encrypted directory path by -// hashing it -func deriveDirIV(dirPath string) []byte { - hash := sha256.Sum256([]byte(dirPath)) +// derivePathIV derives an IV from an encrypted path by hashing it +func derivePathIV(path string) []byte { + hash := sha256.Sum256([]byte(path)) return hash[:nametransform.DirIVLen] } @@ -22,5 +21,5 @@ func (rfs *reverseFS) newDirIVFile(cRelPath string) (nodefs.File, fuse.Status) { if err != nil { return nil, fuse.ToStatus(err) } - return rfs.NewVirtualFile(deriveDirIV(cDir), absDir) + return rfs.NewVirtualFile(derivePathIV(cDir), absDir) } diff --git a/internal/fusefrontend_reverse/reverse_longnames.go b/internal/fusefrontend_reverse/reverse_longnames.go index 487802f..9c45fe8 100644 --- a/internal/fusefrontend_reverse/reverse_longnames.go +++ b/internal/fusefrontend_reverse/reverse_longnames.go @@ -89,7 +89,7 @@ func (rfs *reverseFS) newNameFile(relPath string) (nodefs.File, fuse.Status) { if err != nil { return nil, fuse.ToStatus(err) } - dirIV := deriveDirIV(cDir) + dirIV := derivePathIV(cDir) e, err := rfs.findLongnameParent(pDir, dirIV, longname) if err != nil { return nil, fuse.ToStatus(err) diff --git a/internal/fusefrontend_reverse/rfile.go b/internal/fusefrontend_reverse/rfile.go index 7e54b17..4e9b5ba 100644 --- a/internal/fusefrontend_reverse/rfile.go +++ b/internal/fusefrontend_reverse/rfile.go @@ -13,29 +13,32 @@ import ( "github.com/rfjakob/gocryptfs/internal/tlog" ) -// File header that contains an all-zero File ID -var zeroFileHeader *contentenc.FileHeader - -func init() { - zeroFileHeader = contentenc.RandomHeader() - // Overwrite with zeros - zeroFileHeader.Id = make([]byte, contentenc.HEADER_ID_LEN) -} - type reverseFile struct { // Embed nodefs.defaultFile for a ENOSYS implementation of all methods nodefs.File // Backing FD fd *os.File + // File header (contains the IV) + header contentenc.FileHeader // Content encryption helper contentEnc *contentenc.ContentEnc } -func NewFile(fd *os.File, contentEnc *contentenc.ContentEnc) (nodefs.File, fuse.Status) { +func (rfs *reverseFS) NewFile(relPath string, flags uint32) (nodefs.File, fuse.Status) { + absPath, err := rfs.abs(rfs.decryptPath(relPath)) + if err != nil { + return nil, fuse.ToStatus(err) + } + fd, err := os.OpenFile(absPath, int(flags), 0666) + if err != nil { + return nil, fuse.ToStatus(err) + } + id := derivePathIV(relPath) return &reverseFile{ File: nodefs.NewDefaultFile(), fd: fd, - contentEnc: contentEnc, + header: contentenc.FileHeader{contentenc.CurrentVersion, id}, + contentEnc: rfs.contentEnc, }, fuse.OK } @@ -64,7 +67,7 @@ func (rf *reverseFile) readBackingFile(off uint64, length uint64) (out []byte, e plaintext = plaintext[0:n] // Encrypt blocks - ciphertext := rf.contentEnc.EncryptBlocks(plaintext, blocks[0].BlockNo, zeroFileHeader.Id, contentenc.ReverseDummyNonce) + ciphertext := rf.contentEnc.EncryptBlocks(plaintext, blocks[0].BlockNo, rf.header.Id, contentenc.ReverseDeterministicNonce) // Crop down to the relevant part lenHave := len(ciphertext) @@ -88,7 +91,7 @@ func (rf *reverseFile) Read(buf []byte, ioff int64) (resultData fuse.ReadResult, // Synthesize file header if off < contentenc.HEADER_LEN { - header = zeroFileHeader.Pack() + header = rf.header.Pack() // Truncate to requested part end := int(off) + len(buf) if end > len(header) { @@ -119,3 +122,8 @@ func (rf *reverseFile) Read(buf []byte, ioff int64) (resultData fuse.ReadResult, return fuse.ReadResultData(out.Bytes()), fuse.OK } + +// Release - FUSE call, close file +func (rf *reverseFile) Release() { + rf.fd.Close() +} diff --git a/internal/fusefrontend_reverse/rfs.go b/internal/fusefrontend_reverse/rfs.go index 9ebf91c..6089d41 100644 --- a/internal/fusefrontend_reverse/rfs.go +++ b/internal/fusefrontend_reverse/rfs.go @@ -226,15 +226,7 @@ func (rfs *reverseFS) Open(relPath string, flags uint32, context *fuse.Context) if rfs.isFiltered(relPath) { return nil, fuse.EPERM } - absPath, err := rfs.abs(rfs.decryptPath(relPath)) - if err != nil { - return nil, fuse.ToStatus(err) - } - f, err := os.OpenFile(absPath, int(flags), 0666) - if err != nil { - return nil, fuse.ToStatus(err) - } - return NewFile(f, rfs.contentEnc) + return rfs.NewFile(relPath, flags) } // OpenDir - FUSE readdir call @@ -258,7 +250,7 @@ func (rfs *reverseFS) OpenDir(cipherPath string, context *fuse.Context) ([]fuse. nVirtual := 1 // Encrypt names - dirIV := deriveDirIV(cipherPath) + dirIV := derivePathIV(cipherPath) for i := range entries { var cName string // ".gocryptfs.reverse.conf" in the root directory is mapped to "gocryptfs.conf" diff --git a/internal/fusefrontend_reverse/rpath.go b/internal/fusefrontend_reverse/rpath.go index 19539bb..c603cad 100644 --- a/internal/fusefrontend_reverse/rpath.go +++ b/internal/fusefrontend_reverse/rpath.go @@ -36,7 +36,7 @@ func (rfs *reverseFS) decryptPath(relPath string) (string, error) { // Start at the top and recurse currentDir := filepath.Join(parts[:i]...) nameType := nametransform.NameType(part) - dirIV := deriveDirIV(currentDir) + dirIV := derivePathIV(currentDir) var transformedPart string if nameType == nametransform.LongNameNone { transformedPart, err = rfs.nameTransform.DecryptName(part, dirIV) -- cgit v1.2.3