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")
    35  	}
    36  
    37  	var polyKey [32]byte
    38  	s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce)
    39  	s.XORKeyStream(polyKey[:], polyKey[:])
    40  	s.SetCounter(1) // set the counter to 1, skipping 32 bytes
    41  	s.XORKeyStream(ciphertext, plaintext)
    42  
    43  	p := poly1305.New(&polyKey)
    44  	writeWithPadding(p, additionalData)
    45  	writeWithPadding(p, ciphertext)
    46  	writeUint64(p, len(additionalData))
    47  	writeUint64(p, len(plaintext))
    48  	p.Sum(tag[:0])
    49  
    50  	return ret
    51  }
    52  
    53  func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
    54  	tag := ciphertext[len(ciphertext)-16:]
    55  	ciphertext = ciphertext[:len(ciphertext)-16]
    56  
    57  	var polyKey [32]byte
    58  	s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce)
    59  	s.XORKeyStream(polyKey[:], polyKey[:])
    60  	s.SetCounter(1) // set the counter to 1, skipping 32 bytes
    61  
    62  	p := poly1305.New(&polyKey)
    63  	writeWithPadding(p, additionalData)
    64  	writeWithPadding(p, ciphertext)
    65  	writeUint64(p, len(additionalData))
    66  	writeUint64(p, len(ciphertext))
    67  
    68  	ret, out := sliceForAppend(dst, len(ciphertext))
    69  	if alias.InexactOverlap(out, ciphertext) {
    70  		panic("chacha20poly1305: invalid buffer overlap")
    71  	}
    72  	if !p.Verify(tag) {
    73  		for i := range out {
    74  			out[i] = 0
    75  		}
    76  		return nil, errOpen
    77  	}
    78  
    79  	s.XORKeyStream(out, ciphertext)
    80  	return ret, nil
    81  }
    82  

View as plain text