contentenc: add "ExternalNonce" mode
This will be used for strong symlink encryption in reverse mode.
This commit is contained in:
parent
32e55261ca
commit
12808138ef
@ -168,7 +168,7 @@ func (cf *ConfFile) EncryptKey(key []byte, password string, logN int) {
|
|||||||
// Lock master key using password-based key
|
// Lock master key using password-based key
|
||||||
cc := cryptocore.New(scryptHash, cryptocore.BackendGoGCM, 96)
|
cc := cryptocore.New(scryptHash, cryptocore.BackendGoGCM, 96)
|
||||||
ce := contentenc.New(cc, 4096)
|
ce := contentenc.New(cc, 4096)
|
||||||
cf.EncryptedKey = ce.EncryptBlock(key, 0, nil, contentenc.RandomNonce)
|
cf.EncryptedKey = ce.EncryptBlock(key, 0, nil, contentenc.RandomNonce, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteFile - write out config in JSON format to file "filename.tmp"
|
// WriteFile - write out config in JSON format to file "filename.tmp"
|
||||||
|
@ -22,6 +22,7 @@ const (
|
|||||||
_ = iota // skip zero
|
_ = iota // skip zero
|
||||||
RandomNonce NonceMode = iota
|
RandomNonce NonceMode = iota
|
||||||
ReverseDeterministicNonce NonceMode = iota
|
ReverseDeterministicNonce NonceMode = iota
|
||||||
|
ExternalNonce NonceMode = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
type ContentEnc struct {
|
type ContentEnc struct {
|
||||||
@ -46,7 +47,7 @@ func New(cc *cryptocore.CryptoCore, plainBS uint64) *ContentEnc {
|
|||||||
plainBS: plainBS,
|
plainBS: plainBS,
|
||||||
cipherBS: cipherBS,
|
cipherBS: cipherBS,
|
||||||
allZeroBlock: make([]byte, cipherBS),
|
allZeroBlock: make([]byte, cipherBS),
|
||||||
allZeroNonce: make([]byte, IVBitLen/8),
|
allZeroNonce: make([]byte, cc.IVLen),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,14 +133,14 @@ func (be *ContentEnc) EncryptBlocks(plaintext []byte, firstBlockNo uint64, fileI
|
|||||||
var outBuf bytes.Buffer
|
var outBuf bytes.Buffer
|
||||||
for blockNo := firstBlockNo; inBuf.Len() > 0; blockNo++ {
|
for blockNo := firstBlockNo; inBuf.Len() > 0; blockNo++ {
|
||||||
inBlock := inBuf.Next(int(be.plainBS))
|
inBlock := inBuf.Next(int(be.plainBS))
|
||||||
outBlock := be.EncryptBlock(inBlock, blockNo, fileId, nMode)
|
outBlock := be.EncryptBlock(inBlock, blockNo, fileId, nMode, nil)
|
||||||
outBuf.Write(outBlock)
|
outBuf.Write(outBlock)
|
||||||
}
|
}
|
||||||
return outBuf.Bytes()
|
return outBuf.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
// encryptBlock - Encrypt and add IV and MAC
|
// encryptBlock - Encrypt and add IV and MAC
|
||||||
func (be *ContentEnc) EncryptBlock(plaintext []byte, blockNo uint64, fileID []byte, nMode NonceMode) []byte {
|
func (be *ContentEnc) EncryptBlock(plaintext []byte, blockNo uint64, fileID []byte, nMode NonceMode, externalNonce []byte) []byte {
|
||||||
// Empty block?
|
// Empty block?
|
||||||
if len(plaintext) == 0 {
|
if len(plaintext) == 0 {
|
||||||
return plaintext
|
return plaintext
|
||||||
@ -147,11 +148,16 @@ func (be *ContentEnc) EncryptBlock(plaintext []byte, blockNo uint64, fileID []by
|
|||||||
|
|
||||||
var nonce []byte
|
var nonce []byte
|
||||||
switch nMode {
|
switch nMode {
|
||||||
|
case ExternalNonce:
|
||||||
|
if be.cryptoCore.AEADBackend != cryptocore.BackendGCMSIV {
|
||||||
|
panic("MUST NOT use deterministic nonces unless in GCMSIV mode!")
|
||||||
|
}
|
||||||
|
nonce = externalNonce
|
||||||
case ReverseDeterministicNonce:
|
case ReverseDeterministicNonce:
|
||||||
if be.cryptoCore.AEADBackend != cryptocore.BackendGCMSIV {
|
if be.cryptoCore.AEADBackend != cryptocore.BackendGCMSIV {
|
||||||
panic("MUST NOT use deterministic nonces unless in GCMSIV mode!")
|
panic("MUST NOT use deterministic nonces unless in GCMSIV mode!")
|
||||||
}
|
}
|
||||||
l := IVBitLen / 8
|
l := be.cryptoCore.IVLen
|
||||||
nonce = make([]byte, l)
|
nonce = make([]byte, l)
|
||||||
copy(nonce, fileID)
|
copy(nonce, fileID)
|
||||||
// Add the block number to the last 8 byte. Plus one so the block-zero
|
// Add the block number to the last 8 byte. Plus one so the block-zero
|
||||||
@ -164,6 +170,9 @@ func (be *ContentEnc) EncryptBlock(plaintext []byte, blockNo uint64, fileID []by
|
|||||||
default:
|
default:
|
||||||
panic("invalid nonce mode")
|
panic("invalid nonce mode")
|
||||||
}
|
}
|
||||||
|
if len(nonce) != be.cryptoCore.IVLen {
|
||||||
|
panic("wrong nonce length")
|
||||||
|
}
|
||||||
|
|
||||||
// Authenticate block with block number and file ID
|
// Authenticate block with block number and file ID
|
||||||
aData := make([]byte, 8)
|
aData := make([]byte, 8)
|
||||||
|
@ -256,7 +256,7 @@ func (f *file) doWrite(data []byte, off int64) (uint32, fuse.Status) {
|
|||||||
|
|
||||||
// Encrypt
|
// Encrypt
|
||||||
blockOffset := b.BlockCipherOff()
|
blockOffset := b.BlockCipherOff()
|
||||||
blockData = f.contentEnc.EncryptBlock(blockData, b.BlockNo, f.header.Id, contentenc.RandomNonce)
|
blockData = f.contentEnc.EncryptBlock(blockData, b.BlockNo, f.header.Id, contentenc.RandomNonce, nil)
|
||||||
tlog.Debug.Printf("ino%d: Writing %d bytes to block #%d",
|
tlog.Debug.Printf("ino%d: Writing %d bytes to block #%d",
|
||||||
f.ino, uint64(len(blockData))-f.contentEnc.BlockOverhead(), b.BlockNo)
|
f.ino, uint64(len(blockData))-f.contentEnc.BlockOverhead(), b.BlockNo)
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co
|
|||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
// Symlinks are encrypted like file contents (GCM) and base64-encoded
|
// Symlinks are encrypted like file contents (GCM) and base64-encoded
|
||||||
cBinTarget := fs.contentEnc.EncryptBlock([]byte(target), 0, nil, contentenc.RandomNonce)
|
cBinTarget := fs.contentEnc.EncryptBlock([]byte(target), 0, nil, contentenc.RandomNonce, nil)
|
||||||
cTarget := base64.URLEncoding.EncodeToString(cBinTarget)
|
cTarget := base64.URLEncoding.EncodeToString(cBinTarget)
|
||||||
|
|
||||||
// Handle long file name
|
// Handle long file name
|
||||||
|
Loading…
Reference in New Issue
Block a user