forked from quic-go/quic-go
move to chacha20poly1305 fork
This commit is contained in:
@@ -5,7 +5,8 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/crypto/chacha20poly1305trunc12"
|
||||
"github.com/lucas-clemente/crypto/chacha"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/protocol"
|
||||
)
|
||||
|
||||
@@ -21,11 +22,11 @@ func NewAEADChacha20Poly1305(otherKey []byte, myKey []byte, otherIV []byte, myIV
|
||||
if len(myKey) != 32 || len(otherKey) != 32 || len(myIV) != 4 || len(otherIV) != 4 {
|
||||
return nil, errors.New("chacha20poly1305: expected 32-byte keys and 4-byte IVs")
|
||||
}
|
||||
encrypter, err := chacha20poly1305trunc12.NewAEAD(myKey)
|
||||
encrypter, err := chacha.NewAEADTagSize(myKey, 12)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
decrypter, err := chacha20poly1305trunc12.NewAEAD(otherKey)
|
||||
decrypter, err := chacha.NewAEADTagSize(otherKey, 12)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
// Taken and modified to have tag size = 12
|
||||
// from https://github.com/EncEve/crypto/blob/master/chacha/chachaPoly1305.go
|
||||
// TODO: Check, make independent
|
||||
|
||||
package chacha20poly1305trunc12
|
||||
|
||||
// Use of this source code is governed by a license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"crypto/subtle"
|
||||
|
||||
"github.com/EncEve/crypto"
|
||||
"github.com/EncEve/crypto/chacha"
|
||||
"github.com/EncEve/crypto/poly1305"
|
||||
)
|
||||
|
||||
// The AEAD cipher ChaCha20-Poly1305
|
||||
type aeadCipher struct {
|
||||
key [32]byte
|
||||
}
|
||||
|
||||
// NewAEAD returns a cipher.AEAD implementing the
|
||||
// ChaCha20-Poly1305 construction specified in
|
||||
// RFC 7539. The key argument must be 256 bit
|
||||
// (32 byte).
|
||||
func NewAEAD(key []byte) (cipher.AEAD, error) {
|
||||
if k := len(key); k != 32 {
|
||||
return nil, crypto.KeySizeError(k)
|
||||
}
|
||||
c := new(aeadCipher)
|
||||
for i, v := range key {
|
||||
c.key[i] = v
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (c *aeadCipher) Overhead() int { return 12 }
|
||||
|
||||
func (c *aeadCipher) NonceSize() int { return chacha.NonceSize }
|
||||
|
||||
func (c *aeadCipher) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
|
||||
if n := len(nonce); n != chacha.NonceSize {
|
||||
panic(crypto.NonceSizeError(n))
|
||||
}
|
||||
if len(dst) < len(plaintext) {
|
||||
panic("dst buffer to small")
|
||||
}
|
||||
var Nonce [12]byte
|
||||
copy(Nonce[:], nonce)
|
||||
|
||||
// create the ploy1305 key
|
||||
var polyKey [32]byte
|
||||
chacha.XORKeyStream(polyKey[:], polyKey[:], &(c.key), &Nonce, 0)
|
||||
|
||||
// encrypt the plaintext
|
||||
n := len(plaintext)
|
||||
chacha.XORKeyStream(dst, plaintext, &(c.key), &Nonce, 1)
|
||||
|
||||
// authenticate the ciphertext
|
||||
tag := authenticate(&polyKey, dst[:n], additionalData)
|
||||
return append(dst[:n], tag[0:12]...)
|
||||
}
|
||||
|
||||
func (c *aeadCipher) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
|
||||
if n := len(nonce); n != chacha.NonceSize {
|
||||
return nil, crypto.NonceSizeError(n)
|
||||
}
|
||||
if len(ciphertext) < 12 {
|
||||
return nil, crypto.AuthenticationError{}
|
||||
}
|
||||
if len(dst) < len(ciphertext)-12 {
|
||||
panic("dst buffer to small")
|
||||
}
|
||||
var Nonce [12]byte
|
||||
copy(Nonce[:], nonce)
|
||||
|
||||
hash := ciphertext[len(ciphertext)-12:]
|
||||
ciphertext = ciphertext[:len(ciphertext)-12]
|
||||
|
||||
// create the ploy1305 key
|
||||
var polyKey [32]byte
|
||||
chacha.XORKeyStream(polyKey[:], polyKey[:], &(c.key), &Nonce, 0)
|
||||
|
||||
// authenticate the ciphertext
|
||||
tag := authenticate(&polyKey, ciphertext, additionalData)
|
||||
if subtle.ConstantTimeCompare(tag[0:12], hash[0:12]) != 1 {
|
||||
return nil, crypto.AuthenticationError{}
|
||||
}
|
||||
|
||||
// decrypt ciphertext
|
||||
chacha.XORKeyStream(dst, ciphertext, &(c.key), &Nonce, 1)
|
||||
return dst[:len(ciphertext)], nil
|
||||
}
|
||||
|
||||
// authenticate calculates the poly1305 tag from
|
||||
// the given ciphertext and additional data.
|
||||
func authenticate(key *[32]byte, ciphertext, additionalData []byte) []byte {
|
||||
ctLen := uint64(len(ciphertext))
|
||||
adLen := uint64(len(additionalData))
|
||||
padAD, padCT := adLen%16, ctLen%16
|
||||
|
||||
var buf [16]byte
|
||||
buf[0] = byte(adLen)
|
||||
buf[1] = byte(adLen >> 8)
|
||||
buf[2] = byte(adLen >> 16)
|
||||
buf[3] = byte(adLen >> 24)
|
||||
buf[4] = byte(adLen >> 32)
|
||||
buf[5] = byte(adLen >> 40)
|
||||
buf[6] = byte(adLen >> 48)
|
||||
buf[7] = byte(adLen >> 56)
|
||||
buf[8] = byte(ctLen)
|
||||
buf[9] = byte(ctLen >> 8)
|
||||
buf[10] = byte(ctLen >> 16)
|
||||
buf[11] = byte(ctLen >> 24)
|
||||
buf[12] = byte(ctLen >> 32)
|
||||
buf[13] = byte(ctLen >> 40)
|
||||
buf[14] = byte(ctLen >> 48)
|
||||
buf[15] = byte(ctLen >> 56)
|
||||
|
||||
poly, _ := poly1305.New(key[:])
|
||||
poly.Write(additionalData)
|
||||
if padAD > 0 {
|
||||
poly.Write(make([]byte, 16-padAD))
|
||||
}
|
||||
poly.Write(ciphertext)
|
||||
if padCT > 0 {
|
||||
poly.Write(make([]byte, 16-padCT))
|
||||
}
|
||||
poly.Write(buf[:])
|
||||
return poly.Sum(nil)
|
||||
}
|
||||
Reference in New Issue
Block a user