rclone/vendor/storj.io/common/storj/encryption.go

164 lines
4.9 KiB
Go
Raw Normal View History

2020-05-11 20:57:46 +02:00
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package storj
import (
"encoding/base32"
"github.com/zeebo/errs"
)
// EncryptionParameters is the cipher suite and parameters used for encryption.
2020-05-11 20:57:46 +02:00
type EncryptionParameters struct {
// CipherSuite specifies the cipher suite to be used for encryption.
CipherSuite CipherSuite
// BlockSize determines the unit size at which encryption is performed.
// It is important to distinguish this from the block size used by the
// cipher suite (probably 128 bits). There is some small overhead for
// each encryption unit, so BlockSize should not be too small, but
// smaller sizes yield shorter first-byte latency and better seek times.
// Note that BlockSize itself is the size of data blocks _after_ they
// have been encrypted and the authentication overhead has been added.
// It is _not_ the size of the data blocks to _be_ encrypted.
BlockSize int32
}
// IsZero returns true if no field in the struct is set to non-zero value.
2020-05-11 20:57:46 +02:00
func (params EncryptionParameters) IsZero() bool {
return params == (EncryptionParameters{})
}
// CipherSuite specifies one of the encryption suites supported by Storj
// libraries for encryption of in-network data.
type CipherSuite byte
const (
// EncUnspecified indicates no encryption suite has been selected.
EncUnspecified = CipherSuite(iota)
// EncNull indicates use of the NULL cipher; that is, no encryption is
// done. The ciphertext is equal to the plaintext.
EncNull
// EncAESGCM indicates use of AES128-GCM encryption.
EncAESGCM
// EncSecretBox indicates use of XSalsa20-Poly1305 encryption, as provided
// by the NaCl cryptography library under the name "Secretbox".
EncSecretBox
// EncNullBase64URL is like EncNull but Base64 encodes/decodes the
// binary path data (URL-safe).
2020-05-11 20:57:46 +02:00
EncNullBase64URL
)
// Constant definitions for key and nonce sizes.
2020-05-11 20:57:46 +02:00
const (
KeySize = 32
NonceSize = 24
)
// NewKey creates a new Storj key from humanReadableKey.
func NewKey(humanReadableKey []byte) (*Key, error) {
var key Key
// Because of backward compatibility the key is filled with 0 or truncated if
// humanReadableKey isn't of the same size that KeySize.
// See https://github.com/storj/storj/pull/1967#discussion_r285544849
copy(key[:], humanReadableKey)
return &key, nil
}
// Key represents the largest key used by any encryption protocol.
2020-05-11 20:57:46 +02:00
type Key [KeySize]byte
// Raw returns the key as a raw byte array pointer.
2020-05-11 20:57:46 +02:00
func (key *Key) Raw() *[KeySize]byte {
return (*[KeySize]byte)(key)
}
// IsZero returns true if key is nil or it points to its zero value.
2020-05-11 20:57:46 +02:00
func (key *Key) IsZero() bool {
return key == nil || *key == (Key{})
}
// ErrNonce is used when something goes wrong with a stream ID.
2020-05-11 20:57:46 +02:00
var ErrNonce = errs.Class("nonce error")
// nonceEncoding is base32 without padding.
2020-05-11 20:57:46 +02:00
var nonceEncoding = base32.StdEncoding.WithPadding(base32.NoPadding)
// Nonce represents the largest nonce used by any encryption protocol.
2020-05-11 20:57:46 +02:00
type Nonce [NonceSize]byte
// NonceFromString decodes an base32 encoded.
2020-05-11 20:57:46 +02:00
func NonceFromString(s string) (Nonce, error) {
nonceBytes, err := nonceEncoding.DecodeString(s)
if err != nil {
return Nonce{}, ErrNonce.Wrap(err)
}
return NonceFromBytes(nonceBytes)
}
// NonceFromBytes converts a byte slice into a nonce.
2020-05-11 20:57:46 +02:00
func NonceFromBytes(b []byte) (Nonce, error) {
if len(b) != len(Nonce{}) {
return Nonce{}, ErrNonce.New("not enough bytes to make a nonce; have %d, need %d", len(b), len(NodeID{}))
}
var nonce Nonce
copy(nonce[:], b)
return nonce, nil
}
// IsZero returns whether nonce is unassigned.
2020-05-11 20:57:46 +02:00
func (nonce Nonce) IsZero() bool {
return nonce == Nonce{}
}
// String representation of the nonce.
2020-05-11 20:57:46 +02:00
func (nonce Nonce) String() string { return nonceEncoding.EncodeToString(nonce.Bytes()) }
// Bytes returns bytes of the nonce.
2020-05-11 20:57:46 +02:00
func (nonce Nonce) Bytes() []byte { return nonce[:] }
// Raw returns the nonce as a raw byte array pointer.
2020-05-11 20:57:46 +02:00
func (nonce *Nonce) Raw() *[NonceSize]byte {
return (*[NonceSize]byte)(nonce)
}
// Marshal serializes a nonce.
2020-05-11 20:57:46 +02:00
func (nonce Nonce) Marshal() ([]byte, error) {
return nonce.Bytes(), nil
}
// MarshalTo serializes a nonce into the passed byte slice.
2020-05-11 20:57:46 +02:00
func (nonce *Nonce) MarshalTo(data []byte) (n int, err error) {
n = copy(data, nonce.Bytes())
return n, nil
}
// Unmarshal deserializes a nonce.
2020-05-11 20:57:46 +02:00
func (nonce *Nonce) Unmarshal(data []byte) error {
var err error
*nonce, err = NonceFromBytes(data)
return err
}
// Size returns the length of a nonce (implements gogo's custom type interface).
2020-05-11 20:57:46 +02:00
func (nonce Nonce) Size() int {
return len(nonce)
}
// MarshalJSON serializes a nonce to a json string as bytes.
2020-05-11 20:57:46 +02:00
func (nonce Nonce) MarshalJSON() ([]byte, error) {
return []byte(`"` + nonce.String() + `"`), nil
}
// UnmarshalJSON deserializes a json string (as bytes) to a nonce.
2020-05-11 20:57:46 +02:00
func (nonce *Nonce) UnmarshalJSON(data []byte) error {
var err error
*nonce, err = NonceFromString(string(data))
return err
}
// EncryptedPrivateKey is a private key that has been encrypted.
2020-05-11 20:57:46 +02:00
type EncryptedPrivateKey []byte