Skip to content

Commit

Permalink
fusefrontend: aessiv: enable deterministiv file id and block iv
Browse files Browse the repository at this point in the history
Seems to work ok:

 $ echo aaaaaaaaaaaaaaaaaaa > b/foo
 $ gocryptfs-xray a/LAh7EiK-kjleJhStVZ1JGg
 Header: Version: 2, Id: 8d76d368438112fb00cb807fa8210a74
 Block  0: IV: b05bb152f77816678230885d09a4a596, Tag: c1c7d580fe01dd1eb543efd9d8eda8ad, Offset:    18 Len: 52
 $ > b/foo
 $ echo aaaaaaaaaaaaaaaaaaa > b/foo
 $ gocryptfs-xray a/LAh7EiK-kjleJhStVZ1JGg
 Header: Version: 2, Id: 8d76d368438112fb00cb807fa8210a74
 Block  0: IV: b05bb152f77816678230885d09a4a596, Tag: c1c7d580fe01dd1eb543efd9d8eda8ad, Offset:    18 Len: 52

Deterministic diriv generation is still missing.

Part of #108
  • Loading branch information
rfjakob committed May 28, 2017
1 parent e2341c9 commit 791c78b
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 11 deletions.
5 changes: 5 additions & 0 deletions internal/contentenc/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ func (be *ContentEnc) CipherBS() uint64 {
return be.cipherBS
}

// UsingSIV returns true if we are using AES-SIV for file content encryption.
func (be *ContentEnc) UsingSIV() bool {
return be.cryptoCore.AEADBackend == cryptocore.BackendAESSIV
}

// DecryptBlocks decrypts a number of blocks
// TODO refactor to three-param for
func (be *ContentEnc) DecryptBlocks(ciphertext []byte, firstBlockNo uint64, fileID []byte) ([]byte, error) {
Expand Down
27 changes: 22 additions & 5 deletions internal/fusefrontend/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

"github.com/rfjakob/gocryptfs/internal/contentenc"
"github.com/rfjakob/gocryptfs/internal/openfiletable"
"github.com/rfjakob/gocryptfs/internal/pathiv"
"github.com/rfjakob/gocryptfs/internal/serialize_reads"
"github.com/rfjakob/gocryptfs/internal/stupidgcm"
"github.com/rfjakob/gocryptfs/internal/syscallcompat"
Expand Down Expand Up @@ -56,10 +57,13 @@ type file struct {
// have not implemented. This prevents build breakage when the go-fuse library
// adds new methods to the nodefs.File interface.
nodefs.File
// In AES-SIV mode, file ID and block IVs are deterministically derived from
// the path that was used to open the file.
pathIVs pathiv.FileIVs
}

// NewFile returns a new go-fuse File instance.
func NewFile(fd *os.File, fs *FS) (nodefs.File, fuse.Status) {
func NewFile(fd *os.File, fs *FS, relPath string) (nodefs.File, fuse.Status) {
var st syscall.Stat_t
err := syscall.Fstat(int(fd.Fd()), &st)
if err != nil {
Expand All @@ -68,16 +72,19 @@ func NewFile(fd *os.File, fs *FS) (nodefs.File, fuse.Status) {
}
qi := openfiletable.QInoFromStat(&st)
e := openfiletable.Register(qi)

return &file{
f := &file{
fd: fd,
contentEnc: fs.contentEnc,
qIno: qi,
fileTableEntry: e,
loopbackFile: nodefs.NewLoopbackFile(fd),
fs: fs,
File: nodefs.NewDefaultFile(),
}, fuse.OK
}
if fs.contentEnc.UsingSIV() {
f.pathIVs = pathiv.DeriveFile(relPath)
}
return f, fuse.OK
}

// intFd - return the backing file descriptor as an integer. Used for debug
Expand Down Expand Up @@ -115,6 +122,10 @@ func (f *file) readFileID() ([]byte, error) {
// The caller must hold fileIDLock.Lock().
func (f *file) createHeader() (fileID []byte, err error) {
h := contentenc.RandomHeader()
if f.contentEnc.UsingSIV() {
// We use a deterministic file ID in SIV mode.
h.ID = f.pathIVs.ID
}
buf := h.Pack()
// Prevent partially written (=corrupt) header by preallocating the space beforehand
if !f.fs.args.NoPrealloc {
Expand Down Expand Up @@ -297,7 +308,13 @@ func (f *file) doWrite(data []byte, off int64) (uint32, fuse.Status) {
tlog.Debug.Printf("len(oldData)=%d len(blockData)=%d", len(oldData), len(blockData))
}
// Encrypt
blockData = f.contentEnc.EncryptBlock(blockData, b.BlockNo, fileID)
if f.fs.contentEnc.UsingSIV() {
// We use a deterministic block IV in SIV mode.
iv := pathiv.BlockIV(f.pathIVs.Block0IV, b.BlockNo)
blockData = f.contentEnc.EncryptBlockNonce(blockData, b.BlockNo, fileID, iv)
} else {
blockData = f.contentEnc.EncryptBlock(blockData, b.BlockNo, fileID)
}
tlog.Debug.Printf("ino%d: Writing %d bytes to block #%d",
f.qIno.Ino, uint64(len(blockData))-f.contentEnc.BlockOverhead(), b.BlockNo)
// Store output data in the writeChain
Expand Down
13 changes: 7 additions & 6 deletions internal/fusefrontend/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,12 @@ func (fs *FS) Open(path string, flags uint32, context *fuse.Context) (fuseFile n
return nil, fuse.EPERM
}
newFlags := fs.mangleOpenFlags(flags)
cPath, err := fs.getBackingPath(path)
cRelPath, err := fs.encryptPath(path)
if err != nil {
tlog.Debug.Printf("Open: getBackingPath: %v", err)
tlog.Debug.Printf("Open: encryptPath: %v", err)
return nil, fuse.ToStatus(err)
}
cPath := filepath.Join(fs.args.Cipherdir, cRelPath)
tlog.Debug.Printf("Open: %s", cPath)
f, err := os.OpenFile(cPath, newFlags, 0666)
if err != nil {
Expand All @@ -116,8 +117,7 @@ func (fs *FS) Open(path string, flags uint32, context *fuse.Context) (fuseFile n
}
return nil, fuse.ToStatus(err)
}

return NewFile(f, fs)
return NewFile(f, fs, cRelPath)
}

// Create implements pathfs.Filesystem.
Expand All @@ -126,10 +126,11 @@ func (fs *FS) Create(path string, flags uint32, mode uint32, context *fuse.Conte
return nil, fuse.EPERM
}
newFlags := fs.mangleOpenFlags(flags)
cPath, err := fs.getBackingPath(path)
cRelPath, err := fs.encryptPath(path)
if err != nil {
return nil, fuse.ToStatus(err)
}
cPath := filepath.Join(fs.args.Cipherdir, cRelPath)

var fd *os.File
cName := filepath.Base(cPath)
Expand Down Expand Up @@ -171,7 +172,7 @@ func (fs *FS) Create(path string, flags uint32, mode uint32, context *fuse.Conte
tlog.Warn.Printf("Create: fd.Chown failed: %v", err)
}
}
return NewFile(fd, fs)
return NewFile(fd, fs, path)
}

// Chmod implements pathfs.Filesystem.
Expand Down

0 comments on commit 791c78b

Please sign in to comment.