aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorJakob Unterwurzacher2021-05-26 09:08:52 +0200
committerJakob Unterwurzacher2021-05-26 13:17:56 +0200
commitb4794bedecbddfd90c2a018825a798d2989a2838 (patch)
tree300b323cb4a0de7603f4e62722143ae66f47d38c /internal
parentbebd7ed81f9dd99113672ed9e22456d3fdbc24f6 (diff)
contentenc: fix CipherSizeToPlainSize non-monoticity
For an illegal cipherSize, pretend we have an additional 1-byte block. See code comment for details.
Diffstat (limited to 'internal')
-rw-r--r--internal/contentenc/offsets.go15
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