Restructured MAC/cookie calculation
Added copy-right headers accidentally removed
This commit is contained in:
parent
86707cbc88
commit
8393cbff52
|
@ -18,8 +18,8 @@ func (tun *DummyTUN) Name() string {
|
||||||
return tun.name
|
return tun.name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *DummyTUN) MTU() int {
|
func (tun *DummyTUN) MTU() (int, error) {
|
||||||
return tun.mtu
|
return tun.mtu, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *DummyTUN) Write(d []byte) (int, error) {
|
func (tun *DummyTUN) Write(d []byte) (int, error) {
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/cipher"
|
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"github.com/aead/chacha20poly1305" // Needed for XChaCha20Poly1305, TODO:
|
"errors"
|
||||||
"golang.org/x/crypto/blake2s"
|
"golang.org/x/crypto/blake2s"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -17,9 +16,22 @@ type MACStateDevice struct {
|
||||||
secret [blake2s.Size]byte
|
secret [blake2s.Size]byte
|
||||||
keyMAC1 [blake2s.Size]byte
|
keyMAC1 [blake2s.Size]byte
|
||||||
keyMAC2 [blake2s.Size]byte
|
keyMAC2 [blake2s.Size]byte
|
||||||
xaead cipher.AEAD
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MACStatePeer struct {
|
||||||
|
mutex sync.RWMutex
|
||||||
|
cookieSet time.Time
|
||||||
|
cookie [blake2s.Size128]byte
|
||||||
|
lastMAC1 [blake2s.Size128]byte
|
||||||
|
keyMAC1 [blake2s.Size]byte
|
||||||
|
keyMAC2 [blake2s.Size]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Methods for verifing MAC fields
|
||||||
|
* and creating/consuming cookies replies
|
||||||
|
* (per device)
|
||||||
|
*/
|
||||||
|
|
||||||
func (state *MACStateDevice) Init(pk NoisePublicKey) {
|
func (state *MACStateDevice) Init(pk NoisePublicKey) {
|
||||||
state.mutex.Lock()
|
state.mutex.Lock()
|
||||||
defer state.mutex.Unlock()
|
defer state.mutex.Unlock()
|
||||||
|
@ -38,7 +50,6 @@ func (state *MACStateDevice) Init(pk NoisePublicKey) {
|
||||||
hsh.Sum(state.keyMAC2[:0])
|
hsh.Sum(state.keyMAC2[:0])
|
||||||
}()
|
}()
|
||||||
|
|
||||||
state.xaead, _ = chacha20poly1305.NewXCipher(state.keyMAC2[:])
|
|
||||||
state.refreshed = time.Time{}
|
state.refreshed = time.Time{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +101,10 @@ func (state *MACStateDevice) CheckMAC2(msg []byte, addr *net.UDPAddr) bool {
|
||||||
return hmac.Equal(mac2[:], msg[start:])
|
return hmac.Equal(mac2[:], msg[start:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (device *Device) CreateMessageCookieReply(msg []byte, receiver uint32, addr *net.UDPAddr) (*MessageCookieReply, error) {
|
func (device *Device) CreateMessageCookieReply(
|
||||||
|
msg []byte, receiver uint32, addr *net.UDPAddr,
|
||||||
|
) (*MessageCookieReply, error) {
|
||||||
|
|
||||||
state := &device.mac
|
state := &device.mac
|
||||||
state.mutex.RLock()
|
state.mutex.RLock()
|
||||||
|
|
||||||
|
@ -137,7 +151,15 @@ func (device *Device) CreateMessageCookieReply(msg []byte, receiver uint32, addr
|
||||||
state.mutex.RUnlock()
|
state.mutex.RUnlock()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
state.xaead.Seal(reply.Cookie[:0], reply.Nonce[:], cookie[:], mac1)
|
|
||||||
|
XChaCha20Poly1305Encrypt(
|
||||||
|
reply.Cookie[:0],
|
||||||
|
&reply.Nonce,
|
||||||
|
cookie[:],
|
||||||
|
mac1,
|
||||||
|
&state.keyMAC2,
|
||||||
|
)
|
||||||
|
|
||||||
state.mutex.RUnlock()
|
state.mutex.RUnlock()
|
||||||
return reply, nil
|
return reply, nil
|
||||||
}
|
}
|
||||||
|
@ -163,7 +185,14 @@ func (device *Device) ConsumeMessageCookieReply(msg *MessageCookieReply) bool {
|
||||||
state.mutex.Lock()
|
state.mutex.Lock()
|
||||||
defer state.mutex.Unlock()
|
defer state.mutex.Unlock()
|
||||||
|
|
||||||
_, err := state.xaead.Open(cookie[:0], msg.Nonce[:], msg.Cookie[:], state.lastMAC1[:])
|
_, err := XChaCha20Poly1305Decrypt(
|
||||||
|
cookie[:0],
|
||||||
|
&msg.Nonce,
|
||||||
|
msg.Cookie[:],
|
||||||
|
state.lastMAC1[:],
|
||||||
|
&state.keyMAC2,
|
||||||
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -171,3 +200,69 @@ func (device *Device) ConsumeMessageCookieReply(msg *MessageCookieReply) bool {
|
||||||
state.cookie = cookie
|
state.cookie = cookie
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Methods for generating the MAC fields
|
||||||
|
* (per peer)
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (state *MACStatePeer) Init(pk NoisePublicKey) {
|
||||||
|
state.mutex.Lock()
|
||||||
|
defer state.mutex.Unlock()
|
||||||
|
|
||||||
|
func() {
|
||||||
|
hsh, _ := blake2s.New256(nil)
|
||||||
|
hsh.Write([]byte(WGLabelMAC1))
|
||||||
|
hsh.Write(pk[:])
|
||||||
|
hsh.Sum(state.keyMAC1[:0])
|
||||||
|
}()
|
||||||
|
|
||||||
|
func() {
|
||||||
|
hsh, _ := blake2s.New256(nil)
|
||||||
|
hsh.Write([]byte(WGLabelCookie))
|
||||||
|
hsh.Write(pk[:])
|
||||||
|
hsh.Sum(state.keyMAC2[:0])
|
||||||
|
}()
|
||||||
|
|
||||||
|
state.cookieSet = time.Time{} // never
|
||||||
|
}
|
||||||
|
|
||||||
|
func (state *MACStatePeer) AddMacs(msg []byte) {
|
||||||
|
size := len(msg)
|
||||||
|
|
||||||
|
if size < blake2s.Size128*2 {
|
||||||
|
panic(errors.New("bug: message too short"))
|
||||||
|
}
|
||||||
|
|
||||||
|
startMac1 := size - (blake2s.Size128 * 2)
|
||||||
|
startMac2 := size - blake2s.Size128
|
||||||
|
|
||||||
|
mac1 := msg[startMac1 : startMac1+blake2s.Size128]
|
||||||
|
mac2 := msg[startMac2 : startMac2+blake2s.Size128]
|
||||||
|
|
||||||
|
state.mutex.Lock()
|
||||||
|
defer state.mutex.Unlock()
|
||||||
|
|
||||||
|
// set mac1
|
||||||
|
|
||||||
|
func() {
|
||||||
|
mac, _ := blake2s.New128(state.keyMAC1[:])
|
||||||
|
mac.Write(msg[:startMac1])
|
||||||
|
mac.Sum(mac1[:0])
|
||||||
|
}()
|
||||||
|
copy(state.lastMAC1[:], mac1)
|
||||||
|
|
||||||
|
// set mac2
|
||||||
|
|
||||||
|
if state.cookieSet.IsZero() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if time.Now().Sub(state.cookieSet) > CookieRefreshTime {
|
||||||
|
state.cookieSet = time.Time{}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func() {
|
||||||
|
mac, _ := blake2s.New128(state.cookie[:])
|
||||||
|
mac.Write(msg[:startMac2])
|
||||||
|
mac.Sum(mac2[:0])
|
||||||
|
}()
|
||||||
|
}
|
|
@ -1,83 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/cipher"
|
|
||||||
"errors"
|
|
||||||
"github.com/aead/chacha20poly1305" // Needed for XChaCha20Poly1305, TODO:
|
|
||||||
"golang.org/x/crypto/blake2s"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MACStatePeer struct {
|
|
||||||
mutex sync.RWMutex
|
|
||||||
cookieSet time.Time
|
|
||||||
cookie [blake2s.Size128]byte
|
|
||||||
lastMAC1 [blake2s.Size128]byte
|
|
||||||
keyMAC1 [blake2s.Size]byte
|
|
||||||
keyMAC2 [blake2s.Size]byte
|
|
||||||
xaead cipher.AEAD
|
|
||||||
}
|
|
||||||
|
|
||||||
func (state *MACStatePeer) Init(pk NoisePublicKey) {
|
|
||||||
state.mutex.Lock()
|
|
||||||
defer state.mutex.Unlock()
|
|
||||||
|
|
||||||
func() {
|
|
||||||
hsh, _ := blake2s.New256(nil)
|
|
||||||
hsh.Write([]byte(WGLabelMAC1))
|
|
||||||
hsh.Write(pk[:])
|
|
||||||
hsh.Sum(state.keyMAC1[:0])
|
|
||||||
}()
|
|
||||||
|
|
||||||
func() {
|
|
||||||
hsh, _ := blake2s.New256(nil)
|
|
||||||
hsh.Write([]byte(WGLabelCookie))
|
|
||||||
hsh.Write(pk[:])
|
|
||||||
hsh.Sum(state.keyMAC2[:0])
|
|
||||||
}()
|
|
||||||
|
|
||||||
state.xaead, _ = chacha20poly1305.NewXCipher(state.keyMAC2[:])
|
|
||||||
state.cookieSet = time.Time{} // never
|
|
||||||
}
|
|
||||||
|
|
||||||
func (state *MACStatePeer) AddMacs(msg []byte) {
|
|
||||||
size := len(msg)
|
|
||||||
|
|
||||||
if size < blake2s.Size128*2 {
|
|
||||||
panic(errors.New("bug: message too short"))
|
|
||||||
}
|
|
||||||
|
|
||||||
startMac1 := size - (blake2s.Size128 * 2)
|
|
||||||
startMac2 := size - blake2s.Size128
|
|
||||||
|
|
||||||
mac1 := msg[startMac1 : startMac1+blake2s.Size128]
|
|
||||||
mac2 := msg[startMac2 : startMac2+blake2s.Size128]
|
|
||||||
|
|
||||||
state.mutex.Lock()
|
|
||||||
defer state.mutex.Unlock()
|
|
||||||
|
|
||||||
// set mac1
|
|
||||||
|
|
||||||
func() {
|
|
||||||
mac, _ := blake2s.New128(state.keyMAC1[:])
|
|
||||||
mac.Write(msg[:startMac1])
|
|
||||||
mac.Sum(state.lastMAC1[:0])
|
|
||||||
}()
|
|
||||||
copy(mac1, state.lastMAC1[:])
|
|
||||||
|
|
||||||
// set mac2
|
|
||||||
|
|
||||||
if state.cookieSet.IsZero() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if time.Now().Sub(state.cookieSet) > CookieRefreshTime {
|
|
||||||
state.cookieSet = time.Time{}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
func() {
|
|
||||||
mac, _ := blake2s.New128(state.cookie[:])
|
|
||||||
mac.Write(msg[:startMac2])
|
|
||||||
mac.Sum(mac2[:0])
|
|
||||||
}()
|
|
||||||
}
|
|
|
@ -1,9 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
/* Implementation of the ratelimited form the linux kernel version
|
/* Copyright (C) 2015-2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */
|
||||||
*
|
|
||||||
*
|
/* This file contains a port of the ratelimited from the linux kernel version
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
/* Copyright (C) 2015-2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */
|
||||||
|
|
||||||
/* Implementation of RFC6479
|
/* Implementation of RFC6479
|
||||||
* https://tools.ietf.org/html/rfc6479
|
* https://tools.ietf.org/html/rfc6479
|
||||||
*
|
*
|
||||||
|
|
169
src/xchacha20.go
Normal file
169
src/xchacha20.go
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
// Copyright (c) 2016 Andreas Auernhammer. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"golang.org/x/crypto/chacha20poly1305"
|
||||||
|
)
|
||||||
|
|
||||||
|
func HChaCha20(out *[32]byte, nonce []byte, key *[32]byte) {
|
||||||
|
|
||||||
|
v00 := uint32(0x61707865)
|
||||||
|
v01 := uint32(0x3320646e)
|
||||||
|
v02 := uint32(0x79622d32)
|
||||||
|
v03 := uint32(0x6b206574)
|
||||||
|
|
||||||
|
v04 := binary.LittleEndian.Uint32(key[0:])
|
||||||
|
v05 := binary.LittleEndian.Uint32(key[4:])
|
||||||
|
v06 := binary.LittleEndian.Uint32(key[8:])
|
||||||
|
v07 := binary.LittleEndian.Uint32(key[12:])
|
||||||
|
v08 := binary.LittleEndian.Uint32(key[16:])
|
||||||
|
v09 := binary.LittleEndian.Uint32(key[20:])
|
||||||
|
v10 := binary.LittleEndian.Uint32(key[24:])
|
||||||
|
v11 := binary.LittleEndian.Uint32(key[28:])
|
||||||
|
v12 := binary.LittleEndian.Uint32(nonce[0:])
|
||||||
|
v13 := binary.LittleEndian.Uint32(nonce[4:])
|
||||||
|
v14 := binary.LittleEndian.Uint32(nonce[8:])
|
||||||
|
v15 := binary.LittleEndian.Uint32(nonce[12:])
|
||||||
|
|
||||||
|
for i := 0; i < 20; i += 2 {
|
||||||
|
v00 += v04
|
||||||
|
v12 ^= v00
|
||||||
|
v12 = (v12 << 16) | (v12 >> 16)
|
||||||
|
v08 += v12
|
||||||
|
v04 ^= v08
|
||||||
|
v04 = (v04 << 12) | (v04 >> 20)
|
||||||
|
v00 += v04
|
||||||
|
v12 ^= v00
|
||||||
|
v12 = (v12 << 8) | (v12 >> 24)
|
||||||
|
v08 += v12
|
||||||
|
v04 ^= v08
|
||||||
|
v04 = (v04 << 7) | (v04 >> 25)
|
||||||
|
v01 += v05
|
||||||
|
v13 ^= v01
|
||||||
|
v13 = (v13 << 16) | (v13 >> 16)
|
||||||
|
v09 += v13
|
||||||
|
v05 ^= v09
|
||||||
|
v05 = (v05 << 12) | (v05 >> 20)
|
||||||
|
v01 += v05
|
||||||
|
v13 ^= v01
|
||||||
|
v13 = (v13 << 8) | (v13 >> 24)
|
||||||
|
v09 += v13
|
||||||
|
v05 ^= v09
|
||||||
|
v05 = (v05 << 7) | (v05 >> 25)
|
||||||
|
v02 += v06
|
||||||
|
v14 ^= v02
|
||||||
|
v14 = (v14 << 16) | (v14 >> 16)
|
||||||
|
v10 += v14
|
||||||
|
v06 ^= v10
|
||||||
|
v06 = (v06 << 12) | (v06 >> 20)
|
||||||
|
v02 += v06
|
||||||
|
v14 ^= v02
|
||||||
|
v14 = (v14 << 8) | (v14 >> 24)
|
||||||
|
v10 += v14
|
||||||
|
v06 ^= v10
|
||||||
|
v06 = (v06 << 7) | (v06 >> 25)
|
||||||
|
v03 += v07
|
||||||
|
v15 ^= v03
|
||||||
|
v15 = (v15 << 16) | (v15 >> 16)
|
||||||
|
v11 += v15
|
||||||
|
v07 ^= v11
|
||||||
|
v07 = (v07 << 12) | (v07 >> 20)
|
||||||
|
v03 += v07
|
||||||
|
v15 ^= v03
|
||||||
|
v15 = (v15 << 8) | (v15 >> 24)
|
||||||
|
v11 += v15
|
||||||
|
v07 ^= v11
|
||||||
|
v07 = (v07 << 7) | (v07 >> 25)
|
||||||
|
v00 += v05
|
||||||
|
v15 ^= v00
|
||||||
|
v15 = (v15 << 16) | (v15 >> 16)
|
||||||
|
v10 += v15
|
||||||
|
v05 ^= v10
|
||||||
|
v05 = (v05 << 12) | (v05 >> 20)
|
||||||
|
v00 += v05
|
||||||
|
v15 ^= v00
|
||||||
|
v15 = (v15 << 8) | (v15 >> 24)
|
||||||
|
v10 += v15
|
||||||
|
v05 ^= v10
|
||||||
|
v05 = (v05 << 7) | (v05 >> 25)
|
||||||
|
v01 += v06
|
||||||
|
v12 ^= v01
|
||||||
|
v12 = (v12 << 16) | (v12 >> 16)
|
||||||
|
v11 += v12
|
||||||
|
v06 ^= v11
|
||||||
|
v06 = (v06 << 12) | (v06 >> 20)
|
||||||
|
v01 += v06
|
||||||
|
v12 ^= v01
|
||||||
|
v12 = (v12 << 8) | (v12 >> 24)
|
||||||
|
v11 += v12
|
||||||
|
v06 ^= v11
|
||||||
|
v06 = (v06 << 7) | (v06 >> 25)
|
||||||
|
v02 += v07
|
||||||
|
v13 ^= v02
|
||||||
|
v13 = (v13 << 16) | (v13 >> 16)
|
||||||
|
v08 += v13
|
||||||
|
v07 ^= v08
|
||||||
|
v07 = (v07 << 12) | (v07 >> 20)
|
||||||
|
v02 += v07
|
||||||
|
v13 ^= v02
|
||||||
|
v13 = (v13 << 8) | (v13 >> 24)
|
||||||
|
v08 += v13
|
||||||
|
v07 ^= v08
|
||||||
|
v07 = (v07 << 7) | (v07 >> 25)
|
||||||
|
v03 += v04
|
||||||
|
v14 ^= v03
|
||||||
|
v14 = (v14 << 16) | (v14 >> 16)
|
||||||
|
v09 += v14
|
||||||
|
v04 ^= v09
|
||||||
|
v04 = (v04 << 12) | (v04 >> 20)
|
||||||
|
v03 += v04
|
||||||
|
v14 ^= v03
|
||||||
|
v14 = (v14 << 8) | (v14 >> 24)
|
||||||
|
v09 += v14
|
||||||
|
v04 ^= v09
|
||||||
|
v04 = (v04 << 7) | (v04 >> 25)
|
||||||
|
}
|
||||||
|
|
||||||
|
binary.LittleEndian.PutUint32(out[0:], v00)
|
||||||
|
binary.LittleEndian.PutUint32(out[4:], v01)
|
||||||
|
binary.LittleEndian.PutUint32(out[8:], v02)
|
||||||
|
binary.LittleEndian.PutUint32(out[12:], v03)
|
||||||
|
binary.LittleEndian.PutUint32(out[16:], v12)
|
||||||
|
binary.LittleEndian.PutUint32(out[20:], v13)
|
||||||
|
binary.LittleEndian.PutUint32(out[24:], v14)
|
||||||
|
binary.LittleEndian.PutUint32(out[28:], v15)
|
||||||
|
}
|
||||||
|
|
||||||
|
func XChaCha20Poly1305Encrypt(
|
||||||
|
dst []byte,
|
||||||
|
nonceFull *[24]byte,
|
||||||
|
plaintext []byte,
|
||||||
|
additionalData []byte,
|
||||||
|
key *[chacha20poly1305.KeySize]byte,
|
||||||
|
) []byte {
|
||||||
|
var nonce [chacha20poly1305.NonceSize]byte
|
||||||
|
var derivedKey [chacha20poly1305.KeySize]byte
|
||||||
|
HChaCha20(&derivedKey, nonceFull[:16], key)
|
||||||
|
aead, _ := chacha20poly1305.New(derivedKey[:])
|
||||||
|
copy(nonce[4:], nonceFull[16:])
|
||||||
|
return aead.Seal(dst, nonce[:], plaintext, additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func XChaCha20Poly1305Decrypt(
|
||||||
|
dst []byte,
|
||||||
|
nonceFull *[24]byte,
|
||||||
|
plaintext []byte,
|
||||||
|
additionalData []byte,
|
||||||
|
key *[chacha20poly1305.KeySize]byte,
|
||||||
|
) ([]byte, error) {
|
||||||
|
var nonce [chacha20poly1305.NonceSize]byte
|
||||||
|
var derivedKey [chacha20poly1305.KeySize]byte
|
||||||
|
HChaCha20(&derivedKey, nonceFull[:16], key)
|
||||||
|
aead, _ := chacha20poly1305.New(derivedKey[:])
|
||||||
|
copy(nonce[4:], nonceFull[16:])
|
||||||
|
return aead.Open(dst, nonce[:], plaintext, additionalData)
|
||||||
|
}
|
96
src/xchacha20_test.go
Normal file
96
src/xchacha20_test.go
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type XChaCha20Test struct {
|
||||||
|
Nonce string
|
||||||
|
Key string
|
||||||
|
PT string
|
||||||
|
CT string
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestXChaCha20(t *testing.T) {
|
||||||
|
|
||||||
|
tests := []XChaCha20Test{
|
||||||
|
{
|
||||||
|
Nonce: "000000000000000000000000000000000000000000000000",
|
||||||
|
Key: "0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
PT: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
CT: "789e9689e5208d7fd9e1f3c5b5341f48ef18a13e418998addadd97a3693a987f8e82ecd5c1433bfed1af49750c0f1ff29c4174a05b119aa3a9e8333812e0c0feb1299c5949d895ee01dbf50f8395dd84",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Nonce: "0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f",
|
||||||
|
Key: "0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f",
|
||||||
|
PT: "0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f",
|
||||||
|
CT: "e1a046aa7f71e2af8b80b6408b2fd8d3a350278cde79c94d9efaa475e1339b3dd490127b",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Nonce: "d9a8213e8a697508805c2c171ad54487ead9e3e02d82d5bc",
|
||||||
|
Key: "979196dbd78526f2f584f7534db3f5824d8ccfa858ca7e09bdd3656ecd36033c",
|
||||||
|
PT: "43cc6d624e451bbed952c3e071dc6c03392ce11eb14316a94b2fdc98b22fedea",
|
||||||
|
CT: "53c1e8bef2dbb8f2505ec010a7afe21d5a8e6dd8f987e4ea1a2ed5dfbc844ea400db34496fd2153526c6e87c36694200",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
|
||||||
|
nonce, err := hex.DecodeString(test.Nonce)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
key, err := hex.DecodeString(test.Key)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pt, err := hex.DecodeString(test.PT)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func() {
|
||||||
|
var nonceArray [24]byte
|
||||||
|
var keyArray [32]byte
|
||||||
|
copy(nonceArray[:], nonce)
|
||||||
|
copy(keyArray[:], key)
|
||||||
|
|
||||||
|
// test encryption
|
||||||
|
|
||||||
|
ct := XChaCha20Poly1305Encrypt(
|
||||||
|
nil,
|
||||||
|
&nonceArray,
|
||||||
|
pt,
|
||||||
|
nil,
|
||||||
|
&keyArray,
|
||||||
|
)
|
||||||
|
ctHex := hex.EncodeToString(ct)
|
||||||
|
if ctHex != test.CT {
|
||||||
|
t.Fatal("encryption failed, expected:", test.CT, "got", ctHex)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test decryption
|
||||||
|
|
||||||
|
ptp, err := XChaCha20Poly1305Decrypt(
|
||||||
|
nil,
|
||||||
|
&nonceArray,
|
||||||
|
ct,
|
||||||
|
nil,
|
||||||
|
&keyArray,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ptHex := hex.EncodeToString(ptp)
|
||||||
|
if ptHex != test.PT {
|
||||||
|
t.Fatal("decryption failed, expected:", test.PT, "got", ptHex)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue