primitives.go (1536B)
1 // Copyright 2019 Google LLC 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file or at 5 // https://developers.google.com/open-source/licenses/bsd 6 7 package age 8 9 import ( 10 "crypto/hmac" 11 "crypto/sha256" 12 "io" 13 14 "github.com/FiloSottile/age/internal/format" 15 "golang.org/x/crypto/chacha20poly1305" 16 "golang.org/x/crypto/hkdf" 17 ) 18 19 func aeadEncrypt(key, plaintext []byte) ([]byte, error) { 20 aead, err := chacha20poly1305.New(key) 21 if err != nil { 22 return nil, err 23 } 24 nonce := make([]byte, chacha20poly1305.NonceSize) 25 return aead.Seal(nil, nonce, plaintext, nil), nil 26 } 27 28 func aeadDecrypt(key, ciphertext []byte) ([]byte, error) { 29 aead, err := chacha20poly1305.New(key) 30 if err != nil { 31 return nil, err 32 } 33 nonce := make([]byte, chacha20poly1305.NonceSize) 34 return aead.Open(nil, nonce, ciphertext, nil) 35 } 36 37 func headerMAC(fileKey []byte, hdr *format.Header) ([]byte, error) { 38 h := hkdf.New(sha256.New, fileKey, nil, []byte("header")) 39 hmacKey := make([]byte, 32) 40 if _, err := io.ReadFull(h, hmacKey); err != nil { 41 return nil, err 42 } 43 hh := hmac.New(sha256.New, hmacKey) 44 if err := hdr.MarshalWithoutMAC(hh); err != nil { 45 return nil, err 46 } 47 return hh.Sum(nil), nil 48 } 49 50 func streamKey(fileKey, nonce []byte) []byte { 51 h := hkdf.New(sha256.New, fileKey, nonce, []byte("payload")) 52 streamKey := make([]byte, chacha20poly1305.KeySize) 53 if _, err := io.ReadFull(h, streamKey); err != nil { 54 panic("age: internal error: failed to read from HKDF: " + err.Error()) 55 } 56 return streamKey 57 }