contentenc: add helpers for reverse mode
Add the reverse variant of DecryptBlocks etc: * EncryptBlocks * JointPlaintextRange * ExplodeCipherRange
This commit is contained in:
parent
1d4c6288f2
commit
5931eea387
@ -50,6 +50,7 @@ func (be *ContentEnc) CipherBS() uint64 {
|
||||
}
|
||||
|
||||
// DecryptBlocks - Decrypt a number of blocks
|
||||
// TODO refactor to three-param for
|
||||
func (be *ContentEnc) DecryptBlocks(ciphertext []byte, firstBlockNo uint64, fileId []byte) ([]byte, error) {
|
||||
cBuf := bytes.NewBuffer(ciphertext)
|
||||
var err error
|
||||
@ -110,6 +111,19 @@ func (be *ContentEnc) DecryptBlock(ciphertext []byte, blockNo uint64, fileId []b
|
||||
return plaintext, nil
|
||||
}
|
||||
|
||||
// EncryptBlocks - Encrypt a number of blocks
|
||||
// Used for reverse mode
|
||||
func (be *ContentEnc) EncryptBlocks(plaintext []byte, firstBlockNo uint64, fileId []byte) []byte {
|
||||
inBuf := bytes.NewBuffer(plaintext)
|
||||
var outBuf bytes.Buffer
|
||||
for blockNo := firstBlockNo; inBuf.Len() > 0; blockNo++ {
|
||||
inBlock := inBuf.Next(int(be.plainBS))
|
||||
outBlock := be.EncryptBlock(inBlock, blockNo, fileId)
|
||||
outBuf.Write(outBlock)
|
||||
}
|
||||
return outBuf.Bytes()
|
||||
}
|
||||
|
||||
// encryptBlock - Encrypt and add IV and MAC
|
||||
func (be *ContentEnc) EncryptBlock(plaintext []byte, blockNo uint64, fileID []byte) []byte {
|
||||
|
||||
|
@ -2,10 +2,19 @@ package contentenc
|
||||
|
||||
// intraBlock identifies a part of a file block
|
||||
type intraBlock struct {
|
||||
BlockNo uint64 // Block number in file
|
||||
Skip uint64 // Offset into block plaintext
|
||||
Length uint64 // Length of plaintext data in this block
|
||||
fs *ContentEnc
|
||||
// Block number in the file
|
||||
BlockNo uint64
|
||||
// Offset into block payload
|
||||
// In forwared mode: block plaintext
|
||||
// In reverse mode: offset into block ciphertext. Takes the header into
|
||||
// account.
|
||||
Skip uint64
|
||||
// Length of payload data in this block
|
||||
// In forwared mode: length of the plaintext
|
||||
// In reverse mode: length of the ciphertext. Takes header and trailer into
|
||||
// account.
|
||||
Length uint64
|
||||
fs *ContentEnc
|
||||
}
|
||||
|
||||
// isPartial - is the block partial? This means we have to do read-modify-write.
|
||||
@ -47,3 +56,14 @@ func (ib *intraBlock) JointCiphertextRange(blocks []intraBlock) (offset uint64,
|
||||
|
||||
return offset, length
|
||||
}
|
||||
|
||||
// Plaintext range corresponding to the sum of all "blocks" (complete blocks)
|
||||
func JointPlaintextRange(blocks []intraBlock) (offset uint64, length uint64) {
|
||||
firstBlock := blocks[0]
|
||||
lastBlock := blocks[len(blocks)-1]
|
||||
|
||||
offset = firstBlock.BlockPlainOff()
|
||||
length = lastBlock.BlockPlainOff() + lastBlock.fs.PlainBS() - offset
|
||||
|
||||
return offset, length
|
||||
}
|
||||
|
@ -11,8 +11,11 @@ func (be *ContentEnc) PlainOffToBlockNo(plainOffset uint64) uint64 {
|
||||
return plainOffset / be.plainBS
|
||||
}
|
||||
|
||||
// get the block number at ciphter-text offset
|
||||
// get the block number at cipher-text offset
|
||||
func (be *ContentEnc) CipherOffToBlockNo(cipherOffset uint64) uint64 {
|
||||
if cipherOffset < HEADER_LEN {
|
||||
panic("BUG: offset is inside the file header")
|
||||
}
|
||||
return (cipherOffset - HEADER_LEN) / be.cipherBS
|
||||
}
|
||||
|
||||
@ -89,6 +92,32 @@ func (be *ContentEnc) ExplodePlainRange(offset uint64, length uint64) []intraBlo
|
||||
return blocks
|
||||
}
|
||||
|
||||
// Split a ciphertext byte range into (possibly partial) blocks
|
||||
// This is used in reverse mode when reading files
|
||||
func (be *ContentEnc) ExplodeCipherRange(offset uint64, length uint64) []intraBlock {
|
||||
var blocks []intraBlock
|
||||
var nextBlock intraBlock
|
||||
nextBlock.fs = be
|
||||
|
||||
for length > 0 {
|
||||
nextBlock.BlockNo = be.CipherOffToBlockNo(offset)
|
||||
nextBlock.Skip = offset - be.BlockNoToCipherOff(nextBlock.BlockNo)
|
||||
|
||||
// This block can carry up to "maxLen" payload bytes
|
||||
maxLen := be.cipherBS - nextBlock.Skip
|
||||
nextBlock.Length = maxLen
|
||||
// But if the user requested less, we truncate the block to "length".
|
||||
if length < maxLen {
|
||||
nextBlock.Length = length
|
||||
}
|
||||
|
||||
blocks = append(blocks, nextBlock)
|
||||
offset += nextBlock.Length
|
||||
length -= nextBlock.Length
|
||||
}
|
||||
return blocks
|
||||
}
|
||||
|
||||
func (be *ContentEnc) BlockOverhead() uint64 {
|
||||
return be.cipherBS - be.plainBS
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user