diff --git a/internal/cache/storage_protection.go b/internal/cache/storage_protection.go index caf589dfd..bd6fd32b0 100644 --- a/internal/cache/storage_protection.go +++ b/internal/cache/storage_protection.go @@ -102,9 +102,5 @@ func AuthenticatedEncryptionProtection(key []byte) (StorageProtection, error) { return nil, errors.Wrap(err, "unable to create encryptor") } - if !e.IsAuthenticated() { - return nil, errors.Wrap(err, "encryption is not authenticated!") - } - return authenticatedEncryptionProtection{e}, nil } diff --git a/repo/content/committed_read_manager.go b/repo/content/committed_read_manager.go index 0f3cf4caf..36252e3c1 100644 --- a/repo/content/committed_read_manager.go +++ b/repo/content/committed_read_manager.go @@ -1,9 +1,7 @@ package content import ( - "bytes" "context" - "crypto/aes" "os" "sync" "sync/atomic" @@ -230,19 +228,15 @@ func (sm *SharedManager) decryptContentAndVerify(payload []byte, bi *Info) ([]by func (sm *SharedManager) decryptAndVerify(encrypted, iv []byte) ([]byte, error) { decrypted, err := sm.encryptor.Decrypt(nil, encrypted, iv) if err != nil { + sm.Stats.foundInvalidContent() return nil, errors.Wrap(err, "decrypt") } + sm.Stats.foundValidContent() sm.Stats.decrypted(len(decrypted)) - if sm.encryptor.IsAuthenticated() { - // already verified - return decrypted, nil - } - - // Since the encryption key is a function of data, we must be able to generate exactly the same key - // after decrypting the content. This serves as a checksum. - return decrypted, sm.verifyChecksum(decrypted, iv) + // already verified + return decrypted, nil } // IndexBlobs returns the list of active index blobs. @@ -250,22 +244,6 @@ func (sm *SharedManager) IndexBlobs(ctx context.Context, includeInactive bool) ( return sm.indexBlobManager.listIndexBlobs(ctx, includeInactive) } -func (sm *SharedManager) verifyChecksum(data, contentID []byte) error { - var hashOutput [maxHashSize]byte - - expected := sm.hasher(hashOutput[:0], data) - expected = expected[len(expected)-aes.BlockSize:] - - if !bytes.HasSuffix(contentID, expected) { - sm.Stats.foundInvalidContent() - return errors.Errorf("invalid checksum for blob %x, expected %x", contentID, expected) - } - - sm.Stats.foundValidContent() - - return nil -} - func (sm *SharedManager) setupReadManagerCaches(ctx context.Context, caching *CachingOptions) error { dataCacheStorage, err := cache.NewStorageOrNil(ctx, caching.CacheDirectory, caching.MaxCacheSizeBytes, "contents") if err != nil { @@ -389,7 +367,7 @@ func NewSharedManager(ctx context.Context, st blob.Storage, f *FormattingOptions repositoryFormatBytes: opts.RepositoryFormatBytes, checkInvariantsOnUnlock: os.Getenv("KOPIA_VERIFY_INVARIANTS") != "", writeFormatVersion: int32(f.Version), - encryptionBufferPool: buf.NewPool(ctx, defaultEncryptionBufferPoolSegmentSize+encryptor.MaxOverhead(), "content-manager-encryption"), + encryptionBufferPool: buf.NewPool(ctx, defaultEncryptionBufferPoolSegmentSize+encryptor.Overhead(), "content-manager-encryption"), } caching = caching.CloneOrDefault() diff --git a/repo/content/content_manager_lock_free.go b/repo/content/content_manager_lock_free.go index ac4f7f275..a7d8580c5 100644 --- a/repo/content/content_manager_lock_free.go +++ b/repo/content/content_manager_lock_free.go @@ -25,7 +25,7 @@ func (sm *SharedManager) maybeEncryptContentDataForPacking(output *gather.WriteB return errors.Wrapf(err, "unable to get packed content IV for %q", contentID) } - b := sm.encryptionBufferPool.Allocate(len(data) + sm.encryptor.MaxOverhead()) + b := sm.encryptionBufferPool.Allocate(len(data) + sm.encryptor.Overhead()) defer b.Release() cipherText, err := sm.encryptor.Encrypt(b.Data[:0], data, iv) diff --git a/repo/content/index_blob_manager_test.go b/repo/content/index_blob_manager_test.go index bbac98b99..85e1f8a9c 100644 --- a/repo/content/index_blob_manager_test.go +++ b/repo/content/index_blob_manager_test.go @@ -748,7 +748,7 @@ func newIndexBlobManagerForTesting(t *testing.T, st blob.Storage, localTimeNow f t.Helper() p := &FormattingOptions{ - Encryption: encryption.DeprecatedNoneAlgorithm, + Encryption: encryption.DefaultAlgorithm, Hash: hashing.DefaultAlgorithm, } diff --git a/repo/encryption/aes256_gcm_hmac_sha256_encryptor.go b/repo/encryption/aes256_gcm_hmac_sha256_encryptor.go index 55644fea0..f41a91135 100644 --- a/repo/encryption/aes256_gcm_hmac_sha256_encryptor.go +++ b/repo/encryption/aes256_gcm_hmac_sha256_encryptor.go @@ -56,15 +56,7 @@ func (e aes256GCMHmacSha256) Encrypt(output, input, contentID []byte) ([]byte, e return aeadSealWithRandomNonce(output, a, input, contentID) } -func (e aes256GCMHmacSha256) IsAuthenticated() bool { - return true -} - -func (e aes256GCMHmacSha256) IsDeprecated() bool { - return false -} - -func (e aes256GCMHmacSha256) MaxOverhead() int { +func (e aes256GCMHmacSha256) Overhead() int { return aes256GCMHmacSha256Overhead } diff --git a/repo/encryption/chacha20_poly1305_hmac_sha256_encryptor.go b/repo/encryption/chacha20_poly1305_hmac_sha256_encryptor.go index a590ddcde..8e228aeb3 100644 --- a/repo/encryption/chacha20_poly1305_hmac_sha256_encryptor.go +++ b/repo/encryption/chacha20_poly1305_hmac_sha256_encryptor.go @@ -52,15 +52,7 @@ func (e chacha20poly1305hmacSha256Encryptor) Encrypt(output, input, contentID [] return aeadSealWithRandomNonce(output, a, input, contentID) } -func (e chacha20poly1305hmacSha256Encryptor) IsAuthenticated() bool { - return true -} - -func (e chacha20poly1305hmacSha256Encryptor) IsDeprecated() bool { - return false -} - -func (e chacha20poly1305hmacSha256Encryptor) MaxOverhead() int { +func (e chacha20poly1305hmacSha256Encryptor) Overhead() int { return chacha20poly1305hmacSha256EncryptorOverhead } diff --git a/repo/encryption/deprecated_ctr_encryptor.go b/repo/encryption/deprecated_ctr_encryptor.go deleted file mode 100644 index a2afef268..000000000 --- a/repo/encryption/deprecated_ctr_encryptor.go +++ /dev/null @@ -1,91 +0,0 @@ -package encryption - -import ( - "crypto/aes" - "crypto/cipher" - - "github.com/pkg/errors" -) - -const ( - aes128KeyLength = 16 - aes192KeyLength = 24 - aes256KeyLength = 32 -) - -// ctrEncryptor implements encrypted format which uses CTR mode of a content cipher with nonce==IV. -type ctrEncryptor struct { - createCipher func() (cipher.Block, error) -} - -func (fi ctrEncryptor) Encrypt(output, plainText, contentID []byte) ([]byte, error) { - return symmetricEncrypt(output, fi.createCipher, contentID, plainText) -} - -func (fi ctrEncryptor) Decrypt(output, cipherText, contentID []byte) ([]byte, error) { - return symmetricEncrypt(output, fi.createCipher, contentID, cipherText) -} - -func (fi ctrEncryptor) IsAuthenticated() bool { - return false -} - -func (fi ctrEncryptor) IsDeprecated() bool { - return true -} - -func (fi ctrEncryptor) MaxOverhead() int { - return 0 -} - -func symmetricEncrypt(output []byte, createCipher func() (cipher.Block, error), iv, b []byte) ([]byte, error) { - blockCipher, err := createCipher() - if err != nil { - return nil, err - } - - if len(iv) < blockCipher.BlockSize() { - return nil, errors.Errorf("IV too short: %v expected >= %v", len(iv), blockCipher.BlockSize()) - } - - ctr := cipher.NewCTR(blockCipher, iv[0:blockCipher.BlockSize()]) - - result, out := sliceForAppend(output, len(b)) - ctr.XORKeyStream(out, b) - - return result, nil -} - -func adjustKey(masterKey []byte, desiredKeySize int) ([]byte, error) { - if len(masterKey) == desiredKeySize { - return masterKey, nil - } - - if desiredKeySize < len(masterKey) { - return masterKey[0:desiredKeySize], nil - } - - return nil, errors.Errorf("required key too long %v, but only have %v", desiredKeySize, len(masterKey)) -} - -// newCTREncryptorFactory returns new EncryptorFactory that uses CTR with symmetric encryption (such as AES) and a given key size. -func newCTREncryptorFactory(keySize int, createCipherWithKey func(key []byte) (cipher.Block, error)) EncryptorFactory { - return func(o Parameters) (Encryptor, error) { - key, err := adjustKey(o.GetMasterKey(), keySize) - if err != nil { - return nil, errors.Wrap(err, "unable to get encryption key") - } - - return ctrEncryptor{ - createCipher: func() (cipher.Block, error) { - return createCipherWithKey(key) - }, - }, nil - } -} - -func init() { - Register("AES-128-CTR", "DEPRECATED: AES-128 in CTR mode", true, newCTREncryptorFactory(aes128KeyLength, aes.NewCipher)) - Register("AES-192-CTR", "DEPRECATED: AES-192 in CTR mode", true, newCTREncryptorFactory(aes192KeyLength, aes.NewCipher)) - Register("AES-256-CTR", "DEPRECATED: AES-256 in CTR mode", true, newCTREncryptorFactory(aes256KeyLength, aes.NewCipher)) -} diff --git a/repo/encryption/deprecated_salsa_encryptor.go b/repo/encryption/deprecated_salsa_encryptor.go deleted file mode 100644 index c23942787..000000000 --- a/repo/encryption/deprecated_salsa_encryptor.go +++ /dev/null @@ -1,100 +0,0 @@ -package encryption - -import ( - "crypto/sha256" - - "github.com/pkg/errors" - "golang.org/x/crypto/salsa20" - - "github.com/kopia/kopia/internal/hmac" -) - -const ( - purposeEncryptionKey = "encryption" - purposeHMACSecret = "hmac" - hmacLength = 32 - salsaKeyLength = 32 -) - -type salsaEncryptor struct { - nonceSize int - key *[32]byte - hmacSecret []byte -} - -func (s salsaEncryptor) Decrypt(output, input, contentID []byte) ([]byte, error) { - if s.hmacSecret != nil { - var err error - - input, err = hmac.VerifyAndStrip(input, s.hmacSecret) - if err != nil { - return nil, errors.Wrap(err, "hmac.VerifyAndStrip") - } - } - - return s.encryptDecrypt(output, input, contentID) -} - -func (s salsaEncryptor) Encrypt(output, input, contentID []byte) ([]byte, error) { - v, err := s.encryptDecrypt(output, input, contentID) - if err != nil { - return nil, errors.Wrap(err, "decrypt") - } - - if s.hmacSecret == nil { - return v, nil - } - - return hmac.Append(v, s.hmacSecret), nil -} - -func (s salsaEncryptor) IsAuthenticated() bool { - return s.hmacSecret != nil -} - -func (s salsaEncryptor) MaxOverhead() int { - if s.hmacSecret == nil { - return 0 - } - - return sha256.Size -} - -func (s salsaEncryptor) encryptDecrypt(output, input, contentID []byte) ([]byte, error) { - if len(contentID) < s.nonceSize { - return nil, errors.Errorf("hash too short, expected >=%v bytes, got %v", s.nonceSize, len(contentID)) - } - - result, out := sliceForAppend(output, len(input)) - nonce := contentID[0:s.nonceSize] - salsa20.XORKeyStream(out, input, nonce, s.key) - - return result, nil -} - -func (s salsaEncryptor) IsDeprecated() bool { - return true -} - -func init() { - Register("SALSA20", "DEPRECATED: SALSA20 using shared key and 64-bit nonce", true, func(p Parameters) (Encryptor, error) { - var k [salsaKeyLength]byte - copy(k[:], p.GetMasterKey()[0:salsaKeyLength]) - return salsaEncryptor{8, &k, nil}, nil - }) - - Register("SALSA20-HMAC", "DEPRECATED: SALSA20 with HMAC-SHA256 using shared key and 64-bit nonce", true, func(p Parameters) (Encryptor, error) { - encryptionKey, err := deriveKey(p, []byte(purposeEncryptionKey), salsaKeyLength) - if err != nil { - return nil, err - } - hmacSecret, err := deriveKey(p, []byte(purposeHMACSecret), hmacLength) - if err != nil { - return nil, err - } - - var k [salsaKeyLength]byte - copy(k[:], encryptionKey) - return salsaEncryptor{8, &k, hmacSecret}, nil - }) -} diff --git a/repo/encryption/encryption.go b/repo/encryption/encryption.go index 299a68e1a..027cb3ace 100644 --- a/repo/encryption/encryption.go +++ b/repo/encryption/encryption.go @@ -10,7 +10,11 @@ "golang.org/x/crypto/hkdf" ) -const minDerivedKeyLength = 32 +const ( + minDerivedKeyLength = 32 + + purposeEncryptionKey = "encryption" +) // Encryptor performs encryption and decryption of contents of data. type Encryptor interface { @@ -23,15 +27,8 @@ type Encryptor interface { // authenticity check before decrypting. Decrypt(output, cipherText, contentID []byte) ([]byte, error) - // IsAuthenticated returns true if encryption is authenticated. - // In this case Decrypt() is expected to perform authenticity check. - IsAuthenticated() bool - - // IsDeprecated returns true if encryption is not recommended for new repositories. - IsDeprecated() bool - - // MaxOverhead is the maximum number of bytes of overhead added by Encrypt() - MaxOverhead() int + // Overhead is the number of bytes of overhead added by Encrypt() + Overhead() int } // Parameters encapsulates all encryption parameters. @@ -56,9 +53,6 @@ func CreateEncryptor(p Parameters) (Encryptor, error) { // DefaultAlgorithm is the name of the default encryption algorithm. const DefaultAlgorithm = "AES256-GCM-HMAC-SHA256" -// DeprecatedNoneAlgorithm is the name of the algorithm that does not encrypt. -const DeprecatedNoneAlgorithm = "NONE" - // SupportedAlgorithms returns the names of the supported encryption // methods. func SupportedAlgorithms(includeDeprecated bool) []string { @@ -95,7 +89,6 @@ type encryptorInfo struct { var encryptors = map[string]*encryptorInfo{} // deriveKey uses HKDF to derive a key of a given length and a given purpose from parameters. -// nolint:unparam func deriveKey(p Parameters, purpose []byte, length int) ([]byte, error) { if length < minDerivedKeyLength { return nil, errors.Errorf("derived key must be at least 32 bytes, was %v", length) @@ -107,23 +100,3 @@ func deriveKey(p Parameters, purpose []byte, length int) ([]byte, error) { return key, nil } - -// sliceForAppend takes a slice and a requested number of bytes. It returns a -// slice with the contents of the given slice followed by that many bytes and a -// second slice that aliases into it and contains only the extra bytes. If the -// original slice has sufficient capacity then no allocation is performed. -// -// From: https://golang.org/src/crypto/cipher/gcm.go -// Copyright 2013 The Go Authors. All rights reserved. -func sliceForAppend(in []byte, n int) (head, tail []byte) { - if total := len(in) + n; cap(in) >= total { - head = in[:total] - } else { - head = make([]byte, total) - copy(head, in) - } - - tail = head[len(in):] - - return -} diff --git a/repo/encryption/encryption_test.go b/repo/encryption/encryption_test.go index 2b661a236..682f94d16 100644 --- a/repo/encryption/encryption_test.go +++ b/repo/encryption/encryption_test.go @@ -45,15 +45,13 @@ func TestRoundTrip(t *testing.T) { t.Errorf("invalid response from Encrypt: %v %v", cipherText1, err) } - if !e.IsDeprecated() && encryptionAlgo != encryption.DeprecatedNoneAlgorithm { - cipherText1b, err2 := e.Encrypt(nil, data, contentID1) - if err2 != nil || cipherText1b == nil { - t.Errorf("invalid response from Encrypt: %v %v", cipherText1, err2) - } + cipherText1b, err2 := e.Encrypt(nil, data, contentID1) + if err2 != nil || cipherText1b == nil { + t.Errorf("invalid response from Encrypt: %v %v", cipherText1, err2) + } - if bytes.Equal(cipherText1, cipherText1b) { - t.Errorf("multiple Encrypt returned the same ciphertext: %x", cipherText1) - } + if bytes.Equal(cipherText1, cipherText1b) { + t.Errorf("multiple Encrypt returned the same ciphertext: %x", cipherText1) } plainText1, err := e.Decrypt(nil, cipherText1, contentID1) @@ -90,33 +88,19 @@ func TestRoundTrip(t *testing.T) { t.Errorf("Encrypt()/Decrypt() does not round-trip: %x %x", plainText2, data) } - if encryptionAlgo != encryption.DeprecatedNoneAlgorithm { - if bytes.Equal(cipherText1, cipherText2) { - t.Errorf("ciphertexts should be different, were %x", cipherText1) - } + if bytes.Equal(cipherText1, cipherText2) { + t.Errorf("ciphertexts should be different, were %x", cipherText1) + } - // decrypt using wrong content ID - badPlainText2, err := e.Decrypt(nil, cipherText2, contentID1) - if e.IsAuthenticated() { - if err == nil && encryptionAlgo != "SALSA20-HMAC" { - // "SALSA20-HMAC" is deprecated & wrong, and only validates that checksum is - // valid for some content, but does not validate that we decrypted the - // intended content. - t.Errorf("expected decrypt to fail for authenticated encryption") - } - } else { - if bytes.Equal(badPlainText2, plainText2) { - t.Errorf("decrypted plaintext matches, but it should not: %x", plainText2) - } - } + // decrypt using wrong content ID + if _, err := e.Decrypt(nil, cipherText2, contentID1); err == nil { + t.Fatalf("expected decrypt to fail for authenticated encryption") + } - // flip some bits in the cipherText - if e.IsAuthenticated() { - cipherText2[mathrand.Intn(len(cipherText2))] ^= byte(1 + mathrand.Intn(254)) - if _, err := e.Decrypt(nil, cipherText2, contentID1); err == nil { - t.Errorf("expected decrypt failure on invalid ciphertext, got success") - } - } + // flip some bits in the cipherText + cipherText2[mathrand.Intn(len(cipherText2))] ^= byte(1 + mathrand.Intn(254)) + if _, err := e.Decrypt(nil, cipherText2, contentID1); err == nil { + t.Errorf("expected decrypt failure on invalid ciphertext, got success") } }) } @@ -136,17 +120,8 @@ func TestCiphertextSamples(t *testing.T) { // samples of base16-encoded ciphertexts of payload encrypted with masterKey & contentID samples: map[string]string{ - "NONE": hex.EncodeToString([]byte("foo")), - "AES256-GCM-HMAC-SHA256": "e43ba07f85a6d70c5f1102ca06cf19c597e5f91e527b21f00fb76e8bec3fd1", "CHACHA20-POLY1305-HMAC-SHA256": "118359f3d4d589d939efbbc3168ae4c77c51bcebce6845fe6ef5d11342faa6", - - // deprecated - "AES-128-CTR": "54cd8d", - "AES-192-CTR": "2d084b", - "AES-256-CTR": "8a580a", - "SALSA20": "bf5ec3", - "SALSA20-HMAC": "8bf37fd9ec69843c3c2ac2a2cfdd59f36077206a15289efde640d0e677d03e6ac8f8ec", }, }, { @@ -156,17 +131,8 @@ func TestCiphertextSamples(t *testing.T) { // samples of base16-encoded ciphertexts of payload encrypted with masterKey & contentID samples: map[string]string{ - "NONE": hex.EncodeToString([]byte("quick brown fox jumps over the lazy dog")), - "AES256-GCM-HMAC-SHA256": "eaad755a238f1daa4052db2e5ccddd934790b6cca415b3ccfd46ac5746af33d9d30f4400ffa9eb3a64fb1ce21b888c12c043bf6787d4a5c15ad10f21f6a6027ee3afe0", "CHACHA20-POLY1305-HMAC-SHA256": "836d2ba87892711077adbdbe1452d3b2c590bbfdf6fd3387dc6810220a32ec19de862e1a4f865575e328424b5f178afac1b7eeff11494f719d119b7ebb924d1d0846a3", - - // deprecated - "AES-128-CTR": "974c5c1782076e3de7255deabe8706a509b5772a8b7a8e7f83d01de7098c945934417071ec5351", - "AES-192-CTR": "1200e755ec14125e87136b5281957895eeb429be673b2241da261f949283aea59fd2fa64387764", - "AES-256-CTR": "39f13367828efb5fb22b97865ca0dbaad352d0c1a3083ff056bc771b812239445ed8af022f3760", - "SALSA20": "65ce12b14739aecbf9e6a9b9b9c4a72ffa8886fe0b071c0abdfb3d3e5c336b90f9af411ba69faf", - "SALSA20-HMAC": "a1dc47f250def4d97a422d505fb5e9a9a13699762cb32cfe7705982fa68ce71f54544ab932a1045fb0601087159954d563f0de0aaa15690d93ea63748bf91889e577daeeed5cf8", }, }, } diff --git a/repo/encryption/null_encryptor.go b/repo/encryption/null_encryptor.go deleted file mode 100644 index 84173e4bf..000000000 --- a/repo/encryption/null_encryptor.go +++ /dev/null @@ -1,30 +0,0 @@ -package encryption - -// nullEncryptor implements non-encrypted format. -type nullEncryptor struct{} - -func (fi nullEncryptor) Encrypt(output, plainText, contentID []byte) ([]byte, error) { - return append(output, plainText...), nil -} - -func (fi nullEncryptor) Decrypt(output, cipherText, contentID []byte) ([]byte, error) { - return append(output, cipherText...), nil -} - -func (fi nullEncryptor) IsAuthenticated() bool { - return false -} - -func (fi nullEncryptor) IsDeprecated() bool { - return false -} - -func (fi nullEncryptor) MaxOverhead() int { - return 0 -} - -func init() { - Register(DeprecatedNoneAlgorithm, "No encryption", true, func(p Parameters) (Encryptor, error) { - return nullEncryptor{}, nil - }) -} diff --git a/repo/maintenance/blob_gc_test.go b/repo/maintenance/blob_gc_test.go index 9257cabc4..29864575a 100644 --- a/repo/maintenance/blob_gc_test.go +++ b/repo/maintenance/blob_gc_test.go @@ -11,6 +11,7 @@ "github.com/google/go-cmp/cmp" "github.com/pkg/errors" + "github.com/stretchr/testify/require" "github.com/kopia/kopia/internal/clock" "github.com/kopia/kopia/internal/faketime" @@ -20,11 +21,14 @@ "github.com/kopia/kopia/repo" "github.com/kopia/kopia/repo/blob" "github.com/kopia/kopia/repo/content" + "github.com/kopia/kopia/repo/encryption" "github.com/kopia/kopia/repo/object" ) var testHMACSecret = []byte{1, 2, 3} +var testMasterKey = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} + func TestDeleteUnreferencedBlobs(t *testing.T) { // set up fake clock which is initially synchronized to wall clock time // and moved at the same speed but which can be moved forward. @@ -35,7 +39,8 @@ func TestDeleteUnreferencedBlobs(t *testing.T) { o.TimeNowFunc = ta.NowFunc() }, NewRepositoryOptions: func(nro *repo.NewRepositoryOptions) { - nro.BlockFormat.Encryption = "NONE" + nro.BlockFormat.Encryption = encryption.DefaultAlgorithm + nro.BlockFormat.MasterKey = testMasterKey nro.BlockFormat.Hash = "HMAC-SHA256" nro.BlockFormat.HMACSecret = testHMACSecret }, @@ -190,11 +195,22 @@ func mustPutDummySessionBlob(t *testing.T, st blob.Storage, sessionIDSuffix blob h := hmac.New(sha256.New, testHMACSecret) h.Write(j) - blobID := blob.ID(fmt.Sprintf("s%x-%v", h.Sum(nil)[16:32], sessionIDSuffix)) + iv := h.Sum(nil)[16:32] - if err := st.PutBlob(testlogging.Context(t), blobID, gather.FromSlice(j)); err != nil { - t.Fatal(err) - } + blobID := blob.ID(fmt.Sprintf("s%x-%v", iv, sessionIDSuffix)) + + e, err := encryption.CreateEncryptor(&content.FormattingOptions{ + Encryption: encryption.DefaultAlgorithm, + MasterKey: testMasterKey, + HMACSecret: testHMACSecret, + }) + + require.NoError(t, err) + + enc, err := e.Encrypt(nil, j, iv) + require.NoError(t, err) + + require.NoError(t, st.PutBlob(testlogging.Context(t), blobID, gather.FromSlice(enc))) return blobID } diff --git a/tests/stress_test/stress_test.go b/tests/stress_test/stress_test.go index 57dd6bec9..5511c5949 100644 --- a/tests/stress_test/stress_test.go +++ b/tests/stress_test/stress_test.go @@ -14,6 +14,7 @@ "github.com/kopia/kopia/internal/testlogging" "github.com/kopia/kopia/repo/blob" "github.com/kopia/kopia/repo/content" + "github.com/kopia/kopia/repo/encryption" ) const goroutineCount = 16 @@ -43,7 +44,7 @@ func stressTestWithStorage(t *testing.T, st blob.Storage, duration time.Duration return content.NewManager(ctx, st, &content.FormattingOptions{ Version: 1, Hash: "HMAC-SHA256-128", - Encryption: "AES-256-CTR", + Encryption: encryption.DefaultAlgorithm, MaxPackSize: 20000000, MasterKey: []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, }, nil, nil)