s3_sse_utils.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. package s3api
  2. import "github.com/seaweedfs/seaweedfs/weed/glog"
  3. // calculateIVWithOffset calculates a unique IV by combining a base IV with an offset.
  4. // This ensures each chunk/part uses a unique IV, preventing CTR mode IV reuse vulnerabilities.
  5. // This function is shared between SSE-KMS and SSE-S3 implementations for consistency.
  6. func calculateIVWithOffset(baseIV []byte, offset int64) []byte {
  7. if len(baseIV) != 16 {
  8. glog.Errorf("Invalid base IV length: expected 16, got %d", len(baseIV))
  9. return baseIV // Return original IV as fallback
  10. }
  11. // Create a copy of the base IV to avoid modifying the original
  12. iv := make([]byte, 16)
  13. copy(iv, baseIV)
  14. // Calculate the block offset (AES block size is 16 bytes)
  15. blockOffset := offset / 16
  16. originalBlockOffset := blockOffset
  17. // Add the block offset to the IV counter (last 8 bytes, big-endian)
  18. // This matches how AES-CTR mode increments the counter
  19. // Process from least significant byte (index 15) to most significant byte (index 8)
  20. carry := uint64(0)
  21. for i := 15; i >= 8; i-- {
  22. sum := uint64(iv[i]) + uint64(blockOffset&0xFF) + carry
  23. iv[i] = byte(sum & 0xFF)
  24. carry = sum >> 8
  25. blockOffset = blockOffset >> 8
  26. // If no more blockOffset bits and no carry, we can stop early
  27. if blockOffset == 0 && carry == 0 {
  28. break
  29. }
  30. }
  31. // Single consolidated debug log to avoid performance impact in high-throughput scenarios
  32. glog.V(4).Infof("calculateIVWithOffset: baseIV=%x, offset=%d, blockOffset=%d, derivedIV=%x",
  33. baseIV, offset, originalBlockOffset, iv)
  34. return iv
  35. }