Increase GCM IV size from 96 to 128 bits
This pushes back the birthday bound for collisions to make it virtually irrelevant.
This commit is contained in:
parent
88826dc51d
commit
1caa925868
@ -57,6 +57,11 @@ to mount the gocryptfs filesytem without user interaction.
|
||||
**-fusedebug**
|
||||
: Enable fuse library debug output
|
||||
|
||||
**-gcmiv128**
|
||||
: Use an 128-bit IV for GCM encryption instead of Go's default of
|
||||
96 bits (default true). This pushes back the birthday bound for IV
|
||||
collisions far enough to make it irrelevant.
|
||||
|
||||
**-init**
|
||||
: Initialize encrypted directory
|
||||
|
||||
|
@ -18,7 +18,7 @@ File Contents
|
||||
All file contents are encrypted using AES-256-GCM (Galois/Counter Mode).
|
||||
|
||||
Files are segmented into 4KB blocks. Each block gets a fresh random
|
||||
96 bit IV each time it is modified. A 128-bit authentication tag (GHASH)
|
||||
128 bit IV each time it is modified. A 128-bit authentication tag (GHASH)
|
||||
protects each block from modifications.
|
||||
|
||||
Each file has a header containing a random 128-bit file ID. The
|
||||
|
32
Documentation/file-format.md
Normal file
32
Documentation/file-format.md
Normal file
@ -0,0 +1,32 @@
|
||||
File Format
|
||||
===========
|
||||
|
||||
Header
|
||||
|
||||
2 bytes header version (big endian uint16, currently 2)
|
||||
16 bytes file id
|
||||
|
||||
Data block
|
||||
|
||||
16 bytes GCM IV (nonce)
|
||||
1-4096 bytes encrypted data
|
||||
16 bytes GHASH
|
||||
|
||||
|
||||
Example: 1-byte file
|
||||
--------------------
|
||||
|
||||
Header 18 bytes
|
||||
Data block 33 bytes
|
||||
|
||||
Total: 51 bytes
|
||||
|
||||
|
||||
Example: 5000-byte file
|
||||
-----------------------
|
||||
|
||||
Header 18 bytes
|
||||
Data block 4128 bytes
|
||||
Data block 936 bytes
|
||||
|
||||
Total: 5082 bytes
|
@ -44,7 +44,7 @@ func (be *CryptFS) CipherSizeToPlainSize(cipherSize uint64) uint64 {
|
||||
blockNo := be.CipherOffToBlockNo(cipherSize - 1)
|
||||
blockCount := blockNo + 1
|
||||
|
||||
overhead := BLOCK_OVERHEAD*blockCount + HEADER_LEN
|
||||
overhead := be.BlockOverhead()*blockCount + HEADER_LEN
|
||||
|
||||
return cipherSize - overhead
|
||||
}
|
||||
@ -56,7 +56,7 @@ func (be *CryptFS) PlainSizeToCipherSize(plainSize uint64) uint64 {
|
||||
blockNo := be.PlainOffToBlockNo(plainSize - 1)
|
||||
blockCount := blockNo + 1
|
||||
|
||||
overhead := BLOCK_OVERHEAD*blockCount + HEADER_LEN
|
||||
overhead := be.BlockOverhead()*blockCount + HEADER_LEN
|
||||
|
||||
return plainSize + overhead
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ func CreateConfFile(filename string, password string, plaintextNames bool, logN
|
||||
cf.EncryptKey(key, password, logN)
|
||||
|
||||
// Set feature flags
|
||||
cf.FeatureFlags = append(cf.FeatureFlags, FlagGCMIV128)
|
||||
if plaintextNames {
|
||||
cf.FeatureFlags = append(cf.FeatureFlags, FlagPlaintextNames)
|
||||
} else {
|
||||
@ -94,7 +95,7 @@ func LoadConfFile(filename string, password string) ([]byte, *ConfFile, error) {
|
||||
// Unlock master key using password-based key
|
||||
// We use stock go GCM instead of OpenSSL here as speed is not important
|
||||
// and we get better error messages
|
||||
cfs := NewCryptFS(scryptHash, false, false)
|
||||
cfs := NewCryptFS(scryptHash, false, false, false)
|
||||
key, err := cfs.DecryptBlock(cf.EncryptedKey, 0, nil)
|
||||
if err != nil {
|
||||
Warn.Printf("failed to unlock master key: %s\n", err.Error())
|
||||
@ -115,7 +116,7 @@ func (cf *ConfFile) EncryptKey(key []byte, password string, logN int) {
|
||||
scryptHash := cf.ScryptObject.DeriveKey(password)
|
||||
|
||||
// Lock master key using password-based key
|
||||
cfs := NewCryptFS(scryptHash, false, false)
|
||||
cfs := NewCryptFS(scryptHash, false, false, false)
|
||||
cf.EncryptedKey = cfs.EncryptBlock(key, 0, nil)
|
||||
}
|
||||
|
||||
@ -155,16 +156,18 @@ func (cf *ConfFile) WriteFile() error {
|
||||
|
||||
const (
|
||||
// Understood Feature Flags.
|
||||
// Also teach isFeatureFlagKnown() about any additions
|
||||
// Also teach isFeatureFlagKnown() about any additions and
|
||||
// add it to CreateConfFile() if you want to have it enabled by default.
|
||||
FlagPlaintextNames = "PlaintextNames"
|
||||
FlagDirIV = "DirIV"
|
||||
FlagEMENames = "EMENames"
|
||||
FlagGCMIV128 = "GCMIV128"
|
||||
)
|
||||
|
||||
// Verify that we understand a feature flag
|
||||
func (cf *ConfFile) isFeatureFlagKnown(flag string) bool {
|
||||
switch flag {
|
||||
case FlagPlaintextNames, FlagDirIV, FlagEMENames:
|
||||
case FlagPlaintextNames, FlagDirIV, FlagEMENames, FlagGCMIV128:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
@ -21,7 +21,7 @@ func TestSplitRange(t *testing.T) {
|
||||
testRange{6654, 8945})
|
||||
|
||||
key := make([]byte, KEY_LEN)
|
||||
f := NewCryptFS(key, true, false)
|
||||
f := NewCryptFS(key, true, false, true)
|
||||
|
||||
for _, r := range ranges {
|
||||
parts := f.ExplodePlainRange(r.offset, r.length)
|
||||
@ -48,7 +48,7 @@ func TestCiphertextRange(t *testing.T) {
|
||||
testRange{6654, 8945})
|
||||
|
||||
key := make([]byte, KEY_LEN)
|
||||
f := NewCryptFS(key, true, false)
|
||||
f := NewCryptFS(key, true, false, true)
|
||||
|
||||
for _, r := range ranges {
|
||||
|
||||
@ -70,7 +70,7 @@ func TestCiphertextRange(t *testing.T) {
|
||||
|
||||
func TestBlockNo(t *testing.T) {
|
||||
key := make([]byte, KEY_LEN)
|
||||
f := NewCryptFS(key, true, false)
|
||||
f := NewCryptFS(key, true, false, true)
|
||||
|
||||
b := f.CipherOffToBlockNo(788)
|
||||
if b != 0 {
|
||||
|
@ -11,9 +11,7 @@ import (
|
||||
const (
|
||||
DEFAULT_PLAINBS = 4096
|
||||
KEY_LEN = 32 // AES-256
|
||||
NONCE_LEN = 12
|
||||
AUTH_TAG_LEN = 16
|
||||
BLOCK_OVERHEAD = NONCE_LEN + AUTH_TAG_LEN
|
||||
DIRIV_LEN = 16 // identical to AES block size
|
||||
DIRIV_FILENAME = "gocryptfs.diriv"
|
||||
)
|
||||
@ -21,6 +19,8 @@ const (
|
||||
type CryptFS struct {
|
||||
blockCipher cipher.Block
|
||||
gcm cipher.AEAD
|
||||
gcmIVLen int
|
||||
gcmIVGen nonceGenerator
|
||||
plainBS uint64
|
||||
cipherBS uint64
|
||||
// Stores an all-zero block of size cipherBS
|
||||
@ -29,7 +29,7 @@ type CryptFS struct {
|
||||
DirIVCacheEnc DirIVCache
|
||||
}
|
||||
|
||||
func NewCryptFS(key []byte, useOpenssl bool, plaintextNames bool) *CryptFS {
|
||||
func NewCryptFS(key []byte, useOpenssl bool, plaintextNames bool, GCMIV128 bool) *CryptFS {
|
||||
|
||||
if len(key) != KEY_LEN {
|
||||
panic(fmt.Sprintf("Unsupported key length %d", len(key)))
|
||||
@ -40,22 +40,31 @@ func NewCryptFS(key []byte, useOpenssl bool, plaintextNames bool) *CryptFS {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// We want the IV size in bytes
|
||||
gcmIV := 96 / 8
|
||||
if GCMIV128 {
|
||||
gcmIV = 128 / 8
|
||||
}
|
||||
|
||||
var gcm cipher.AEAD
|
||||
if useOpenssl {
|
||||
gcm = opensslGCM{key}
|
||||
} else {
|
||||
gcm, err = cipher.NewGCM(b)
|
||||
gcm, err = cipher.NewGCMWithNonceSize(b, gcmIV)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
cipherBS := DEFAULT_PLAINBS + NONCE_LEN + AUTH_TAG_LEN
|
||||
plainBS := DEFAULT_PLAINBS
|
||||
cipherBS := plainBS + gcmIV + AUTH_TAG_LEN
|
||||
|
||||
return &CryptFS{
|
||||
blockCipher: b,
|
||||
gcm: gcm,
|
||||
plainBS: DEFAULT_PLAINBS,
|
||||
gcmIVLen: gcmIV,
|
||||
gcmIVGen: nonceGenerator{nonceLen: gcmIV},
|
||||
plainBS: uint64(plainBS),
|
||||
cipherBS: uint64(cipherBS),
|
||||
allZeroBlock: make([]byte, cipherBS),
|
||||
}
|
||||
@ -65,3 +74,8 @@ func NewCryptFS(key []byte, useOpenssl bool, plaintextNames bool) *CryptFS {
|
||||
func (be *CryptFS) PlainBS() uint64 {
|
||||
return be.plainBS
|
||||
}
|
||||
|
||||
// Per-block storage overhead
|
||||
func (be *CryptFS) BlockOverhead() uint64 {
|
||||
return be.cipherBS - be.plainBS
|
||||
}
|
||||
|
@ -59,15 +59,15 @@ func (be *CryptFS) DecryptBlock(ciphertext []byte, blockNo uint64, fileId []byte
|
||||
return make([]byte, be.plainBS), nil
|
||||
}
|
||||
|
||||
if len(ciphertext) < NONCE_LEN {
|
||||
if len(ciphertext) < be.gcmIVLen {
|
||||
Warn.Printf("DecryptBlock: Block is too short: %d bytes\n", len(ciphertext))
|
||||
return nil, errors.New("Block is too short")
|
||||
}
|
||||
|
||||
// Extract nonce
|
||||
nonce := ciphertext[:NONCE_LEN]
|
||||
nonce := ciphertext[:be.gcmIVLen]
|
||||
ciphertextOrig := ciphertext
|
||||
ciphertext = ciphertext[NONCE_LEN:]
|
||||
ciphertext = ciphertext[be.gcmIVLen:]
|
||||
|
||||
// Decrypt
|
||||
var plaintext []byte
|
||||
@ -94,7 +94,7 @@ func (be *CryptFS) EncryptBlock(plaintext []byte, blockNo uint64, fileID []byte)
|
||||
}
|
||||
|
||||
// Get fresh nonce
|
||||
nonce := gcmNonce.Get()
|
||||
nonce := be.gcmIVGen.Get()
|
||||
|
||||
// Authenticate block with block number and file ID
|
||||
aData := make([]byte, 8)
|
||||
|
@ -12,7 +12,7 @@ func TestEncryptPathNoIV(t *testing.T) {
|
||||
s = append(s, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890")
|
||||
|
||||
key := make([]byte, KEY_LEN)
|
||||
fs := NewCryptFS(key, true, false)
|
||||
fs := NewCryptFS(key, true, false, true)
|
||||
|
||||
for _, n := range s {
|
||||
c := fs.EncryptPathNoIV(n)
|
||||
@ -33,7 +33,7 @@ func TestPad16(t *testing.T) {
|
||||
s = append(s, []byte("12345678901234567abcdefg"))
|
||||
|
||||
key := make([]byte, KEY_LEN)
|
||||
fs := NewCryptFS(key, true, false)
|
||||
fs := NewCryptFS(key, true, false, true)
|
||||
|
||||
for i := range s {
|
||||
orig := s[i]
|
||||
|
@ -24,16 +24,15 @@ func RandUint64() uint64 {
|
||||
return binary.BigEndian.Uint64(b)
|
||||
}
|
||||
|
||||
var gcmNonce nonce96
|
||||
|
||||
type nonce96 struct {
|
||||
type nonceGenerator struct {
|
||||
lastNonce []byte
|
||||
nonceLen int // bytes
|
||||
}
|
||||
|
||||
// Get a random 96 bit nonce
|
||||
func (n *nonce96) Get() []byte {
|
||||
nonce := RandBytes(12)
|
||||
Debug.Printf("nonce96.Get(): %s\n", hex.EncodeToString(nonce))
|
||||
func (n *nonceGenerator) Get() []byte {
|
||||
nonce := RandBytes(n.nonceLen)
|
||||
Debug.Printf("nonceGenerator.Get(): %s\n", hex.EncodeToString(nonce))
|
||||
if bytes.Equal(nonce, n.lastNonce) {
|
||||
m := fmt.Sprintf("Got the same nonce twice: %s. This should never happen!", hex.EncodeToString(nonce))
|
||||
panic(m)
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"github.com/spacemonkeygo/openssl"
|
||||
)
|
||||
|
||||
// Supports all nonce sizes
|
||||
type opensslGCM struct {
|
||||
key []byte
|
||||
}
|
||||
@ -16,13 +17,13 @@ func (be opensslGCM) Overhead() int {
|
||||
}
|
||||
|
||||
func (be opensslGCM) NonceSize() int {
|
||||
return NONCE_LEN
|
||||
// We support any nonce size
|
||||
return -1
|
||||
}
|
||||
|
||||
// Seal encrypts and authenticates plaintext, authenticates the
|
||||
// additional data and appends the result to dst, returning the updated
|
||||
// slice. The nonce must be NonceSize() bytes long and unique for all
|
||||
// time, for a given key.
|
||||
// slice. opensslGCM supports any nonce size.
|
||||
func (be opensslGCM) Seal(dst, nonce, plaintext, data []byte) []byte {
|
||||
|
||||
// Preallocate output buffer
|
||||
|
Binary file not shown.
@ -0,0 +1 @@
|
||||
cHxK1r_WYNd43oz_foCmzgt5jWrSvpiD-Ngy94L8LndrP9Kic-xlEg==
|
@ -0,0 +1 @@
|
||||
cdrpE7F_WZBEDSu1DI2k880I-9dsPjhD8AU8faPjh4omHmDcdcHlyimF
|
16
integration_tests/example_filesystems/v0.7/gocryptfs.conf
Normal file
16
integration_tests/example_filesystems/v0.7/gocryptfs.conf
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"EncryptedKey": "rjkwSNwi3nCUKMLaDttlYweHSDgyhbDx5sWv/a+h+cG1co5IXoXF9ZQSxXl1Qwm/XhY/dvTvnGZRREde",
|
||||
"ScryptObject": {
|
||||
"Salt": "mX6madEb9nbE+xgo840s9d2ro88f/5GuEiimQ+C7Z1I=",
|
||||
"N": 65536,
|
||||
"R": 8,
|
||||
"P": 1,
|
||||
"KeyLen": 32
|
||||
},
|
||||
"Version": 2,
|
||||
"FeatureFlags": [
|
||||
"GCMIV128",
|
||||
"DirIV",
|
||||
"EMENames"
|
||||
]
|
||||
}
|
@ -0,0 +1 @@
|
||||
¤7vßØFT5ÌÖË£<C38B>N×
|
@ -60,7 +60,7 @@ func TestExampleFSv04(t *testing.T) {
|
||||
checkExampleFS(t, pDir)
|
||||
unmount(pDir)
|
||||
mount(cDir, pDir, "-masterkey", "74676e34-0b47c145-00dac61a-17a92316-"+
|
||||
"bb57044c-e205b71f-65f4fdca-7cabd4b3", "-diriv=false", "-emenames=false")
|
||||
"bb57044c-e205b71f-65f4fdca-7cabd4b3", "-diriv=false", "-emenames=false", "-gcmiv128=false")
|
||||
checkExampleFS(t, pDir)
|
||||
unmount(pDir)
|
||||
err = os.Remove(pDir)
|
||||
@ -82,7 +82,7 @@ func TestExampleFSv05(t *testing.T) {
|
||||
checkExampleFS(t, pDir)
|
||||
unmount(pDir)
|
||||
mount(cDir, pDir, "-masterkey", "199eae55-36bff4af-83b9a3a2-4fa16f65-"+
|
||||
"1549ccdb-2d08d1f0-b1b26965-1b61f896", "-emenames=false")
|
||||
"1549ccdb-2d08d1f0-b1b26965-1b61f896", "-emenames=false", "-gcmiv128=false")
|
||||
checkExampleFS(t, pDir)
|
||||
unmount(pDir)
|
||||
err = os.Remove(pDir)
|
||||
@ -104,7 +104,7 @@ func TestExampleFSv06(t *testing.T) {
|
||||
checkExampleFS(t, pDir)
|
||||
unmount(pDir)
|
||||
mount(cDir, pDir, "-masterkey", "7bc8deb0-5fc894ef-a093da43-61561a81-"+
|
||||
"0e8dee83-fdc056a4-937c37dd-9df5c520")
|
||||
"0e8dee83-fdc056a4-937c37dd-9df5c520", "-gcmiv128=false")
|
||||
checkExampleFS(t, pDir)
|
||||
unmount(pDir)
|
||||
err = os.Remove(pDir)
|
||||
@ -113,8 +113,10 @@ func TestExampleFSv06(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Test example_filesystems/v0.6
|
||||
// Test example_filesystems/v0.6-plaintextnames
|
||||
// with password mount and -masterkey mount
|
||||
// v0.6 changed the file name handling a lot, hence the explicit test case for
|
||||
// plaintextnames.
|
||||
func TestExampleFSv06PlaintextNames(t *testing.T) {
|
||||
pDir := tmpDir + "TestExampleFsV06PlaintextNames/"
|
||||
cDir := "example_filesystems/v0.6-plaintextnames"
|
||||
@ -126,7 +128,30 @@ func TestExampleFSv06PlaintextNames(t *testing.T) {
|
||||
checkExampleFS(t, pDir)
|
||||
unmount(pDir)
|
||||
mount(cDir, pDir, "-masterkey", "f4690202-595e4593-64c4f7e0-4dddd7d1-"+
|
||||
"303147f9-0ca8aea2-966341a7-52ea8ae9", "-plaintextnames")
|
||||
"303147f9-0ca8aea2-966341a7-52ea8ae9", "-plaintextnames", "-gcmiv128=false")
|
||||
checkExampleFS(t, pDir)
|
||||
unmount(pDir)
|
||||
err = os.Remove(pDir)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Test example_filesystems/v0.7
|
||||
// with password mount and -masterkey mount
|
||||
// v0.7 adds 128 bit GCM IVs
|
||||
func TestExampleFSv07(t *testing.T) {
|
||||
pDir := tmpDir + "TestExampleFsV07/"
|
||||
cDir := "example_filesystems/v0.7"
|
||||
err := os.Mkdir(pDir, 0777)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
mount(cDir, pDir, "-extpass", "echo test")
|
||||
checkExampleFS(t, pDir)
|
||||
unmount(pDir)
|
||||
mount(cDir, pDir, "-masterkey", "bee8d0c5-74ec49ff-24b8793d-91d488a9-"+
|
||||
"6117c58b-357eafaa-162ce3cf-8a061a28")
|
||||
checkExampleFS(t, pDir)
|
||||
unmount(pDir)
|
||||
err = os.Remove(pDir)
|
||||
|
5
main.go
5
main.go
@ -35,7 +35,7 @@ const (
|
||||
|
||||
type argContainer struct {
|
||||
debug, init, zerokey, fusedebug, openssl, passwd, foreground, version,
|
||||
plaintextnames, quiet, diriv, emenames bool
|
||||
plaintextnames, quiet, diriv, emenames, gcmiv128 bool
|
||||
masterkey, mountpoint, cipherdir, cpuprofile, config, extpass string
|
||||
notifypid, scryptn int
|
||||
}
|
||||
@ -149,6 +149,7 @@ func main() {
|
||||
flagSet.BoolVar(&args.quiet, "q", false, "Quiet - silence informational messages")
|
||||
flagSet.BoolVar(&args.diriv, "diriv", true, "Use per-directory file name IV")
|
||||
flagSet.BoolVar(&args.emenames, "emenames", true, "Use EME filename encryption. This option implies diriv.")
|
||||
flagSet.BoolVar(&args.gcmiv128, "gcmiv128", true, "Use an 128-bit IV for GCM encryption instead of Go's default of 96 bits")
|
||||
flagSet.StringVar(&args.masterkey, "masterkey", "", "Mount with explicit master key")
|
||||
flagSet.StringVar(&args.cpuprofile, "cpuprofile", "", "Write cpu profile to specified file")
|
||||
flagSet.StringVar(&args.config, "config", "", "Use specified config file instead of CIPHERDIR/gocryptfs.conf")
|
||||
@ -293,6 +294,7 @@ func pathfsFrontend(key []byte, args argContainer, confFile *cryptfs.ConfFile) *
|
||||
PlaintextNames: args.plaintextnames,
|
||||
DirIV: args.diriv,
|
||||
EMENames: args.emenames,
|
||||
GCMIV128: args.gcmiv128,
|
||||
}
|
||||
// confFile is nil when "-zerokey" or "-masterkey" was used
|
||||
if confFile != nil {
|
||||
@ -300,6 +302,7 @@ func pathfsFrontend(key []byte, args argContainer, confFile *cryptfs.ConfFile) *
|
||||
frontendArgs.PlaintextNames = confFile.IsFeatureFlagSet(cryptfs.FlagPlaintextNames)
|
||||
frontendArgs.DirIV = confFile.IsFeatureFlagSet(cryptfs.FlagDirIV)
|
||||
frontendArgs.EMENames = confFile.IsFeatureFlagSet(cryptfs.FlagEMENames)
|
||||
frontendArgs.GCMIV128 = confFile.IsFeatureFlagSet(cryptfs.FlagGCMIV128)
|
||||
}
|
||||
// EMENames implies DirIV, both on the command line and in the config file.
|
||||
if frontendArgs.EMENames {
|
||||
|
@ -8,4 +8,5 @@ type Args struct {
|
||||
PlaintextNames bool
|
||||
DirIV bool
|
||||
EMENames bool
|
||||
GCMIV128 bool
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ func (f *file) doWrite(data []byte, off int64) (uint32, fuse.Status) {
|
||||
blockOffset, blockLen := b.CiphertextRange()
|
||||
blockData = f.cfs.EncryptBlock(blockData, b.BlockNo, f.header.Id)
|
||||
cryptfs.Debug.Printf("ino%d: Writing %d bytes to block #%d, md5=%s\n",
|
||||
f.ino, len(blockData)-cryptfs.BLOCK_OVERHEAD, b.BlockNo, cryptfs.Debug.Md5sum(blockData))
|
||||
f.ino, uint64(len(blockData))-f.cfs.BlockOverhead(), b.BlockNo, cryptfs.Debug.Md5sum(blockData))
|
||||
|
||||
// Prevent partially written (=corrupt) blocks by preallocating the space beforehand
|
||||
f.fdLock.Lock()
|
||||
|
@ -29,7 +29,7 @@ type FS struct {
|
||||
// Encrypted FUSE overlay filesystem
|
||||
func NewFS(args Args) *FS {
|
||||
return &FS{
|
||||
CryptFS: cryptfs.NewCryptFS(args.Masterkey, args.OpenSSL, args.PlaintextNames),
|
||||
CryptFS: cryptfs.NewCryptFS(args.Masterkey, args.OpenSSL, args.PlaintextNames, args.GCMIV128),
|
||||
FileSystem: pathfs.NewLoopbackFileSystem(args.Cipherdir),
|
||||
args: args,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user