12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- package encryption
- import (
- cryptorand "crypto/rand"
- "fmt"
- "io"
- "github.com/docker/swarmkit/api"
- "golang.org/x/crypto/nacl/secretbox"
- )
- const naclSecretboxKeySize = 32
- const naclSecretboxNonceSize = 24
- // This provides the default implementation of an encrypter and decrypter, as well
- // as the default KDF function.
- // NACLSecretbox is an implementation of an encrypter/decrypter. Encrypting
- // generates random Nonces.
- type NACLSecretbox struct {
- key [naclSecretboxKeySize]byte
- }
- // NewNACLSecretbox returns a new NACL secretbox encrypter/decrypter with the given key
- func NewNACLSecretbox(key []byte) NACLSecretbox {
- secretbox := NACLSecretbox{}
- copy(secretbox.key[:], key)
- return secretbox
- }
- // Algorithm returns the type of algorithm this is (NACL Secretbox using XSalsa20 and Poly1305)
- func (n NACLSecretbox) Algorithm() api.MaybeEncryptedRecord_Algorithm {
- return api.MaybeEncryptedRecord_NACLSecretboxSalsa20Poly1305
- }
- // Encrypt encrypts some bytes and returns an encrypted record
- func (n NACLSecretbox) Encrypt(data []byte) (*api.MaybeEncryptedRecord, error) {
- var nonce [24]byte
- if _, err := io.ReadFull(cryptorand.Reader, nonce[:]); err != nil {
- return nil, err
- }
- // Seal's first argument is an "out", the data that the new encrypted message should be
- // appended to. Since we don't want to append anything, we pass nil.
- encrypted := secretbox.Seal(nil, data, &nonce, &n.key)
- return &api.MaybeEncryptedRecord{
- Algorithm: n.Algorithm(),
- Data: encrypted,
- Nonce: nonce[:],
- }, nil
- }
- // Decrypt decrypts a MaybeEncryptedRecord and returns some bytes
- func (n NACLSecretbox) Decrypt(record api.MaybeEncryptedRecord) ([]byte, error) {
- if record.Algorithm != n.Algorithm() {
- return nil, fmt.Errorf("not a NACL secretbox record")
- }
- if len(record.Nonce) != naclSecretboxNonceSize {
- return nil, fmt.Errorf("invalid nonce size for NACL secretbox: require 24, got %d", len(record.Nonce))
- }
- var decryptNonce [naclSecretboxNonceSize]byte
- copy(decryptNonce[:], record.Nonce[:naclSecretboxNonceSize])
- // Open's first argument is an "out", the data that the decrypted message should be
- // appended to. Since we don't want to append anything, we pass nil.
- decrypted, ok := secretbox.Open(nil, record.Data, &decryptNonce, &n.key)
- if !ok {
- return nil, fmt.Errorf("decryption error using NACL secretbox")
- }
- return decrypted, nil
- }
|