From 7a34c88d73f64ca03209902e27ca4f5f622c395c Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sat, 31 Aug 2024 11:25:48 -0700 Subject: [PATCH] add consistent nonce to make multipart deterministic per part (#20359) This change adds a consistent nonce to ensure that multipart uploads are deterministic on a per-part basis. Thanks to @klauspost for the work here minio/sio@3cd3734 --- cmd/object-multipart-handlers.go | 23 +++++++++++++++++++++-- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/cmd/object-multipart-handlers.go b/cmd/object-multipart-handlers.go index 512dcec88..d32ad30d4 100644 --- a/cmd/object-multipart-handlers.go +++ b/cmd/object-multipart-handlers.go @@ -20,6 +20,7 @@ package cmd import ( "bufio" "context" + "fmt" "io" "net/http" "net/url" @@ -44,6 +45,7 @@ import ( "github.com/minio/minio/internal/fips" "github.com/minio/minio/internal/handlers" "github.com/minio/minio/internal/hash" + "github.com/minio/minio/internal/hash/sha256" xhttp "github.com/minio/minio/internal/http" "github.com/minio/minio/internal/logger" "github.com/minio/mux" @@ -516,8 +518,16 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt } copy(objectEncryptionKey[:], key) + var nonce [12]byte + tmp := sha256.Sum256([]byte(fmt.Sprint(uploadID, partID))) + copy(nonce[:], tmp[:12]) + partEncryptionKey := objectEncryptionKey.DerivePartKey(uint32(partID)) - encReader, err := sio.EncryptReader(reader, sio.Config{Key: partEncryptionKey[:], CipherSuites: fips.DARECiphers()}) + encReader, err := sio.EncryptReader(reader, sio.Config{ + Key: partEncryptionKey[:], + CipherSuites: fips.DARECiphers(), + Nonce: &nonce, + }) if err != nil { writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL) return @@ -806,7 +816,16 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http // We add a buffer on bigger files to reduce the number of syscalls upstream. in = bufio.NewReaderSize(hashReader, encryptBufferSize) } - reader, err = sio.EncryptReader(in, sio.Config{Key: partEncryptionKey[:], CipherSuites: fips.DARECiphers()}) + + var nonce [12]byte + tmp := sha256.Sum256([]byte(fmt.Sprint(uploadID, partID))) + copy(nonce[:], tmp[:12]) + + reader, err = sio.EncryptReader(in, sio.Config{ + Key: partEncryptionKey[:], + CipherSuites: fips.DARECiphers(), + Nonce: &nonce, + }) if err != nil { writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL) return diff --git a/go.mod b/go.mod index b24546958..6d395704c 100644 --- a/go.mod +++ b/go.mod @@ -57,7 +57,7 @@ require ( github.com/minio/pkg/v3 v3.0.13 github.com/minio/selfupdate v0.6.0 github.com/minio/simdjson-go v0.4.5 - github.com/minio/sio v0.4.0 + github.com/minio/sio v0.4.1 github.com/minio/xxml v0.0.3 github.com/minio/zipindex v0.3.1 github.com/mitchellh/go-homedir v1.1.0 diff --git a/go.sum b/go.sum index 24efce755..9ac7cb6d0 100644 --- a/go.sum +++ b/go.sum @@ -446,8 +446,8 @@ github.com/minio/selfupdate v0.6.0/go.mod h1:bO02GTIPCMQFTEvE5h4DjYB58bCoZ35XLeB github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/simdjson-go v0.4.5 h1:r4IQwjRGmWCQ2VeMc7fGiilu1z5du0gJ/I/FsKwgo5A= github.com/minio/simdjson-go v0.4.5/go.mod h1:eoNz0DcLQRyEDeaPr4Ru6JpjlZPzbA0IodxVJk8lO8E= -github.com/minio/sio v0.4.0 h1:u4SWVEm5lXSqU42ZWawV0D9I5AZ5YMmo2RXpEQ/kRhc= -github.com/minio/sio v0.4.0/go.mod h1:oBSjJeGbBdRMZZwna07sX9EFzZy+ywu5aofRiV1g79I= +github.com/minio/sio v0.4.1 h1:EMe3YBC1nf+sRQia65Rutxi+Z554XPV0dt8BIBA+a/0= +github.com/minio/sio v0.4.1/go.mod h1:oBSjJeGbBdRMZZwna07sX9EFzZy+ywu5aofRiV1g79I= github.com/minio/websocket v1.6.0 h1:CPvnQvNvlVaQmvw5gtJNyYQhg4+xRmrPNhBbv8BdpAE= github.com/minio/websocket v1.6.0/go.mod h1:COH1CePZfHT9Ec1O7vZjTlX5uEPpyYnrifPNbu665DM= github.com/minio/xxml v0.0.3 h1:ZIpPQpfyG5uZQnqqC0LZuWtPk/WT8G/qkxvO6jb7zMU=