Source file src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package chacha20poly1305
     6  
     7  import (
     8  	"encoding/binary"
     9  
    10  	"golang.org/x/crypto/chacha20"
    11  	"golang.org/x/crypto/internal/alias"
    12  	"golang.org/x/crypto/internal/poly1305"
    13  )
    14  
    15  func writeWithPadding(p *poly1305.MAC, b []byte) {
    16  	p.Write(b)
    17  	if rem := len(b) % 16; rem != 0 {
    18  		var buf [16]byte
    19  		padLen := 16 - rem
    20  		p.Write(buf[:padLen])
    21  	}
    22  }
    23  
    24  func writeUint64(p *poly1305.MAC, n int) {
    25  	var buf [8]byte
    26  	binary.LittleEndian.PutUint64(buf[:], uint64(n))
    27  	p.Write(buf[:])
    28  }
    29  
    30  func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte {
    31  	ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
    32  	ciphertext, tag := out[:len(plaintext)], out[len(plaintext):]
    33  	if alias.InexactOverlap(out, plaintext) {
    34  		panic("chacha20poly1305: invalid buffer overlap of output and input")
    35  	}
    36  	if alias.AnyOverlap(out, additionalData) {
    37  		panic("chacha20poly1305: invalid buffer overlap of output and additional data")
    38  	}
    39  
    40  	var polyKey [32]byte
    41  	s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce)
    42  	s.XORKeyStream(polyKey[:], polyKey[:])
    43  	s.SetCounter(1) // set the counter to 1, skipping 32 bytes
    44  	s.XORKeyStream(ciphertext, plaintext)
    45  
    46  	p := poly1305.New(&polyKey)
    47  	writeWithPadding(p, additionalData)
    48  	writeWithPadding(p, ciphertext)
    49  	writeUint64(p, len(additionalData))
    50  	writeUint64(p, len(plaintext))
    51  	p.Sum(tag[:0])
    52  
    53  	return ret
    54  }
    55  
    56  func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
    57  	tag := ciphertext[len(ciphertext)-16:]
    58  	ciphertext = ciphertext[:len(ciphertext)-16]
    59  
    60  	var polyKey [32]byte
    61  	s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce)
    62  	s.XORKeyStream(polyKey[:], polyKey[:])
    63  	s.SetCounter(1) // set the counter to 1, skipping 32 bytes
    64  
    65  	p := poly1305.New(&polyKey)
    66  	writeWithPadding(p, additionalData)
    67  	writeWithPadding(p, ciphertext)
    68  	writeUint64(p, len(additionalData))
    69  	writeUint64(p, len(ciphertext))
    70  
    71  	ret, out := sliceForAppend(dst, len(ciphertext))
    72  	if alias.InexactOverlap(out, ciphertext) {
    73  		panic("chacha20poly1305: invalid buffer overlap of output and input")
    74  	}
    75  	if alias.AnyOverlap(out, additionalData) {
    76  		panic("chacha20poly1305: invalid buffer overlap of output and additional data")
    77  	}
    78  	if !p.Verify(tag) {
    79  		for i := range out {
    80  			out[i] = 0
    81  		}
    82  		return nil, errOpen
    83  	}
    84  
    85  	s.XORKeyStream(out, ciphertext)
    86  	return ret, nil
    87  }
    88  

View as plain text