github.com/icodeface/tls@v0.0.0-20230910023335-34df9250cd12/internal/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go (about) 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 //go:build go1.7 && amd64 && !gccgo && !appengine 6 // +build go1.7,amd64,!gccgo,!appengine 7 8 package chacha20poly1305 9 10 import ( 11 "encoding/binary" 12 13 "github.com/icodeface/tls/internal/cpu" 14 ) 15 16 //go:noescape 17 func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool 18 19 //go:noescape 20 func chacha20Poly1305Seal(dst []byte, key []uint32, src, ad []byte) 21 22 var ( 23 useASM = cpu.X86.HasSSSE3 24 useAVX2 = cpu.X86.HasAVX2 && cpu.X86.HasBMI2 25 ) 26 27 // setupState writes a ChaCha20 input matrix to state. See 28 // https://tools.ietf.org/html/rfc7539#section-2.3. 29 func setupState(state *[16]uint32, key *[8]uint32, nonce []byte) { 30 state[0] = 0x61707865 31 state[1] = 0x3320646e 32 state[2] = 0x79622d32 33 state[3] = 0x6b206574 34 35 state[4] = key[0] 36 state[5] = key[1] 37 state[6] = key[2] 38 state[7] = key[3] 39 state[8] = key[4] 40 state[9] = key[5] 41 state[10] = key[6] 42 state[11] = key[7] 43 44 state[12] = 0 45 state[13] = binary.LittleEndian.Uint32(nonce[:4]) 46 state[14] = binary.LittleEndian.Uint32(nonce[4:8]) 47 state[15] = binary.LittleEndian.Uint32(nonce[8:12]) 48 } 49 50 func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte { 51 if !useASM { 52 return c.sealGeneric(dst, nonce, plaintext, additionalData) 53 } 54 55 var state [16]uint32 56 setupState(&state, &c.key, nonce) 57 58 ret, out := sliceForAppend(dst, len(plaintext)+16) 59 chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData) 60 return ret 61 } 62 63 func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { 64 if !useASM { 65 return c.openGeneric(dst, nonce, ciphertext, additionalData) 66 } 67 68 var state [16]uint32 69 setupState(&state, &c.key, nonce) 70 71 ciphertext = ciphertext[:len(ciphertext)-16] 72 ret, out := sliceForAppend(dst, len(ciphertext)) 73 if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) { 74 for i := range out { 75 out[i] = 0 76 } 77 return nil, errOpen 78 } 79 80 return ret, nil 81 }