123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- // Copyright 2016 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package chacha20poly1305
- import (
- "encoding/binary"
- "golang.org/x/crypto/chacha20"
- "golang.org/x/crypto/internal/alias"
- "golang.org/x/crypto/internal/poly1305"
- )
- func writeWithPadding(p *poly1305.MAC, b []byte) {
- p.Write(b)
- if rem := len(b) % 16; rem != 0 {
- var buf [16]byte
- padLen := 16 - rem
- p.Write(buf[:padLen])
- }
- }
- func writeUint64(p *poly1305.MAC, n int) {
- var buf [8]byte
- binary.LittleEndian.PutUint64(buf[:], uint64(n))
- p.Write(buf[:])
- }
- func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte {
- ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
- ciphertext, tag := out[:len(plaintext)], out[len(plaintext):]
- if alias.InexactOverlap(out, plaintext) {
- panic("chacha20poly1305: invalid buffer overlap")
- }
- var polyKey [32]byte
- s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce)
- s.XORKeyStream(polyKey[:], polyKey[:])
- s.SetCounter(1) // set the counter to 1, skipping 32 bytes
- s.XORKeyStream(ciphertext, plaintext)
- p := poly1305.New(&polyKey)
- writeWithPadding(p, additionalData)
- writeWithPadding(p, ciphertext)
- writeUint64(p, len(additionalData))
- writeUint64(p, len(plaintext))
- p.Sum(tag[:0])
- return ret
- }
- func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
- tag := ciphertext[len(ciphertext)-16:]
- ciphertext = ciphertext[:len(ciphertext)-16]
- var polyKey [32]byte
- s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce)
- s.XORKeyStream(polyKey[:], polyKey[:])
- s.SetCounter(1) // set the counter to 1, skipping 32 bytes
- p := poly1305.New(&polyKey)
- writeWithPadding(p, additionalData)
- writeWithPadding(p, ciphertext)
- writeUint64(p, len(additionalData))
- writeUint64(p, len(ciphertext))
- ret, out := sliceForAppend(dst, len(ciphertext))
- if alias.InexactOverlap(out, ciphertext) {
- panic("chacha20poly1305: invalid buffer overlap")
- }
- if !p.Verify(tag) {
- for i := range out {
- out[i] = 0
- }
- return nil, errOpen
- }
- s.XORKeyStream(out, ciphertext)
- return ret, nil
- }
|