crypto: move crypto buffer helpers

This commit is contained in:
Michael Eischer 2022-06-12 14:48:30 +02:00
parent a0cef9f247
commit 8c11fc3ec9
11 changed files with 29 additions and 26 deletions

View file

@ -11,6 +11,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/restic/restic/internal/crypto"
"github.com/restic/restic/internal/debug" "github.com/restic/restic/internal/debug"
"github.com/restic/restic/internal/fs" "github.com/restic/restic/internal/fs"
"github.com/restic/restic/internal/restic" "github.com/restic/restic/internal/restic"
@ -225,7 +226,7 @@ func TestEnsureFileContent(ctx context.Context, t testing.TB, repo restic.Reposi
return return
} }
content := make([]byte, restic.CiphertextLength(len(file.Content))) content := make([]byte, crypto.CiphertextLength(len(file.Content)))
pos := 0 pos := 0
for _, id := range node.Content { for _, id := range node.Content {
part, err := repo.LoadBlob(ctx, restic.DataBlob, id, content[pos:]) part, err := repo.LoadBlob(ctx, restic.DataBlob, id, content[pos:])

View file

@ -8,6 +8,7 @@ import (
"runtime" "runtime"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/restic/restic/internal/crypto"
"github.com/restic/restic/internal/debug" "github.com/restic/restic/internal/debug"
"github.com/restic/restic/internal/fs" "github.com/restic/restic/internal/fs"
"github.com/restic/restic/internal/restic" "github.com/restic/restic/internal/restic"
@ -58,7 +59,7 @@ func (c *Cache) load(h restic.Handle, length int, offset int64) (io.ReadCloser,
return nil, errors.WithStack(err) return nil, errors.WithStack(err)
} }
if fi.Size() <= int64(restic.CiphertextLength(0)) { if fi.Size() <= int64(crypto.CiphertextLength(0)) {
_ = f.Close() _ = f.Close()
_ = c.remove(h) _ = c.remove(h)
return nil, errors.Errorf("cached file %v is truncated, removing", h) return nil, errors.Errorf("cached file %v is truncated, removing", h)
@ -116,7 +117,7 @@ func (c *Cache) Save(h restic.Handle, rd io.Reader) error {
return errors.Wrap(err, "Copy") return errors.Wrap(err, "Copy")
} }
if n <= int64(restic.CiphertextLength(0)) { if n <= int64(crypto.CiphertextLength(0)) {
_ = f.Close() _ = f.Close()
_ = fs.Remove(f.Name()) _ = fs.Remove(f.Name())
debug.Log("trying to cache truncated file %v, removing", h) debug.Log("trying to cache truncated file %v, removing", h)

View file

@ -1,21 +1,19 @@
package restic package crypto
import "github.com/restic/restic/internal/crypto"
// NewBlobBuffer returns a buffer that is large enough to hold a blob of size // NewBlobBuffer returns a buffer that is large enough to hold a blob of size
// plaintext bytes, including the crypto overhead. // plaintext bytes, including the crypto overhead.
func NewBlobBuffer(size int) []byte { func NewBlobBuffer(size int) []byte {
return make([]byte, size, size+crypto.Extension) return make([]byte, size, size+Extension)
} }
// PlaintextLength returns the plaintext length of a blob with ciphertextSize // PlaintextLength returns the plaintext length of a blob with ciphertextSize
// bytes. // bytes.
func PlaintextLength(ciphertextSize int) int { func PlaintextLength(ciphertextSize int) int {
return ciphertextSize - crypto.Extension return ciphertextSize - Extension
} }
// CiphertextLength returns the encrypted length of a blob with plaintextSize // CiphertextLength returns the encrypted length of a blob with plaintextSize
// bytes. // bytes.
func CiphertextLength(plaintextSize int) int { func CiphertextLength(plaintextSize int) int {
return plaintextSize + crypto.Extension return plaintextSize + Extension
} }

View file

@ -79,7 +79,7 @@ func (p *Packer) Finalize() error {
return err return err
} }
encryptedHeader := make([]byte, 0, restic.CiphertextLength(len(header))) encryptedHeader := make([]byte, 0, crypto.CiphertextLength(len(header)))
nonce := crypto.NewRandomNonce() nonce := crypto.NewRandomNonce()
encryptedHeader = append(encryptedHeader, nonce...) encryptedHeader = append(encryptedHeader, nonce...)
encryptedHeader = p.k.Seal(encryptedHeader, nonce, header, nil) encryptedHeader = p.k.Seal(encryptedHeader, nonce, header, nil)
@ -107,7 +107,7 @@ func (p *Packer) Finalize() error {
// HeaderOverhead returns an estimate of the number of bytes written by a call to Finalize. // HeaderOverhead returns an estimate of the number of bytes written by a call to Finalize.
func (p *Packer) HeaderOverhead() int { func (p *Packer) HeaderOverhead() int {
return restic.CiphertextLength(0) + binary.Size(uint32(0)) return crypto.CiphertextLength(0) + binary.Size(uint32(0))
} }
// makeHeader constructs the header for p. // makeHeader constructs the header for p.
@ -275,7 +275,7 @@ func List(k *crypto.Key, rd io.ReaderAt, size int64) (entries []restic.Blob, hdr
return nil, 0, err return nil, 0, err
} }
if len(buf) < restic.CiphertextLength(0) { if len(buf) < crypto.CiphertextLength(0) {
return nil, 0, errors.New("invalid header, too small") return nil, 0, errors.New("invalid header, too small")
} }

View file

@ -7,6 +7,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/restic/restic/internal/crypto"
"github.com/restic/restic/internal/errors" "github.com/restic/restic/internal/errors"
"github.com/restic/restic/internal/restic" "github.com/restic/restic/internal/restic"
@ -194,7 +195,7 @@ func (idx *Index) LookupSize(bh restic.BlobHandle) (plaintextLength uint, found
if e.uncompressedLength != 0 { if e.uncompressedLength != 0 {
return uint(e.uncompressedLength), true return uint(e.uncompressedLength), true
} }
return uint(restic.PlaintextLength(int(e.length))), true return uint(crypto.PlaintextLength(int(e.length))), true
} }
// Supersedes returns the list of indexes this index supersedes, if any. // Supersedes returns the list of indexes this index supersedes, if any.

View file

@ -263,7 +263,7 @@ func AddKey(ctx context.Context, s *Repository, password, username, hostname str
} }
nonce := crypto.NewRandomNonce() nonce := crypto.NewRandomNonce()
ciphertext := make([]byte, 0, restic.CiphertextLength(len(buf))) ciphertext := make([]byte, 0, crypto.CiphertextLength(len(buf)))
ciphertext = append(ciphertext, nonce...) ciphertext = append(ciphertext, nonce...)
ciphertext = newkey.user.Seal(ciphertext, nonce, buf, nil) ciphertext = newkey.user.Seal(ciphertext, nonce, buf, nil)
newkey.Data = ciphertext newkey.Data = ciphertext

View file

@ -8,6 +8,7 @@ import (
"time" "time"
"github.com/restic/restic/internal/checker" "github.com/restic/restic/internal/checker"
"github.com/restic/restic/internal/crypto"
"github.com/restic/restic/internal/repository" "github.com/restic/restic/internal/repository"
"github.com/restic/restic/internal/restic" "github.com/restic/restic/internal/restic"
rtest "github.com/restic/restic/internal/test" rtest "github.com/restic/restic/internal/test"
@ -22,7 +23,7 @@ func TestMasterIndex(t *testing.T) {
PackID: restic.NewRandomID(), PackID: restic.NewRandomID(),
Blob: restic.Blob{ Blob: restic.Blob{
BlobHandle: bhInIdx1, BlobHandle: bhInIdx1,
Length: uint(restic.CiphertextLength(10)), Length: uint(crypto.CiphertextLength(10)),
Offset: 0, Offset: 0,
}, },
} }
@ -31,7 +32,7 @@ func TestMasterIndex(t *testing.T) {
PackID: restic.NewRandomID(), PackID: restic.NewRandomID(),
Blob: restic.Blob{ Blob: restic.Blob{
BlobHandle: bhInIdx2, BlobHandle: bhInIdx2,
Length: uint(restic.CiphertextLength(100)), Length: uint(crypto.CiphertextLength(100)),
Offset: 10, Offset: 10,
UncompressedLength: 200, UncompressedLength: 200,
}, },
@ -41,7 +42,7 @@ func TestMasterIndex(t *testing.T) {
PackID: restic.NewRandomID(), PackID: restic.NewRandomID(),
Blob: restic.Blob{ Blob: restic.Blob{
BlobHandle: bhInIdx12, BlobHandle: bhInIdx12,
Length: uint(restic.CiphertextLength(123)), Length: uint(crypto.CiphertextLength(123)),
Offset: 110, Offset: 110,
}, },
} }
@ -50,7 +51,7 @@ func TestMasterIndex(t *testing.T) {
PackID: restic.NewRandomID(), PackID: restic.NewRandomID(),
Blob: restic.Blob{ Blob: restic.Blob{
BlobHandle: bhInIdx12, BlobHandle: bhInIdx12,
Length: uint(restic.CiphertextLength(123)), Length: uint(crypto.CiphertextLength(123)),
Offset: 50, Offset: 50,
UncompressedLength: 80, UncompressedLength: 80,
}, },

View file

@ -398,7 +398,7 @@ func (r *Repository) saveAndEncrypt(ctx context.Context, t restic.BlobType, data
nonce := crypto.NewRandomNonce() nonce := crypto.NewRandomNonce()
ciphertext := make([]byte, 0, restic.CiphertextLength(len(data))) ciphertext := make([]byte, 0, crypto.CiphertextLength(len(data)))
ciphertext = append(ciphertext, nonce...) ciphertext = append(ciphertext, nonce...)
// encrypt blob // encrypt blob
@ -475,7 +475,7 @@ func (r *Repository) SaveUnpacked(ctx context.Context, t restic.FileType, p []by
} }
} }
ciphertext := restic.NewBlobBuffer(len(p)) ciphertext := crypto.NewBlobBuffer(len(p))
ciphertext = ciphertext[:0] ciphertext = ciphertext[:0]
nonce := crypto.NewRandomNonce() nonce := crypto.NewRandomNonce()
ciphertext = append(ciphertext, nonce...) ciphertext = append(ciphertext, nonce...)

View file

@ -190,7 +190,7 @@ func testLoadBlob(t *testing.T, version uint) {
defer cleanup() defer cleanup()
length := 1000000 length := 1000000
buf := restic.NewBlobBuffer(length) buf := crypto.NewBlobBuffer(length)
_, err := io.ReadFull(rnd, buf) _, err := io.ReadFull(rnd, buf)
rtest.OK(t, err) rtest.OK(t, err)
@ -201,7 +201,7 @@ func testLoadBlob(t *testing.T, version uint) {
rtest.OK(t, err) rtest.OK(t, err)
rtest.OK(t, repo.Flush(context.Background())) rtest.OK(t, repo.Flush(context.Background()))
base := restic.CiphertextLength(length) base := crypto.CiphertextLength(length)
for _, testlength := range []int{0, base - 20, base - 1, base, base + 7, base + 15, base + 1000} { for _, testlength := range []int{0, base - 20, base - 1, base, base + 7, base + 15, base + 1000} {
buf = make([]byte, 0, testlength) buf = make([]byte, 0, testlength)
buf, err := repo.LoadBlob(context.TODO(), restic.DataBlob, id, buf) buf, err := repo.LoadBlob(context.TODO(), restic.DataBlob, id, buf)
@ -226,7 +226,7 @@ func benchmarkLoadBlob(b *testing.B, version uint) {
defer cleanup() defer cleanup()
length := 1000000 length := 1000000
buf := restic.NewBlobBuffer(length) buf := crypto.NewBlobBuffer(length)
_, err := io.ReadFull(rnd, buf) _, err := io.ReadFull(rnd, buf)
rtest.OK(b, err) rtest.OK(b, err)
@ -269,7 +269,7 @@ func benchmarkLoadUnpacked(b *testing.B, version uint) {
defer cleanup() defer cleanup()
length := 1000000 length := 1000000
buf := restic.NewBlobBuffer(length) buf := crypto.NewBlobBuffer(length)
_, err := io.ReadFull(rnd, buf) _, err := io.ReadFull(rnd, buf)
rtest.OK(b, err) rtest.OK(b, err)

View file

@ -3,6 +3,7 @@ package restic
import ( import (
"fmt" "fmt"
"github.com/restic/restic/internal/crypto"
"github.com/restic/restic/internal/errors" "github.com/restic/restic/internal/errors"
) )
@ -23,7 +24,7 @@ func (b Blob) DataLength() uint {
if b.UncompressedLength != 0 { if b.UncompressedLength != 0 {
return b.UncompressedLength return b.UncompressedLength
} }
return uint(PlaintextLength(int(b.Length))) return uint(crypto.PlaintextLength(int(b.Length)))
} }
func (b Blob) IsCompressed() bool { func (b Blob) IsCompressed() bool {

View file

@ -61,7 +61,7 @@ func newTestRepo(content []TestFile) *TestRepo {
key := crypto.NewRandomKey() key := crypto.NewRandomKey()
seal := func(data []byte) []byte { seal := func(data []byte) []byte {
ciphertext := restic.NewBlobBuffer(len(data)) ciphertext := crypto.NewBlobBuffer(len(data))
ciphertext = ciphertext[:0] // truncate the slice ciphertext = ciphertext[:0] // truncate the slice
nonce := crypto.NewRandomNonce() nonce := crypto.NewRandomNonce()
ciphertext = append(ciphertext, nonce...) ciphertext = append(ciphertext, nonce...)