mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2025-09-19 06:37:56 +08:00
Files
43 lines
1.5 KiB
Go
43 lines
1.5 KiB
Go
package s3api
|
|||
|
|||
import "github.com/seaweedfs/seaweedfs/weed/glog"
|
|||
|
|||
// calculateIVWithOffset calculates a unique IV by combining a base IV with an offset.
|
|||
// This ensures each chunk/part uses a unique IV, preventing CTR mode IV reuse vulnerabilities.
|
|||
// This function is shared between SSE-KMS and SSE-S3 implementations for consistency.
|
|||
func calculateIVWithOffset(baseIV []byte, offset int64) []byte {
|
|||
if len(baseIV) != 16 {
|
|||
glog.Errorf("Invalid base IV length: expected 16, got %d", len(baseIV))
|
|||
return baseIV // Return original IV as fallback
|
|||
}
|
|||
|
|||
// Create a copy of the base IV to avoid modifying the original
|
|||
iv := make([]byte, 16)
|
|||
copy(iv, baseIV)
|
|||
|
|||
// Calculate the block offset (AES block size is 16 bytes)
|
|||
blockOffset := offset / 16
|
|||
originalBlockOffset := blockOffset
|
|||
|
|||
// Add the block offset to the IV counter (last 8 bytes, big-endian)
|
|||
// This matches how AES-CTR mode increments the counter
|
|||
// Process from least significant byte (index 15) to most significant byte (index 8)
|
|||
carry := uint64(0)
|
|||
for i := 15; i >= 8; i-- {
|
|||
sum := uint64(iv[i]) + uint64(blockOffset&0xFF) + carry
|
|||
iv[i] = byte(sum & 0xFF)
|
|||
carry = sum >> 8
|
|||
blockOffset = blockOffset >> 8
|
|||
|
|||
// If no more blockOffset bits and no carry, we can stop early
|
|||
if blockOffset == 0 && carry == 0 {
|
|||
break
|
|||
}
|
|||
}
|
|||
|
|||
// Single consolidated debug log to avoid performance impact in high-throughput scenarios
|
|||
glog.V(4).Infof("calculateIVWithOffset: baseIV=%x, offset=%d, blockOffset=%d, derivedIV=%x",
|
|||
baseIV, offset, originalBlockOffset, iv)
|
|||
return iv
|
|||
}
|