github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/manager/encryption/nacl.go (about) 1 package encryption 2 3 import ( 4 cryptorand "crypto/rand" 5 "fmt" 6 "io" 7 8 "github.com/docker/swarmkit/api" 9 10 "golang.org/x/crypto/nacl/secretbox" 11 ) 12 13 const naclSecretboxKeySize = 32 14 const naclSecretboxNonceSize = 24 15 16 // This provides the default implementation of an encrypter and decrypter, as well 17 // as the default KDF function. 18 19 // NACLSecretbox is an implementation of an encrypter/decrypter. Encrypting 20 // generates random Nonces. 21 type NACLSecretbox struct { 22 key [naclSecretboxKeySize]byte 23 } 24 25 // NewNACLSecretbox returns a new NACL secretbox encrypter/decrypter with the given key 26 func NewNACLSecretbox(key []byte) NACLSecretbox { 27 secretbox := NACLSecretbox{} 28 copy(secretbox.key[:], key) 29 return secretbox 30 } 31 32 // Algorithm returns the type of algorithm this is (NACL Secretbox using XSalsa20 and Poly1305) 33 func (n NACLSecretbox) Algorithm() api.MaybeEncryptedRecord_Algorithm { 34 return api.MaybeEncryptedRecord_NACLSecretboxSalsa20Poly1305 35 } 36 37 // Encrypt encrypts some bytes and returns an encrypted record 38 func (n NACLSecretbox) Encrypt(data []byte) (*api.MaybeEncryptedRecord, error) { 39 var nonce [24]byte 40 if _, err := io.ReadFull(cryptorand.Reader, nonce[:]); err != nil { 41 return nil, err 42 } 43 44 // Seal's first argument is an "out", the data that the new encrypted message should be 45 // appended to. Since we don't want to append anything, we pass nil. 46 encrypted := secretbox.Seal(nil, data, &nonce, &n.key) 47 return &api.MaybeEncryptedRecord{ 48 Algorithm: n.Algorithm(), 49 Data: encrypted, 50 Nonce: nonce[:], 51 }, nil 52 } 53 54 // Decrypt decrypts a MaybeEncryptedRecord and returns some bytes 55 func (n NACLSecretbox) Decrypt(record api.MaybeEncryptedRecord) ([]byte, error) { 56 if record.Algorithm != n.Algorithm() { 57 return nil, fmt.Errorf("not a NACL secretbox record") 58 } 59 if len(record.Nonce) != naclSecretboxNonceSize { 60 return nil, fmt.Errorf("invalid nonce size for NACL secretbox: require 24, got %d", len(record.Nonce)) 61 } 62 63 var decryptNonce [naclSecretboxNonceSize]byte 64 copy(decryptNonce[:], record.Nonce[:naclSecretboxNonceSize]) 65 66 // Open's first argument is an "out", the data that the decrypted message should be 67 // appended to. Since we don't want to append anything, we pass nil. 68 decrypted, ok := secretbox.Open(nil, record.Data, &decryptNonce, &n.key) 69 if !ok { 70 return nil, fmt.Errorf("no decryption key for record encrypted with %s", n.Algorithm()) 71 } 72 return decrypted, nil 73 }