diff options
author | Jakob Unterwurzacher | 2021-05-26 09:08:52 +0200 |
---|---|---|
committer | Jakob Unterwurzacher | 2021-05-26 13:17:56 +0200 |
commit | b4794bedecbddfd90c2a018825a798d2989a2838 (patch) | |
tree | 300b323cb4a0de7603f4e62722143ae66f47d38c | |
parent | bebd7ed81f9dd99113672ed9e22456d3fdbc24f6 (diff) |
contentenc: fix CipherSizeToPlainSize non-monoticity
For an illegal cipherSize, pretend we have an additional
1-byte block.
See code comment for details.
-rw-r--r-- | internal/contentenc/offsets.go | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/internal/contentenc/offsets.go b/internal/contentenc/offsets.go index fdeb583..7487baf 100644 --- a/internal/contentenc/offsets.go +++ b/internal/contentenc/offsets.go @@ -31,7 +31,11 @@ func (be *ContentEnc) BlockNoToPlainOff(blockNo uint64) uint64 { return blockNo * be.plainBS } -// CipherSizeToPlainSize calculates the plaintext size from a ciphertext size +// CipherSizeToPlainSize calculates the plaintext size `plainSize` from a +// ciphertext size `cipherSize` (in bytes). +// +// Not all ciphertext sizes are legal due to the per-block overheads. +// For an illegal cipherSize, we return a best guess plainSize. func (be *ContentEnc) CipherSizeToPlainSize(cipherSize uint64) uint64 { // Zero-sized files stay zero-sized if cipherSize == 0 { @@ -49,6 +53,15 @@ func (be *ContentEnc) CipherSizeToPlainSize(cipherSize uint64) uint64 { return 0 } + // If the last block is incomplete, pad it to 1 byte of plaintext + // (= 33 bytes of ciphertext). + lastBlockSize := (cipherSize - HeaderLen) % be.cipherBS + if lastBlockSize > 0 && lastBlockSize <= be.BlockOverhead() { + tmp := cipherSize - lastBlockSize + be.BlockOverhead() + 1 + tlog.Warn.Printf("cipherSize %d: incomplete last block (%d bytes), padding to %d bytes", cipherSize, lastBlockSize, tmp) + cipherSize = tmp + } + // Block number at last byte blockNo := be.CipherOffToBlockNo(cipherSize - 1) blockCount := blockNo + 1 |