internal/stream: reject negative and overflowing encrypted sizes

This commit is contained in:
Filippo Valsorda
2026-08-29 14:26:05 +02:00
parent 04f65ea9fc
commit 91bc452b9a
2 changed files with 16 additions and 0 deletions
+4
View File
@@ -12,6 +12,7 @@ import (
"errors"
"fmt"
"io"
"math"
"sync/atomic"
"golang.org/x/crypto/chacha20poly1305"
@@ -20,6 +21,9 @@ import (
const ChunkSize = 64 * 1024
func EncryptedChunkCount(encryptedSize int64) (int64, error) {
if encryptedSize < 0 || encryptedSize > math.MaxInt64-encChunkSize+1 {
return 0, fmt.Errorf("invalid encrypted payload size: %d", encryptedSize)
}
chunks := (encryptedSize + encChunkSize - 1) / encChunkSize
plaintextSize := encryptedSize - chunks*chacha20poly1305.Overhead
+12
View File
@@ -10,6 +10,7 @@ import (
"errors"
"fmt"
"io"
"math"
"testing"
"testing/iotest"
@@ -631,6 +632,17 @@ func TestDecryptReaderAtInvalidSize(t *testing.T) {
if err == nil {
t.Error("invalid size (empty final chunk): expected error, got nil")
}
// Negative sizes and sizes that would overflow the chunk count computation
// must be rejected with an error rather than a panic.
for _, size := range []int64{-1, -70000, math.MaxInt64, math.MaxInt64 - 200, math.MaxInt64 - 65550} {
if _, err := stream.EncryptedChunkCount(size); err == nil {
t.Errorf("EncryptedChunkCount(%d): expected error, got nil", size)
}
if _, err := stream.NewDecryptReaderAt(key, bytes.NewReader(ciphertext), size); err == nil {
t.Errorf("NewDecryptReaderAt(%d): expected error, got nil", size)
}
}
}
func TestDecryptReaderAtTruncated(t *testing.T) {