Adapt storj and encryption packages (#513)

This commit is contained in:
Kaloyan Raev 2018-10-19 16:38:13 +03:00 committed by GitHub
parent fc2fe0c294
commit ac4805a841
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 187 additions and 201 deletions

View File

@ -17,6 +17,7 @@ import (
"storj.io/storj/pkg/eestream"
"storj.io/storj/pkg/encryption"
"storj.io/storj/pkg/ranger"
"storj.io/storj/pkg/storj"
)
var (
@ -37,15 +38,14 @@ func main() {
// Main is the exported CLI executable function
func Main() error {
encKey := encryption.Key(sha256.Sum256([]byte(*key)))
encKey := storj.Key(sha256.Sum256([]byte(*key)))
fc, err := infectious.NewFEC(*rsk, *rsn)
if err != nil {
return err
}
es := eestream.NewRSScheme(fc, *erasureShareSize)
var firstNonce encryption.Nonce
cipher := encryption.AESGCM
decrypter, err := cipher.NewDecrypter(&encKey, &firstNonce, es.StripeSize())
var firstNonce storj.Nonce
decrypter, err := encryption.NewDecrypter(storj.AESGCM, &encKey, &firstNonce, es.StripeSize())
if err != nil {
return err
}

View File

@ -21,6 +21,7 @@ import (
"storj.io/storj/pkg/eestream"
"storj.io/storj/pkg/encryption"
"storj.io/storj/pkg/ranger"
"storj.io/storj/pkg/storj"
)
var (
@ -46,15 +47,14 @@ func main() {
// Main is the exported CLI executable function
func Main() error {
encKey := encryption.Key(sha256.Sum256([]byte(*key)))
encKey := storj.Key(sha256.Sum256([]byte(*key)))
fc, err := infectious.NewFEC(*rsk, *rsn)
if err != nil {
return err
}
es := eestream.NewRSScheme(fc, *erasureShareSize)
var firstNonce encryption.Nonce
cipher := encryption.AESGCM
decrypter, err := cipher.NewDecrypter(&encKey, &firstNonce, es.StripeSize())
var firstNonce storj.Nonce
decrypter, err := encryption.NewDecrypter(storj.AESGCM, &encKey, &firstNonce, es.StripeSize())
if err != nil {
return err
}

View File

@ -16,6 +16,7 @@ import (
"storj.io/storj/pkg/eestream"
"storj.io/storj/pkg/encryption"
"storj.io/storj/pkg/storj"
)
var (
@ -53,10 +54,9 @@ func Main() error {
if err != nil {
return err
}
encKey := encryption.Key(sha256.Sum256([]byte(*key)))
var firstNonce encryption.Nonce
cipher := encryption.AESGCM
encrypter, err := cipher.NewEncrypter(&encKey, &firstNonce, es.StripeSize())
encKey := storj.Key(sha256.Sum256([]byte(*key)))
var firstNonce storj.Nonce
encrypter, err := encryption.NewEncrypter(storj.AESGCM, &encKey, &firstNonce, es.StripeSize())
if err != nil {
return err
}

View File

@ -21,6 +21,7 @@ import (
"storj.io/storj/internal/pkg/readcloser"
"storj.io/storj/pkg/encryption"
"storj.io/storj/pkg/ranger"
"storj.io/storj/pkg/storj"
)
func randData(amount int) []byte {
@ -103,10 +104,9 @@ func TestRSRanger(t *testing.T) {
if err != nil {
t.Fatal(err)
}
encKey := encryption.Key(sha256.Sum256([]byte("the secret key")))
var firstNonce encryption.Nonce
cipher := encryption.AESGCM
encrypter, err := cipher.NewEncrypter(&encKey, &firstNonce, rs.StripeSize())
encKey := storj.Key(sha256.Sum256([]byte("the secret key")))
var firstNonce storj.Nonce
encrypter, err := encryption.NewEncrypter(storj.AESGCM, &encKey, &firstNonce, rs.StripeSize())
if err != nil {
t.Fatal(err)
}
@ -123,7 +123,7 @@ func TestRSRanger(t *testing.T) {
for i, piece := range pieces {
rrs[i] = ranger.ByteRanger(piece)
}
decrypter, err := cipher.NewDecrypter(&encKey, &firstNonce, rs.StripeSize())
decrypter, err := encryption.NewDecrypter(storj.AESGCM, &encKey, &firstNonce, rs.StripeSize())
if err != nil {
t.Fatal(err)
}

View File

@ -8,12 +8,14 @@ import (
"crypto/cipher"
"github.com/zeebo/errs"
"storj.io/storj/pkg/storj"
)
type aesgcmEncrypter struct {
blockSize int
key Key
startingNonce AESGCMNonce
key *storj.Key
startingNonce *AESGCMNonce
overhead int
aesgcm cipher.AEAD
}
@ -31,8 +33,8 @@ type aesgcmEncrypter struct {
//
// When in doubt, generate a new key from crypto/rand and a startingNonce
// from crypto/rand as often as possible.
func NewAESGCMEncrypter(key *Key, startingNonce *AESGCMNonce, encryptedBlockSize int) (Transformer, error) {
block, err := aes.NewCipher((*key)[:])
func NewAESGCMEncrypter(key *storj.Key, startingNonce *AESGCMNonce, encryptedBlockSize int) (Transformer, error) {
block, err := aes.NewCipher(key[:])
if err != nil {
return nil, err
}
@ -45,8 +47,8 @@ func NewAESGCMEncrypter(key *Key, startingNonce *AESGCMNonce, encryptedBlockSize
}
return &aesgcmEncrypter{
blockSize: encryptedBlockSize - aesgcmEncrypt.Overhead(),
key: *key,
startingNonce: *startingNonce,
key: key,
startingNonce: startingNonce,
overhead: aesgcmEncrypt.Overhead(),
aesgcm: aesgcmEncrypt,
}, nil
@ -69,19 +71,19 @@ func calcGCMNonce(startingNonce *AESGCMNonce, blockNum int64) (rv [12]byte, err
}
func (s *aesgcmEncrypter) Transform(out, in []byte, blockNum int64) ([]byte, error) {
n, err := calcGCMNonce(&s.startingNonce, blockNum)
nonce, err := calcGCMNonce(s.startingNonce, blockNum)
if err != nil {
return nil, err
}
ciphertext := s.aesgcm.Seal(out, n[:], in, nil)
ciphertext := s.aesgcm.Seal(out, nonce[:], in, nil)
return ciphertext, nil
}
type aesgcmDecrypter struct {
blockSize int
key Key
startingNonce AESGCMNonce
key *storj.Key
startingNonce *AESGCMNonce
overhead int
aesgcm cipher.AEAD
}
@ -89,7 +91,7 @@ type aesgcmDecrypter struct {
// NewAESGCMDecrypter returns a Transformer that decrypts the data passing
// through with key. See the comments for NewAESGCMEncrypter about
// startingNonce.
func NewAESGCMDecrypter(key *Key, startingNonce *AESGCMNonce, encryptedBlockSize int) (Transformer, error) {
func NewAESGCMDecrypter(key *storj.Key, startingNonce *AESGCMNonce, encryptedBlockSize int) (Transformer, error) {
block, err := aes.NewCipher(key[:])
if err != nil {
return nil, err
@ -103,8 +105,8 @@ func NewAESGCMDecrypter(key *Key, startingNonce *AESGCMNonce, encryptedBlockSize
}
return &aesgcmDecrypter{
blockSize: encryptedBlockSize - aesgcmDecrypt.Overhead(),
key: *key,
startingNonce: *startingNonce,
key: key,
startingNonce: startingNonce,
overhead: aesgcmDecrypt.Overhead(),
aesgcm: aesgcmDecrypt,
}, nil
@ -118,16 +120,16 @@ func (s *aesgcmDecrypter) OutBlockSize() int {
}
func (s *aesgcmDecrypter) Transform(out, in []byte, blockNum int64) ([]byte, error) {
n, err := calcGCMNonce(&s.startingNonce, blockNum)
nonce, err := calcGCMNonce(s.startingNonce, blockNum)
if err != nil {
return nil, err
}
return s.aesgcm.Open(out, n[:], in, nil)
return s.aesgcm.Open(out, nonce[:], in, nil)
}
// EncryptAESGCM encrypts byte data with a key and nonce. The cipher data is returned
func EncryptAESGCM(data []byte, key *Key, nonce *AESGCMNonce) (cipherData []byte, err error) {
func EncryptAESGCM(data []byte, key *storj.Key, nonce *AESGCMNonce) (cipherData []byte, err error) {
block, err := aes.NewCipher(key[:])
if err != nil {
return []byte{}, errs.Wrap(err)
@ -141,7 +143,7 @@ func EncryptAESGCM(data []byte, key *Key, nonce *AESGCMNonce) (cipherData []byte
}
// DecryptAESGCM decrypts byte data with a key and nonce. The plain data is returned
func DecryptAESGCM(cipherData []byte, key *Key, nonce *AESGCMNonce) (data []byte, err error) {
func DecryptAESGCM(cipherData []byte, key *storj.Key, nonce *AESGCMNonce) (data []byte, err error) {
if len(cipherData) == 0 {
return []byte{}, errs.New("empty cipher data")
}

View File

@ -7,11 +7,13 @@ import (
"bytes"
"io/ioutil"
"testing"
"storj.io/storj/pkg/storj"
)
func TestAesGcm(t *testing.T) {
var key Key
copy(key[:], randData(KeySize))
var key storj.Key
copy(key[:], randData(storj.KeySize))
var firstNonce AESGCMNonce
copy(firstNonce[:], randData(AESGCMNonceSize))
encrypter, err := NewAESGCMEncrypter(&key, &firstNonce, 4*1024)

View File

@ -5,138 +5,98 @@ package encryption
import (
"github.com/zeebo/errs"
"storj.io/storj/pkg/storj"
)
// Cipher is a type used to define the type of encryption to use
type Cipher byte
// AESGCMNonceSize is the size of an AES-GCM nonce
const AESGCMNonceSize = 12
// Constant definitions for no encryption (0), AESGCM (1), and SecretBox (2)
const (
None = Cipher(iota)
AESGCM
SecretBox
)
// AESGCMNonce represents the nonce used by the AES-GCM protocol
type AESGCMNonce [AESGCMNonceSize]byte
// Constant definitions for key and nonce sizes
const (
KeySize = 32
NonceSize = 24
AESGCMNonceSize = 12
)
// Key represents the largest key used by any encryption protocol
type Key [KeySize]byte
// Bytes returns the key as a byte array pointer
func (k *Key) Bytes() *[KeySize]byte {
return (*[KeySize]byte)(k)
}
// Encrypt encrypts the current key with the given key and nonce
func (k *Key) Encrypt(cipher Cipher, key *Key, nonce *Nonce) (EncryptedPrivateKey, error) {
return cipher.Encrypt(k[:], key, nonce)
}
// Nonce represents the largest nonce used by any encryption protocol
type Nonce [NonceSize]byte
// Bytes returns the nonce as a byte array pointer
func (nonce *Nonce) Bytes() *[NonceSize]byte {
return (*[NonceSize]byte)(nonce)
}
// Increment increments the nonce with the given amount
func (nonce *Nonce) Increment(amount int64) (truncated bool, err error) {
return incrementBytes(nonce[:], amount)
}
// AESGCMNonce returns the nonce as a AES-GCM nonce
func (nonce *Nonce) AESGCMNonce() *AESGCMNonce {
// ToAESGCMNonce returns the nonce as a AES-GCM nonce
func ToAESGCMNonce(nonce *storj.Nonce) *AESGCMNonce {
aes := new(AESGCMNonce)
copy((*aes)[:], nonce[:AESGCMNonceSize])
return aes
}
// AESGCMNonce represents the nonce used by the AES-GCM protocol
type AESGCMNonce [AESGCMNonceSize]byte
// Bytes returns the nonce as a byte array pointer
func (nonce *AESGCMNonce) Bytes() *[AESGCMNonceSize]byte {
return (*[AESGCMNonceSize]byte)(nonce)
// Increment increments the nonce with the given amount
func Increment(nonce *storj.Nonce, amount int64) (truncated bool, err error) {
return incrementBytes(nonce[:], amount)
}
// EncryptedPrivateKey is a private key that has been encrypted
type EncryptedPrivateKey []byte
// Decrypt decrypts the current key with the given key and nonce
func (k EncryptedPrivateKey) Decrypt(cipher Cipher, key *Key, nonce *Nonce) (*Key, error) {
plainData, err := cipher.Decrypt(k, key, nonce)
if err != nil {
return nil, err
}
var decryptedKey Key
copy(decryptedKey[:], plainData)
return &decryptedKey, nil
}
// Encrypt encrypts byte data with a key and nonce. The cipher data is returned
// The type of encryption to use can be modified with encType
func (cipher Cipher) Encrypt(data []byte, key *Key, nonce *Nonce) (cipherData []byte, err error) {
// Encrypt encrypts data with the given cipher, key and nonce
func Encrypt(data []byte, cipher storj.Cipher, key *storj.Key, nonce *storj.Nonce) (cipherData []byte, err error) {
switch cipher {
case None:
case storj.Unencrypted:
return data, nil
case AESGCM:
return EncryptAESGCM(data, key, nonce.AESGCMNonce())
case SecretBox:
case storj.AESGCM:
return EncryptAESGCM(data, key, ToAESGCMNonce(nonce))
case storj.SecretBox:
return EncryptSecretBox(data, key, nonce)
default:
return nil, errs.New("Invalid encryption type")
}
}
// Decrypt decrypts byte data with a key and nonce. The plain data is returned
// The type of encryption to use can be modified with encType
func (cipher Cipher) Decrypt(cipherData []byte, key *Key, nonce *Nonce) (data []byte, err error) {
// Decrypt decrypts cipherData with the given cipher, key and nonce
func Decrypt(cipherData []byte, cipher storj.Cipher, key *storj.Key, nonce *storj.Nonce) (data []byte, err error) {
switch cipher {
case None:
case storj.Unencrypted:
return cipherData, nil
case AESGCM:
return DecryptAESGCM(cipherData, key, nonce.AESGCMNonce())
case SecretBox:
case storj.AESGCM:
return DecryptAESGCM(cipherData, key, ToAESGCMNonce(nonce))
case storj.SecretBox:
return DecryptSecretBox(cipherData, key, nonce)
default:
return nil, errs.New("Invalid encryption type")
}
}
// NewEncrypter creates transform stream using a key and a nonce to encrypt data passing through it
// The type of encryption to use can be modified with encType
func (cipher Cipher) NewEncrypter(key *Key, startingNonce *Nonce, encBlockSize int) (Transformer, error) {
// NewEncrypter creates a Transformer using the given cipher, key and nonce to encrypt data passing through it
func NewEncrypter(cipher storj.Cipher, key *storj.Key, startingNonce *storj.Nonce, encryptedBlockSize int) (Transformer, error) {
switch cipher {
case None:
case storj.Unencrypted:
return &NoopTransformer{}, nil
case AESGCM:
return NewAESGCMEncrypter(key, startingNonce.AESGCMNonce(), encBlockSize)
case SecretBox:
return NewSecretboxEncrypter(key, startingNonce, encBlockSize)
case storj.AESGCM:
return NewAESGCMEncrypter(key, ToAESGCMNonce(startingNonce), encryptedBlockSize)
case storj.SecretBox:
return NewSecretboxEncrypter(key, startingNonce, encryptedBlockSize)
default:
return nil, errs.New("Invalid encryption type")
}
}
// NewDecrypter creates transform stream using a key and a nonce to decrypt data passing through it
// The type of encryption to use can be modified with encType
func (cipher Cipher) NewDecrypter(key *Key, startingNonce *Nonce, encBlockSize int) (Transformer, error) {
// NewDecrypter creates a Transformer using the given cipher, key and nonce to decrypt data passing through it
func NewDecrypter(cipher storj.Cipher, key *storj.Key, startingNonce *storj.Nonce, encryptedBlockSize int) (Transformer, error) {
switch cipher {
case None:
case storj.Unencrypted:
return &NoopTransformer{}, nil
case AESGCM:
return NewAESGCMDecrypter(key, startingNonce.AESGCMNonce(), encBlockSize)
case SecretBox:
return NewSecretboxDecrypter(key, startingNonce, encBlockSize)
case storj.AESGCM:
return NewAESGCMDecrypter(key, ToAESGCMNonce(startingNonce), encryptedBlockSize)
case storj.SecretBox:
return NewSecretboxDecrypter(key, startingNonce, encryptedBlockSize)
default:
return nil, errs.New("Invalid encryption type")
}
}
// EncryptKey encrypts keyToEncrypt with the given cipher, key and nonce
func EncryptKey(keyToEncrypt *storj.Key, cipher storj.Cipher, key *storj.Key, nonce *storj.Nonce) (storj.EncryptedPrivateKey, error) {
return Encrypt(keyToEncrypt[:], cipher, key, nonce)
}
// DecryptKey decrypts keyToDecrypt with the given cipher, key and nonce
func DecryptKey(keyToDecrypt storj.EncryptedPrivateKey, cipher storj.Cipher, key *storj.Key, nonce *storj.Nonce) (*storj.Key, error) {
plainData, err := Decrypt(keyToDecrypt, cipher, key, nonce)
if err != nil {
return nil, err
}
var decryptedKey storj.Key
copy(decryptedKey[:], plainData)
return &decryptedKey, nil
}

View File

@ -6,12 +6,14 @@ package encryption
import (
"github.com/zeebo/errs"
"golang.org/x/crypto/nacl/secretbox"
"storj.io/storj/pkg/storj"
)
type secretboxEncrypter struct {
blockSize int
key Key
startingNonce Nonce
key *storj.Key
startingNonce *storj.Nonce
}
// NewSecretboxEncrypter returns a Transformer that encrypts the data passing
@ -27,14 +29,14 @@ type secretboxEncrypter struct {
//
// When in doubt, generate a new key from crypto/rand and a startingNonce
// from crypto/rand as often as possible.
func NewSecretboxEncrypter(key *Key, startingNonce *Nonce, encryptedBlockSize int) (Transformer, error) {
func NewSecretboxEncrypter(key *storj.Key, startingNonce *storj.Nonce, encryptedBlockSize int) (Transformer, error) {
if encryptedBlockSize <= secretbox.Overhead {
return nil, Error.New("block size too small")
}
return &secretboxEncrypter{
blockSize: encryptedBlockSize - secretbox.Overhead,
key: *key,
startingNonce: *startingNonce,
key: key,
startingNonce: startingNonce,
}, nil
}
@ -46,8 +48,8 @@ func (s *secretboxEncrypter) OutBlockSize() int {
return s.blockSize + secretbox.Overhead
}
func calcNonce(startingNonce *Nonce, blockNum int64) (rv *Nonce, err error) {
rv = new(Nonce)
func calcNonce(startingNonce *storj.Nonce, blockNum int64) (rv *storj.Nonce, err error) {
rv = new(storj.Nonce)
if copy(rv[:], (*startingNonce)[:]) != len(rv) {
return rv, Error.New("didn't copy memory?!")
}
@ -56,30 +58,30 @@ func calcNonce(startingNonce *Nonce, blockNum int64) (rv *Nonce, err error) {
}
func (s *secretboxEncrypter) Transform(out, in []byte, blockNum int64) ([]byte, error) {
n, err := calcNonce(&s.startingNonce, blockNum)
nonce, err := calcNonce(s.startingNonce, blockNum)
if err != nil {
return nil, err
}
return secretbox.Seal(out, in, n.Bytes(), s.key.Bytes()), nil
return secretbox.Seal(out, in, nonce.Raw(), s.key.Raw()), nil
}
type secretboxDecrypter struct {
blockSize int
key Key
startingNonce Nonce
key *storj.Key
startingNonce *storj.Nonce
}
// NewSecretboxDecrypter returns a Transformer that decrypts the data passing
// through with key. See the comments for NewSecretboxEncrypter about
// startingNonce.
func NewSecretboxDecrypter(key *Key, startingNonce *Nonce, encryptedBlockSize int) (Transformer, error) {
func NewSecretboxDecrypter(key *storj.Key, startingNonce *storj.Nonce, encryptedBlockSize int) (Transformer, error) {
if encryptedBlockSize <= secretbox.Overhead {
return nil, Error.New("block size too small")
}
return &secretboxDecrypter{
blockSize: encryptedBlockSize - secretbox.Overhead,
key: *key,
startingNonce: *startingNonce,
key: key,
startingNonce: startingNonce,
}, nil
}
@ -92,11 +94,11 @@ func (s *secretboxDecrypter) OutBlockSize() int {
}
func (s *secretboxDecrypter) Transform(out, in []byte, blockNum int64) ([]byte, error) {
n, err := calcNonce(&s.startingNonce, blockNum)
nonce, err := calcNonce(s.startingNonce, blockNum)
if err != nil {
return nil, err
}
rv, success := secretbox.Open(out, in, n.Bytes(), s.key.Bytes())
rv, success := secretbox.Open(out, in, nonce.Raw(), s.key.Raw())
if !success {
return nil, Error.New("failed decrypting")
}
@ -104,13 +106,13 @@ func (s *secretboxDecrypter) Transform(out, in []byte, blockNum int64) ([]byte,
}
// EncryptSecretBox encrypts byte data with a key and nonce. The cipher data is returned
func EncryptSecretBox(data []byte, key *Key, nonce *Nonce) (cipherData []byte, err error) {
return secretbox.Seal(nil, data, nonce.Bytes(), key.Bytes()), nil
func EncryptSecretBox(data []byte, key *storj.Key, nonce *storj.Nonce) (cipherData []byte, err error) {
return secretbox.Seal(nil, data, nonce.Raw(), key.Raw()), nil
}
// DecryptSecretBox decrypts byte data with a key and nonce. The plain data is returned
func DecryptSecretBox(cipherData []byte, key *Key, nonce *Nonce) (data []byte, err error) {
data, success := secretbox.Open(nil, cipherData, nonce.Bytes(), key.Bytes())
func DecryptSecretBox(cipherData []byte, key *storj.Key, nonce *storj.Nonce) (data []byte, err error) {
data, success := secretbox.Open(nil, cipherData, nonce.Raw(), key.Raw())
if !success {
return nil, errs.New("Failed decrypting")
}

View File

@ -8,6 +8,8 @@ import (
"crypto/rand"
"io/ioutil"
"testing"
"storj.io/storj/pkg/storj"
)
func randData(amount int) []byte {
@ -20,10 +22,10 @@ func randData(amount int) []byte {
}
func TestSecretbox(t *testing.T) {
var key Key
copy(key[:], randData(KeySize))
var firstNonce Nonce
copy(firstNonce[:], randData(NonceSize))
var key storj.Key
copy(key[:], randData(storj.KeySize))
var firstNonce storj.Nonce
copy(firstNonce[:], randData(storj.NonceSize))
encrypter, err := NewSecretboxEncrypter(&key, &firstNonce, 4*1024)
if err != nil {
t.Fatal(err)

View File

@ -21,6 +21,7 @@ import (
"storj.io/storj/pkg/storage/objects"
segment "storj.io/storj/pkg/storage/segments"
streams "storj.io/storj/pkg/storage/streams"
"storj.io/storj/pkg/storj"
"storj.io/storj/pkg/transport"
)
@ -154,7 +155,7 @@ func (c Config) GetBucketStore(ctx context.Context, identity *provider.FullIdent
err = Error.New("EncryptionBlockSize must be a multiple of ErasureShareSize * RS MinThreshold")
return nil, err
}
stream, err := streams.NewStreamStore(segments, c.SegmentSize, c.EncKey, c.EncBlockSize, c.EncType)
stream, err := streams.NewStreamStore(segments, c.SegmentSize, c.EncKey, c.EncBlockSize, storj.Cipher(c.EncType))
if err != nil {
return nil, err
}

View File

@ -24,6 +24,7 @@ import (
ranger "storj.io/storj/pkg/ranger"
"storj.io/storj/pkg/storage/meta"
"storj.io/storj/pkg/storage/segments"
"storj.io/storj/pkg/storj"
"storj.io/storj/storage"
)
@ -68,11 +69,11 @@ type streamStore struct {
segmentSize int64
rootKey []byte
encBlockSize int
encType encryption.Cipher
cipher storj.Cipher
}
// NewStreamStore stuff
func NewStreamStore(segments segments.Store, segmentSize int64, rootKey string, encBlockSize int, encType int) (Store, error) {
func NewStreamStore(segments segments.Store, segmentSize int64, rootKey string, encBlockSize int, cipher storj.Cipher) (Store, error) {
if segmentSize <= 0 {
return nil, errs.New("segment size must be larger than 0")
}
@ -88,7 +89,7 @@ func NewStreamStore(segments segments.Store, segmentSize int64, rootKey string,
segmentSize: segmentSize,
rootKey: []byte(rootKey),
encBlockSize: encBlockSize,
encType: encryption.Cipher(encType),
cipher: cipher,
}, nil
}
@ -122,13 +123,12 @@ func (s *streamStore) Put(ctx context.Context, path paths.Path, data io.Reader,
if err != nil {
return Meta{}, err
}
cipher := s.encType
eofReader := NewEOFReader(data)
for !eofReader.isEOF() && !eofReader.hasError() {
// generate random key for encrypting the segment's content
var contentKey encryption.Key
var contentKey storj.Key
_, err = rand.Read(contentKey[:])
if err != nil {
return Meta{}, err
@ -137,25 +137,25 @@ func (s *streamStore) Put(ctx context.Context, path paths.Path, data io.Reader,
// Initialize the content nonce with the segment's index incremented by 1.
// The increment by 1 is to avoid nonce reuse with the metadata encryption,
// which is encrypted with the zero nonce.
var contentNonce encryption.Nonce
_, err := contentNonce.Increment(currentSegment + 1)
var contentNonce storj.Nonce
_, err := encryption.Increment(&contentNonce, currentSegment+1)
if err != nil {
return Meta{}, err
}
encrypter, err := cipher.NewEncrypter(&contentKey, &contentNonce, s.encBlockSize)
encrypter, err := encryption.NewEncrypter(s.cipher, &contentKey, &contentNonce, s.encBlockSize)
if err != nil {
return Meta{}, err
}
// generate random nonce for encrypting the content key
var keyNonce encryption.Nonce
var keyNonce storj.Nonce
_, err = rand.Read(keyNonce[:])
if err != nil {
return Meta{}, err
}
encryptedKey, err := contentKey.Encrypt(cipher, (*encryption.Key)(derivedKey), &keyNonce)
encryptedKey, err := encryption.EncryptKey(&contentKey, s.cipher, (*storj.Key)(derivedKey), &keyNonce)
if err != nil {
return Meta{}, err
}
@ -176,7 +176,7 @@ func (s *streamStore) Put(ctx context.Context, path paths.Path, data io.Reader,
if err != nil {
return Meta{}, err
}
cipherData, err := cipher.Encrypt(data, &contentKey, &contentNonce)
cipherData, err := encryption.Encrypt(data, s.cipher, &contentKey, &contentNonce)
if err != nil {
return Meta{}, err
}
@ -192,7 +192,7 @@ func (s *streamStore) Put(ctx context.Context, path paths.Path, data io.Reader,
if !eofReader.isEOF() {
segmentPath := getSegmentPath(encPath, currentSegment)
if cipher == encryption.None {
if s.cipher == storj.Unencrypted {
return segmentPath, nil, nil
}
@ -220,18 +220,18 @@ func (s *streamStore) Put(ctx context.Context, path paths.Path, data io.Reader,
}
// encrypt metadata with the content encryption key and zero nonce
encryptedStreamInfo, err := cipher.Encrypt(streamInfo, &contentKey, &encryption.Nonce{})
encryptedStreamInfo, err := encryption.Encrypt(streamInfo, s.cipher, &contentKey, &storj.Nonce{})
if err != nil {
return nil, nil, err
}
streamMeta := pb.StreamMeta{
EncryptedStreamInfo: encryptedStreamInfo,
EncryptionType: int32(s.encType),
EncryptionType: int32(s.cipher),
EncryptionBlockSize: int32(s.encBlockSize),
}
if cipher != encryption.None {
if s.cipher != storj.Unencrypted {
streamMeta.LastSegmentMeta = &pb.SegmentMeta{
EncryptedKey: encryptedKey,
KeyNonce: keyNonce[:],
@ -314,8 +314,8 @@ func (s *streamStore) Get(ctx context.Context, path paths.Path) (rr ranger.Range
for i := int64(0); i < stream.NumberOfSegments-1; i++ {
currentPath := getSegmentPath(encPath, i)
size := stream.SegmentsSize
var contentNonce encryption.Nonce
_, err := contentNonce.Increment(i + 1)
var contentNonce storj.Nonce
_, err := encryption.Increment(&contentNonce, i+1)
if err != nil {
return nil, Meta{}, err
}
@ -323,16 +323,16 @@ func (s *streamStore) Get(ctx context.Context, path paths.Path) (rr ranger.Range
segments: s.segments,
path: currentPath,
size: size,
derivedKey: (*encryption.Key)(derivedKey),
derivedKey: (*storj.Key)(derivedKey),
startingNonce: &contentNonce,
encBlockSize: int(streamMeta.EncryptionBlockSize),
encType: encryption.Cipher(streamMeta.EncryptionType),
cipher: storj.Cipher(streamMeta.EncryptionType),
}
rangers = append(rangers, rr)
}
var contentNonce encryption.Nonce
_, err = contentNonce.Increment(stream.NumberOfSegments)
var contentNonce storj.Nonce
_, err = encryption.Increment(&contentNonce, stream.NumberOfSegments)
if err != nil {
return nil, Meta{}, err
}
@ -341,8 +341,8 @@ func (s *streamStore) Get(ctx context.Context, path paths.Path) (rr ranger.Range
ctx,
lastSegmentRanger,
stream.LastSegmentSize,
encryption.Cipher(streamMeta.EncryptionType),
(*encryption.Key)(derivedKey),
storj.Cipher(streamMeta.EncryptionType),
(*storj.Key)(derivedKey),
encryptedKey,
keyNonce,
&contentNonce,
@ -518,10 +518,10 @@ type lazySegmentRanger struct {
segments segments.Store
path paths.Path
size int64
derivedKey *encryption.Key
startingNonce *encryption.Nonce
derivedKey *storj.Key
startingNonce *storj.Nonce
encBlockSize int
encType encryption.Cipher
cipher storj.Cipher
}
// Size implements Ranger.Size
@ -542,7 +542,7 @@ func (lr *lazySegmentRanger) Range(ctx context.Context, offset, length int64) (i
return nil, err
}
encryptedKey, keyNonce := getEncryptedKeyAndNonce(&segmentMeta)
lr.ranger, err = decryptRanger(ctx, rr, lr.size, lr.encType, lr.derivedKey, encryptedKey, keyNonce, lr.startingNonce, lr.encBlockSize)
lr.ranger, err = decryptRanger(ctx, rr, lr.size, lr.cipher, lr.derivedKey, encryptedKey, keyNonce, lr.startingNonce, lr.encBlockSize)
if err != nil {
return nil, err
}
@ -551,14 +551,13 @@ func (lr *lazySegmentRanger) Range(ctx context.Context, offset, length int64) (i
}
// decryptRanger returns a decrypted ranger of the given rr ranger
func decryptRanger(ctx context.Context, rr ranger.Ranger, decryptedSize int64, cipher encryption.Cipher, derivedKey *encryption.Key, encryptedKey []byte, encryptedKeyNonce, startingNonce *encryption.Nonce, encBlockSize int) (ranger.Ranger, error) {
e, err := cipher.Decrypt(encryptedKey, derivedKey, encryptedKeyNonce)
func decryptRanger(ctx context.Context, rr ranger.Ranger, decryptedSize int64, cipher storj.Cipher, derivedKey *storj.Key, encryptedKey storj.EncryptedPrivateKey, encryptedKeyNonce, startingNonce *storj.Nonce, encBlockSize int) (ranger.Ranger, error) {
contentKey, err := encryption.DecryptKey(encryptedKey, cipher, derivedKey, encryptedKeyNonce)
if err != nil {
return nil, err
}
var encKey encryption.Key
copy(encKey[:], e)
decrypter, err := cipher.NewDecrypter(&encKey, startingNonce, encBlockSize)
decrypter, err := encryption.NewDecrypter(cipher, contentKey, startingNonce, encBlockSize)
if err != nil {
return nil, err
}
@ -573,7 +572,7 @@ func decryptRanger(ctx context.Context, rr ranger.Ranger, decryptedSize int64, c
if err != nil {
return nil, err
}
data, err := cipher.Decrypt(cipherData, &encKey, startingNonce)
data, err := encryption.Decrypt(cipherData, cipher, contentKey, startingNonce)
if err != nil {
return nil, err
}
@ -637,12 +636,12 @@ func (s *streamStore) cancelHandler(ctx context.Context, totalSegments int64, pa
}
}
func getEncryptedKeyAndNonce(m *pb.SegmentMeta) (encryption.EncryptedPrivateKey, *encryption.Nonce) {
func getEncryptedKeyAndNonce(m *pb.SegmentMeta) (storj.EncryptedPrivateKey, *storj.Nonce) {
if m == nil {
return nil, nil
}
var nonce encryption.Nonce
var nonce storj.Nonce
copy(nonce[:], m.KeyNonce)
return m.EncryptedKey, &nonce
@ -660,13 +659,13 @@ func decryptStreamInfo(ctx context.Context, item segments.Meta, path paths.Path,
return nil, err
}
cipher := encryption.Cipher(streamMeta.EncryptionType)
cipher := storj.Cipher(streamMeta.EncryptionType)
encryptedKey, keyNonce := getEncryptedKeyAndNonce(streamMeta.LastSegmentMeta)
contentKey, err := encryptedKey.Decrypt(cipher, (*encryption.Key)(derivedKey), keyNonce)
contentKey, err := encryption.DecryptKey(encryptedKey, cipher, (*storj.Key)(derivedKey), keyNonce)
if err != nil {
return nil, err
}
// decrypt metadata with the content encryption key and zero nonce
return cipher.Decrypt(streamMeta.EncryptedStreamInfo, contentKey, &encryption.Nonce{})
return encryption.Decrypt(streamMeta.EncryptedStreamInfo, cipher, contentKey, &storj.Nonce{})
}

View File

@ -5,22 +5,40 @@ package storj
// EncryptionScheme is the scheme and parameters used for encryption
type EncryptionScheme struct {
Algorithm EncryptionAlgorithm
Cipher Cipher
}
// EncryptionAlgorithm specifies an encryption algorithm
type EncryptionAlgorithm byte
// Cipher specifies an encryption algorithm
type Cipher byte
// List of supported encryption algorithms
const (
InvalidEncryptionAlgorithm = EncryptionAlgorithm(iota)
Unencrypted
Unencrypted = Cipher(iota)
AESGCM
Secretbox
SecretBox
)
// Constant definitions for key and nonce sizes
const (
KeySize = 32
NonceSize = 24
)
// Key represents the largest key used by any encryption protocol
type Key [KeySize]byte
// Raw returns the key as a raw byte array pointer
func (key *Key) Raw() *[KeySize]byte {
return (*[KeySize]byte)(key)
}
// Nonce represents the largest nonce used by any encryption protocol
type Nonce [24]byte // TODO: unify with eestream.Nonce
type Nonce [NonceSize]byte
// Raw returns the nonce as a raw byte array pointer
func (nonce *Nonce) Raw() *[NonceSize]byte {
return (*[NonceSize]byte)(nonce)
}
// EncryptedPrivateKey is a private key that has been encrypted
type EncryptedPrivateKey []byte