From c28f3fdd66c761523df48d9c74623b0c7c4b4c35 Mon Sep 17 00:00:00 2001 From: chrislu Date: Mon, 17 Nov 2025 16:09:13 -0800 Subject: [PATCH] correct IV based on its position within that part, not its position in the entire object --- weed/s3api/s3api_object_handlers.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/weed/s3api/s3api_object_handlers.go b/weed/s3api/s3api_object_handlers.go index ec33edf6c..1622d6811 100644 --- a/weed/s3api/s3api_object_handlers.go +++ b/weed/s3api/s3api_object_handlers.go @@ -1288,12 +1288,12 @@ func (s3a *S3ApiServer) decryptSSECChunkView(ctx context.Context, fileChunk *fil return nil, fmt.Errorf("failed to fetch chunk view: %w", err) } - // Calculate IV using both PartOffset and OffsetInChunk for CTR seek - // CTR mode allows seeking by adjusting the IV to any byte offset - absoluteOffset := ssecMetadata.PartOffset + chunkView.OffsetInChunk + // For multipart SSE-C, each part is encrypted independently from offset 0 + // PartOffset tells us where this part sits in the final object, but encryption starts at 0 + // Only use OffsetInChunk for IV adjustment, not PartOffset var adjustedIV []byte - if absoluteOffset > 0 { - adjustedIV = adjustCTRIV(chunkIV, absoluteOffset) + if chunkView.OffsetInChunk > 0 { + adjustedIV = adjustCTRIV(chunkIV, chunkView.OffsetInChunk) } else { adjustedIV = chunkIV }