lib/connections: Add KCP support (fixes #804)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3489
This commit is contained in:
committed by
Jakob Borg
parent
151004d645
commit
0da0774ce4
526
vendor/golang.org/x/crypto/cast5/cast5.go
generated
vendored
Normal file
526
vendor/golang.org/x/crypto/cast5/cast5.go
generated
vendored
Normal file
@@ -0,0 +1,526 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package cast5 implements CAST5, as defined in RFC 2144. CAST5 is a common
|
||||
// OpenPGP cipher.
|
||||
package cast5 // import "golang.org/x/crypto/cast5"
|
||||
|
||||
import "errors"
|
||||
|
||||
const BlockSize = 8
|
||||
const KeySize = 16
|
||||
|
||||
type Cipher struct {
|
||||
masking [16]uint32
|
||||
rotate [16]uint8
|
||||
}
|
||||
|
||||
func NewCipher(key []byte) (c *Cipher, err error) {
|
||||
if len(key) != KeySize {
|
||||
return nil, errors.New("CAST5: keys must be 16 bytes")
|
||||
}
|
||||
|
||||
c = new(Cipher)
|
||||
c.keySchedule(key)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Cipher) BlockSize() int {
|
||||
return BlockSize
|
||||
}
|
||||
|
||||
func (c *Cipher) Encrypt(dst, src []byte) {
|
||||
l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
|
||||
r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
|
||||
|
||||
l, r = r, l^f1(r, c.masking[0], c.rotate[0])
|
||||
l, r = r, l^f2(r, c.masking[1], c.rotate[1])
|
||||
l, r = r, l^f3(r, c.masking[2], c.rotate[2])
|
||||
l, r = r, l^f1(r, c.masking[3], c.rotate[3])
|
||||
|
||||
l, r = r, l^f2(r, c.masking[4], c.rotate[4])
|
||||
l, r = r, l^f3(r, c.masking[5], c.rotate[5])
|
||||
l, r = r, l^f1(r, c.masking[6], c.rotate[6])
|
||||
l, r = r, l^f2(r, c.masking[7], c.rotate[7])
|
||||
|
||||
l, r = r, l^f3(r, c.masking[8], c.rotate[8])
|
||||
l, r = r, l^f1(r, c.masking[9], c.rotate[9])
|
||||
l, r = r, l^f2(r, c.masking[10], c.rotate[10])
|
||||
l, r = r, l^f3(r, c.masking[11], c.rotate[11])
|
||||
|
||||
l, r = r, l^f1(r, c.masking[12], c.rotate[12])
|
||||
l, r = r, l^f2(r, c.masking[13], c.rotate[13])
|
||||
l, r = r, l^f3(r, c.masking[14], c.rotate[14])
|
||||
l, r = r, l^f1(r, c.masking[15], c.rotate[15])
|
||||
|
||||
dst[0] = uint8(r >> 24)
|
||||
dst[1] = uint8(r >> 16)
|
||||
dst[2] = uint8(r >> 8)
|
||||
dst[3] = uint8(r)
|
||||
dst[4] = uint8(l >> 24)
|
||||
dst[5] = uint8(l >> 16)
|
||||
dst[6] = uint8(l >> 8)
|
||||
dst[7] = uint8(l)
|
||||
}
|
||||
|
||||
func (c *Cipher) Decrypt(dst, src []byte) {
|
||||
l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
|
||||
r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
|
||||
|
||||
l, r = r, l^f1(r, c.masking[15], c.rotate[15])
|
||||
l, r = r, l^f3(r, c.masking[14], c.rotate[14])
|
||||
l, r = r, l^f2(r, c.masking[13], c.rotate[13])
|
||||
l, r = r, l^f1(r, c.masking[12], c.rotate[12])
|
||||
|
||||
l, r = r, l^f3(r, c.masking[11], c.rotate[11])
|
||||
l, r = r, l^f2(r, c.masking[10], c.rotate[10])
|
||||
l, r = r, l^f1(r, c.masking[9], c.rotate[9])
|
||||
l, r = r, l^f3(r, c.masking[8], c.rotate[8])
|
||||
|
||||
l, r = r, l^f2(r, c.masking[7], c.rotate[7])
|
||||
l, r = r, l^f1(r, c.masking[6], c.rotate[6])
|
||||
l, r = r, l^f3(r, c.masking[5], c.rotate[5])
|
||||
l, r = r, l^f2(r, c.masking[4], c.rotate[4])
|
||||
|
||||
l, r = r, l^f1(r, c.masking[3], c.rotate[3])
|
||||
l, r = r, l^f3(r, c.masking[2], c.rotate[2])
|
||||
l, r = r, l^f2(r, c.masking[1], c.rotate[1])
|
||||
l, r = r, l^f1(r, c.masking[0], c.rotate[0])
|
||||
|
||||
dst[0] = uint8(r >> 24)
|
||||
dst[1] = uint8(r >> 16)
|
||||
dst[2] = uint8(r >> 8)
|
||||
dst[3] = uint8(r)
|
||||
dst[4] = uint8(l >> 24)
|
||||
dst[5] = uint8(l >> 16)
|
||||
dst[6] = uint8(l >> 8)
|
||||
dst[7] = uint8(l)
|
||||
}
|
||||
|
||||
type keyScheduleA [4][7]uint8
|
||||
type keyScheduleB [4][5]uint8
|
||||
|
||||
// keyScheduleRound contains the magic values for a round of the key schedule.
|
||||
// The keyScheduleA deals with the lines like:
|
||||
// z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8]
|
||||
// Conceptually, both x and z are in the same array, x first. The first
|
||||
// element describes which word of this array gets written to and the
|
||||
// second, which word gets read. So, for the line above, it's "4, 0", because
|
||||
// it's writing to the first word of z, which, being after x, is word 4, and
|
||||
// reading from the first word of x: word 0.
|
||||
//
|
||||
// Next are the indexes into the S-boxes. Now the array is treated as bytes. So
|
||||
// "xD" is 0xd. The first byte of z is written as "16 + 0", just to be clear
|
||||
// that it's z that we're indexing.
|
||||
//
|
||||
// keyScheduleB deals with lines like:
|
||||
// K1 = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2]
|
||||
// "K1" is ignored because key words are always written in order. So the five
|
||||
// elements are the S-box indexes. They use the same form as in keyScheduleA,
|
||||
// above.
|
||||
|
||||
type keyScheduleRound struct{}
|
||||
type keySchedule []keyScheduleRound
|
||||
|
||||
var schedule = []struct {
|
||||
a keyScheduleA
|
||||
b keyScheduleB
|
||||
}{
|
||||
{
|
||||
keyScheduleA{
|
||||
{4, 0, 0xd, 0xf, 0xc, 0xe, 0x8},
|
||||
{5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa},
|
||||
{6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9},
|
||||
{7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb},
|
||||
},
|
||||
keyScheduleB{
|
||||
{16 + 8, 16 + 9, 16 + 7, 16 + 6, 16 + 2},
|
||||
{16 + 0xa, 16 + 0xb, 16 + 5, 16 + 4, 16 + 6},
|
||||
{16 + 0xc, 16 + 0xd, 16 + 3, 16 + 2, 16 + 9},
|
||||
{16 + 0xe, 16 + 0xf, 16 + 1, 16 + 0, 16 + 0xc},
|
||||
},
|
||||
},
|
||||
{
|
||||
keyScheduleA{
|
||||
{0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0},
|
||||
{1, 4, 0, 2, 1, 3, 16 + 2},
|
||||
{2, 5, 7, 6, 5, 4, 16 + 1},
|
||||
{3, 7, 0xa, 9, 0xb, 8, 16 + 3},
|
||||
},
|
||||
keyScheduleB{
|
||||
{3, 2, 0xc, 0xd, 8},
|
||||
{1, 0, 0xe, 0xf, 0xd},
|
||||
{7, 6, 8, 9, 3},
|
||||
{5, 4, 0xa, 0xb, 7},
|
||||
},
|
||||
},
|
||||
{
|
||||
keyScheduleA{
|
||||
{4, 0, 0xd, 0xf, 0xc, 0xe, 8},
|
||||
{5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa},
|
||||
{6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9},
|
||||
{7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb},
|
||||
},
|
||||
keyScheduleB{
|
||||
{16 + 3, 16 + 2, 16 + 0xc, 16 + 0xd, 16 + 9},
|
||||
{16 + 1, 16 + 0, 16 + 0xe, 16 + 0xf, 16 + 0xc},
|
||||
{16 + 7, 16 + 6, 16 + 8, 16 + 9, 16 + 2},
|
||||
{16 + 5, 16 + 4, 16 + 0xa, 16 + 0xb, 16 + 6},
|
||||
},
|
||||
},
|
||||
{
|
||||
keyScheduleA{
|
||||
{0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0},
|
||||
{1, 4, 0, 2, 1, 3, 16 + 2},
|
||||
{2, 5, 7, 6, 5, 4, 16 + 1},
|
||||
{3, 7, 0xa, 9, 0xb, 8, 16 + 3},
|
||||
},
|
||||
keyScheduleB{
|
||||
{8, 9, 7, 6, 3},
|
||||
{0xa, 0xb, 5, 4, 7},
|
||||
{0xc, 0xd, 3, 2, 8},
|
||||
{0xe, 0xf, 1, 0, 0xd},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func (c *Cipher) keySchedule(in []byte) {
|
||||
var t [8]uint32
|
||||
var k [32]uint32
|
||||
|
||||
for i := 0; i < 4; i++ {
|
||||
j := i * 4
|
||||
t[i] = uint32(in[j])<<24 | uint32(in[j+1])<<16 | uint32(in[j+2])<<8 | uint32(in[j+3])
|
||||
}
|
||||
|
||||
x := []byte{6, 7, 4, 5}
|
||||
ki := 0
|
||||
|
||||
for half := 0; half < 2; half++ {
|
||||
for _, round := range schedule {
|
||||
for j := 0; j < 4; j++ {
|
||||
var a [7]uint8
|
||||
copy(a[:], round.a[j][:])
|
||||
w := t[a[1]]
|
||||
w ^= sBox[4][(t[a[2]>>2]>>(24-8*(a[2]&3)))&0xff]
|
||||
w ^= sBox[5][(t[a[3]>>2]>>(24-8*(a[3]&3)))&0xff]
|
||||
w ^= sBox[6][(t[a[4]>>2]>>(24-8*(a[4]&3)))&0xff]
|
||||
w ^= sBox[7][(t[a[5]>>2]>>(24-8*(a[5]&3)))&0xff]
|
||||
w ^= sBox[x[j]][(t[a[6]>>2]>>(24-8*(a[6]&3)))&0xff]
|
||||
t[a[0]] = w
|
||||
}
|
||||
|
||||
for j := 0; j < 4; j++ {
|
||||
var b [5]uint8
|
||||
copy(b[:], round.b[j][:])
|
||||
w := sBox[4][(t[b[0]>>2]>>(24-8*(b[0]&3)))&0xff]
|
||||
w ^= sBox[5][(t[b[1]>>2]>>(24-8*(b[1]&3)))&0xff]
|
||||
w ^= sBox[6][(t[b[2]>>2]>>(24-8*(b[2]&3)))&0xff]
|
||||
w ^= sBox[7][(t[b[3]>>2]>>(24-8*(b[3]&3)))&0xff]
|
||||
w ^= sBox[4+j][(t[b[4]>>2]>>(24-8*(b[4]&3)))&0xff]
|
||||
k[ki] = w
|
||||
ki++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < 16; i++ {
|
||||
c.masking[i] = k[i]
|
||||
c.rotate[i] = uint8(k[16+i] & 0x1f)
|
||||
}
|
||||
}
|
||||
|
||||
// These are the three 'f' functions. See RFC 2144, section 2.2.
|
||||
func f1(d, m uint32, r uint8) uint32 {
|
||||
t := m + d
|
||||
I := (t << r) | (t >> (32 - r))
|
||||
return ((sBox[0][I>>24] ^ sBox[1][(I>>16)&0xff]) - sBox[2][(I>>8)&0xff]) + sBox[3][I&0xff]
|
||||
}
|
||||
|
||||
func f2(d, m uint32, r uint8) uint32 {
|
||||
t := m ^ d
|
||||
I := (t << r) | (t >> (32 - r))
|
||||
return ((sBox[0][I>>24] - sBox[1][(I>>16)&0xff]) + sBox[2][(I>>8)&0xff]) ^ sBox[3][I&0xff]
|
||||
}
|
||||
|
||||
func f3(d, m uint32, r uint8) uint32 {
|
||||
t := m - d
|
||||
I := (t << r) | (t >> (32 - r))
|
||||
return ((sBox[0][I>>24] + sBox[1][(I>>16)&0xff]) ^ sBox[2][(I>>8)&0xff]) - sBox[3][I&0xff]
|
||||
}
|
||||
|
||||
var sBox = [8][256]uint32{
|
||||
{
|
||||
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
|
||||
0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
|
||||
0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
|
||||
0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
|
||||
0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
|
||||
0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
|
||||
0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
|
||||
0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
|
||||
0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
|
||||
0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
|
||||
0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
|
||||
0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
|
||||
0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
|
||||
0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
|
||||
0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
|
||||
0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
|
||||
0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
|
||||
0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
|
||||
0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
|
||||
0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
|
||||
0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
|
||||
0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
|
||||
0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
|
||||
0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
|
||||
0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
|
||||
0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
|
||||
0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
|
||||
0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
|
||||
0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
|
||||
0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
|
||||
0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
|
||||
0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf,
|
||||
},
|
||||
{
|
||||
0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
|
||||
0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
|
||||
0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
|
||||
0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
|
||||
0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
|
||||
0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
|
||||
0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
|
||||
0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
|
||||
0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
|
||||
0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
|
||||
0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
|
||||
0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
|
||||
0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
|
||||
0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
|
||||
0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
|
||||
0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
|
||||
0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
|
||||
0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
|
||||
0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
|
||||
0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
|
||||
0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
|
||||
0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
|
||||
0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
|
||||
0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
|
||||
0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
|
||||
0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
|
||||
0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
|
||||
0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
|
||||
0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
|
||||
0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
|
||||
0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
|
||||
0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1,
|
||||
},
|
||||
{
|
||||
0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
|
||||
0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
|
||||
0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
|
||||
0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
|
||||
0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
|
||||
0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
|
||||
0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
|
||||
0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
|
||||
0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
|
||||
0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
|
||||
0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
|
||||
0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
|
||||
0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
|
||||
0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
|
||||
0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
|
||||
0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
|
||||
0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
|
||||
0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
|
||||
0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
|
||||
0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
|
||||
0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
|
||||
0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
|
||||
0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
|
||||
0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
|
||||
0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
|
||||
0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
|
||||
0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
|
||||
0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
|
||||
0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
|
||||
0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
|
||||
0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
|
||||
0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783,
|
||||
},
|
||||
{
|
||||
0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
|
||||
0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
|
||||
0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
|
||||
0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
|
||||
0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
|
||||
0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
|
||||
0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
|
||||
0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
|
||||
0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
|
||||
0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
|
||||
0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
|
||||
0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
|
||||
0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
|
||||
0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
|
||||
0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
|
||||
0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
|
||||
0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
|
||||
0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
|
||||
0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
|
||||
0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
|
||||
0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
|
||||
0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
|
||||
0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
|
||||
0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
|
||||
0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
|
||||
0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
|
||||
0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
|
||||
0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
|
||||
0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
|
||||
0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
|
||||
0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
|
||||
0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2,
|
||||
},
|
||||
{
|
||||
0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
|
||||
0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
|
||||
0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
|
||||
0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
|
||||
0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
|
||||
0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
|
||||
0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
|
||||
0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
|
||||
0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
|
||||
0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
|
||||
0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
|
||||
0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
|
||||
0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
|
||||
0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
|
||||
0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
|
||||
0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
|
||||
0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
|
||||
0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
|
||||
0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
|
||||
0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
|
||||
0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
|
||||
0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
|
||||
0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
|
||||
0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
|
||||
0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
|
||||
0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
|
||||
0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
|
||||
0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
|
||||
0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
|
||||
0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
|
||||
0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
|
||||
0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4,
|
||||
},
|
||||
{
|
||||
0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
|
||||
0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
|
||||
0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
|
||||
0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
|
||||
0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
|
||||
0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
|
||||
0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
|
||||
0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
|
||||
0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
|
||||
0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
|
||||
0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
|
||||
0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
|
||||
0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
|
||||
0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
|
||||
0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
|
||||
0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
|
||||
0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
|
||||
0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
|
||||
0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
|
||||
0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
|
||||
0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
|
||||
0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
|
||||
0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
|
||||
0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
|
||||
0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
|
||||
0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
|
||||
0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
|
||||
0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
|
||||
0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
|
||||
0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
|
||||
0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
|
||||
0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f,
|
||||
},
|
||||
{
|
||||
0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
|
||||
0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
|
||||
0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
|
||||
0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
|
||||
0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
|
||||
0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
|
||||
0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
|
||||
0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
|
||||
0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
|
||||
0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
|
||||
0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
|
||||
0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
|
||||
0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
|
||||
0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
|
||||
0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
|
||||
0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
|
||||
0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
|
||||
0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
|
||||
0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
|
||||
0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
|
||||
0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
|
||||
0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
|
||||
0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
|
||||
0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
|
||||
0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
|
||||
0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
|
||||
0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
|
||||
0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
|
||||
0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
|
||||
0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
|
||||
0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
|
||||
0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3,
|
||||
},
|
||||
{
|
||||
0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
|
||||
0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
|
||||
0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
|
||||
0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
|
||||
0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
|
||||
0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
|
||||
0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
|
||||
0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
|
||||
0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
|
||||
0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
|
||||
0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
|
||||
0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
|
||||
0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
|
||||
0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
|
||||
0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
|
||||
0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
|
||||
0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
|
||||
0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
|
||||
0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
|
||||
0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
|
||||
0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
|
||||
0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
|
||||
0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
|
||||
0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
|
||||
0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
|
||||
0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
|
||||
0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
|
||||
0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
|
||||
0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
|
||||
0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
|
||||
0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
|
||||
0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e,
|
||||
},
|
||||
}
|
||||
106
vendor/golang.org/x/crypto/cast5/cast5_test.go
generated
vendored
Normal file
106
vendor/golang.org/x/crypto/cast5/cast5_test.go
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package cast5
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// This test vector is taken from RFC 2144, App B.1.
|
||||
// Since the other two test vectors are for reduced-round variants, we can't
|
||||
// use them.
|
||||
var basicTests = []struct {
|
||||
key, plainText, cipherText string
|
||||
}{
|
||||
{
|
||||
"0123456712345678234567893456789a",
|
||||
"0123456789abcdef",
|
||||
"238b4fe5847e44b2",
|
||||
},
|
||||
}
|
||||
|
||||
func TestBasic(t *testing.T) {
|
||||
for i, test := range basicTests {
|
||||
key, _ := hex.DecodeString(test.key)
|
||||
plainText, _ := hex.DecodeString(test.plainText)
|
||||
expected, _ := hex.DecodeString(test.cipherText)
|
||||
|
||||
c, err := NewCipher(key)
|
||||
if err != nil {
|
||||
t.Errorf("#%d: failed to create Cipher: %s", i, err)
|
||||
continue
|
||||
}
|
||||
var cipherText [BlockSize]byte
|
||||
c.Encrypt(cipherText[:], plainText)
|
||||
if !bytes.Equal(cipherText[:], expected) {
|
||||
t.Errorf("#%d: got:%x want:%x", i, cipherText, expected)
|
||||
}
|
||||
|
||||
var plainTextAgain [BlockSize]byte
|
||||
c.Decrypt(plainTextAgain[:], cipherText[:])
|
||||
if !bytes.Equal(plainTextAgain[:], plainText) {
|
||||
t.Errorf("#%d: got:%x want:%x", i, plainTextAgain, plainText)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestFull performs the test specified in RFC 2144, App B.2.
|
||||
// However, due to the length of time taken, it's disabled here and a more
|
||||
// limited version is included, below.
|
||||
func TestFull(t *testing.T) {
|
||||
if testing.Short() {
|
||||
// This is too slow for normal testing
|
||||
return
|
||||
}
|
||||
|
||||
a, b := iterate(1000000)
|
||||
|
||||
const expectedA = "eea9d0a249fd3ba6b3436fb89d6dca92"
|
||||
const expectedB = "b2c95eb00c31ad7180ac05b8e83d696e"
|
||||
|
||||
if hex.EncodeToString(a) != expectedA {
|
||||
t.Errorf("a: got:%x want:%s", a, expectedA)
|
||||
}
|
||||
if hex.EncodeToString(b) != expectedB {
|
||||
t.Errorf("b: got:%x want:%s", b, expectedB)
|
||||
}
|
||||
}
|
||||
|
||||
func iterate(iterations int) ([]byte, []byte) {
|
||||
const initValueHex = "0123456712345678234567893456789a"
|
||||
|
||||
initValue, _ := hex.DecodeString(initValueHex)
|
||||
|
||||
var a, b [16]byte
|
||||
copy(a[:], initValue)
|
||||
copy(b[:], initValue)
|
||||
|
||||
for i := 0; i < iterations; i++ {
|
||||
c, _ := NewCipher(b[:])
|
||||
c.Encrypt(a[:8], a[:8])
|
||||
c.Encrypt(a[8:], a[8:])
|
||||
c, _ = NewCipher(a[:])
|
||||
c.Encrypt(b[:8], b[:8])
|
||||
c.Encrypt(b[8:], b[8:])
|
||||
}
|
||||
|
||||
return a[:], b[:]
|
||||
}
|
||||
|
||||
func TestLimited(t *testing.T) {
|
||||
a, b := iterate(1000)
|
||||
|
||||
const expectedA = "23f73b14b02a2ad7dfb9f2c35644798d"
|
||||
const expectedB = "e5bf37eff14c456a40b21ce369370a9f"
|
||||
|
||||
if hex.EncodeToString(a) != expectedA {
|
||||
t.Errorf("a: got:%x want:%s", a, expectedA)
|
||||
}
|
||||
if hex.EncodeToString(b) != expectedB {
|
||||
t.Errorf("b: got:%x want:%s", b, expectedB)
|
||||
}
|
||||
}
|
||||
77
vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
generated
vendored
Normal file
77
vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package pbkdf2 implements the key derivation function PBKDF2 as defined in RFC
|
||||
2898 / PKCS #5 v2.0.
|
||||
|
||||
A key derivation function is useful when encrypting data based on a password
|
||||
or any other not-fully-random data. It uses a pseudorandom function to derive
|
||||
a secure encryption key based on the password.
|
||||
|
||||
While v2.0 of the standard defines only one pseudorandom function to use,
|
||||
HMAC-SHA1, the drafted v2.1 specification allows use of all five FIPS Approved
|
||||
Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To
|
||||
choose, you can pass the `New` functions from the different SHA packages to
|
||||
pbkdf2.Key.
|
||||
*/
|
||||
package pbkdf2 // import "golang.org/x/crypto/pbkdf2"
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"hash"
|
||||
)
|
||||
|
||||
// Key derives a key from the password, salt and iteration count, returning a
|
||||
// []byte of length keylen that can be used as cryptographic key. The key is
|
||||
// derived based on the method described as PBKDF2 with the HMAC variant using
|
||||
// the supplied hash function.
|
||||
//
|
||||
// For example, to use a HMAC-SHA-1 based PBKDF2 key derivation function, you
|
||||
// can get a derived key for e.g. AES-256 (which needs a 32-byte key) by
|
||||
// doing:
|
||||
//
|
||||
// dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New)
|
||||
//
|
||||
// Remember to get a good random salt. At least 8 bytes is recommended by the
|
||||
// RFC.
|
||||
//
|
||||
// Using a higher iteration count will increase the cost of an exhaustive
|
||||
// search but will also make derivation proportionally slower.
|
||||
func Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
|
||||
prf := hmac.New(h, password)
|
||||
hashLen := prf.Size()
|
||||
numBlocks := (keyLen + hashLen - 1) / hashLen
|
||||
|
||||
var buf [4]byte
|
||||
dk := make([]byte, 0, numBlocks*hashLen)
|
||||
U := make([]byte, hashLen)
|
||||
for block := 1; block <= numBlocks; block++ {
|
||||
// N.B.: || means concatenation, ^ means XOR
|
||||
// for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
|
||||
// U_1 = PRF(password, salt || uint(i))
|
||||
prf.Reset()
|
||||
prf.Write(salt)
|
||||
buf[0] = byte(block >> 24)
|
||||
buf[1] = byte(block >> 16)
|
||||
buf[2] = byte(block >> 8)
|
||||
buf[3] = byte(block)
|
||||
prf.Write(buf[:4])
|
||||
dk = prf.Sum(dk)
|
||||
T := dk[len(dk)-hashLen:]
|
||||
copy(U, T)
|
||||
|
||||
// U_n = PRF(password, U_(n-1))
|
||||
for n := 2; n <= iter; n++ {
|
||||
prf.Reset()
|
||||
prf.Write(U)
|
||||
U = U[:0]
|
||||
U = prf.Sum(U)
|
||||
for x := range U {
|
||||
T[x] ^= U[x]
|
||||
}
|
||||
}
|
||||
}
|
||||
return dk[:keyLen]
|
||||
}
|
||||
157
vendor/golang.org/x/crypto/pbkdf2/pbkdf2_test.go
generated
vendored
Normal file
157
vendor/golang.org/x/crypto/pbkdf2/pbkdf2_test.go
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package pbkdf2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"hash"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testVector struct {
|
||||
password string
|
||||
salt string
|
||||
iter int
|
||||
output []byte
|
||||
}
|
||||
|
||||
// Test vectors from RFC 6070, http://tools.ietf.org/html/rfc6070
|
||||
var sha1TestVectors = []testVector{
|
||||
{
|
||||
"password",
|
||||
"salt",
|
||||
1,
|
||||
[]byte{
|
||||
0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
|
||||
0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
|
||||
0x2f, 0xe0, 0x37, 0xa6,
|
||||
},
|
||||
},
|
||||
{
|
||||
"password",
|
||||
"salt",
|
||||
2,
|
||||
[]byte{
|
||||
0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c,
|
||||
0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0,
|
||||
0xd8, 0xde, 0x89, 0x57,
|
||||
},
|
||||
},
|
||||
{
|
||||
"password",
|
||||
"salt",
|
||||
4096,
|
||||
[]byte{
|
||||
0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a,
|
||||
0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0,
|
||||
0x65, 0xa4, 0x29, 0xc1,
|
||||
},
|
||||
},
|
||||
// // This one takes too long
|
||||
// {
|
||||
// "password",
|
||||
// "salt",
|
||||
// 16777216,
|
||||
// []byte{
|
||||
// 0xee, 0xfe, 0x3d, 0x61, 0xcd, 0x4d, 0xa4, 0xe4,
|
||||
// 0xe9, 0x94, 0x5b, 0x3d, 0x6b, 0xa2, 0x15, 0x8c,
|
||||
// 0x26, 0x34, 0xe9, 0x84,
|
||||
// },
|
||||
// },
|
||||
{
|
||||
"passwordPASSWORDpassword",
|
||||
"saltSALTsaltSALTsaltSALTsaltSALTsalt",
|
||||
4096,
|
||||
[]byte{
|
||||
0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b,
|
||||
0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a,
|
||||
0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70,
|
||||
0x38,
|
||||
},
|
||||
},
|
||||
{
|
||||
"pass\000word",
|
||||
"sa\000lt",
|
||||
4096,
|
||||
[]byte{
|
||||
0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
|
||||
0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Test vectors from
|
||||
// http://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors
|
||||
var sha256TestVectors = []testVector{
|
||||
{
|
||||
"password",
|
||||
"salt",
|
||||
1,
|
||||
[]byte{
|
||||
0x12, 0x0f, 0xb6, 0xcf, 0xfc, 0xf8, 0xb3, 0x2c,
|
||||
0x43, 0xe7, 0x22, 0x52, 0x56, 0xc4, 0xf8, 0x37,
|
||||
0xa8, 0x65, 0x48, 0xc9,
|
||||
},
|
||||
},
|
||||
{
|
||||
"password",
|
||||
"salt",
|
||||
2,
|
||||
[]byte{
|
||||
0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3,
|
||||
0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0,
|
||||
0x2a, 0x30, 0x3f, 0x8e,
|
||||
},
|
||||
},
|
||||
{
|
||||
"password",
|
||||
"salt",
|
||||
4096,
|
||||
[]byte{
|
||||
0xc5, 0xe4, 0x78, 0xd5, 0x92, 0x88, 0xc8, 0x41,
|
||||
0xaa, 0x53, 0x0d, 0xb6, 0x84, 0x5c, 0x4c, 0x8d,
|
||||
0x96, 0x28, 0x93, 0xa0,
|
||||
},
|
||||
},
|
||||
{
|
||||
"passwordPASSWORDpassword",
|
||||
"saltSALTsaltSALTsaltSALTsaltSALTsalt",
|
||||
4096,
|
||||
[]byte{
|
||||
0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f,
|
||||
0x32, 0xd8, 0x14, 0xb8, 0x11, 0x6e, 0x84, 0xcf,
|
||||
0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18,
|
||||
0x1c,
|
||||
},
|
||||
},
|
||||
{
|
||||
"pass\000word",
|
||||
"sa\000lt",
|
||||
4096,
|
||||
[]byte{
|
||||
0x89, 0xb6, 0x9d, 0x05, 0x16, 0xf8, 0x29, 0x89,
|
||||
0x3c, 0x69, 0x62, 0x26, 0x65, 0x0a, 0x86, 0x87,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func testHash(t *testing.T, h func() hash.Hash, hashName string, vectors []testVector) {
|
||||
for i, v := range vectors {
|
||||
o := Key([]byte(v.password), []byte(v.salt), v.iter, len(v.output), h)
|
||||
if !bytes.Equal(o, v.output) {
|
||||
t.Errorf("%s %d: expected %x, got %x", hashName, i, v.output, o)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithHMACSHA1(t *testing.T) {
|
||||
testHash(t, sha1.New, "SHA1", sha1TestVectors)
|
||||
}
|
||||
|
||||
func TestWithHMACSHA256(t *testing.T) {
|
||||
testHash(t, sha256.New, "SHA256", sha256TestVectors)
|
||||
}
|
||||
144
vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go
generated
vendored
Normal file
144
vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go
generated
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package salsa provides low-level access to functions in the Salsa family.
|
||||
package salsa // import "golang.org/x/crypto/salsa20/salsa"
|
||||
|
||||
// Sigma is the Salsa20 constant for 256-bit keys.
|
||||
var Sigma = [16]byte{'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', '2', '-', 'b', 'y', 't', 'e', ' ', 'k'}
|
||||
|
||||
// HSalsa20 applies the HSalsa20 core function to a 16-byte input in, 32-byte
|
||||
// key k, and 16-byte constant c, and puts the result into the 32-byte array
|
||||
// out.
|
||||
func HSalsa20(out *[32]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
|
||||
x0 := uint32(c[0]) | uint32(c[1])<<8 | uint32(c[2])<<16 | uint32(c[3])<<24
|
||||
x1 := uint32(k[0]) | uint32(k[1])<<8 | uint32(k[2])<<16 | uint32(k[3])<<24
|
||||
x2 := uint32(k[4]) | uint32(k[5])<<8 | uint32(k[6])<<16 | uint32(k[7])<<24
|
||||
x3 := uint32(k[8]) | uint32(k[9])<<8 | uint32(k[10])<<16 | uint32(k[11])<<24
|
||||
x4 := uint32(k[12]) | uint32(k[13])<<8 | uint32(k[14])<<16 | uint32(k[15])<<24
|
||||
x5 := uint32(c[4]) | uint32(c[5])<<8 | uint32(c[6])<<16 | uint32(c[7])<<24
|
||||
x6 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24
|
||||
x7 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24
|
||||
x8 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24
|
||||
x9 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24
|
||||
x10 := uint32(c[8]) | uint32(c[9])<<8 | uint32(c[10])<<16 | uint32(c[11])<<24
|
||||
x11 := uint32(k[16]) | uint32(k[17])<<8 | uint32(k[18])<<16 | uint32(k[19])<<24
|
||||
x12 := uint32(k[20]) | uint32(k[21])<<8 | uint32(k[22])<<16 | uint32(k[23])<<24
|
||||
x13 := uint32(k[24]) | uint32(k[25])<<8 | uint32(k[26])<<16 | uint32(k[27])<<24
|
||||
x14 := uint32(k[28]) | uint32(k[29])<<8 | uint32(k[30])<<16 | uint32(k[31])<<24
|
||||
x15 := uint32(c[12]) | uint32(c[13])<<8 | uint32(c[14])<<16 | uint32(c[15])<<24
|
||||
|
||||
for i := 0; i < 20; i += 2 {
|
||||
u := x0 + x12
|
||||
x4 ^= u<<7 | u>>(32-7)
|
||||
u = x4 + x0
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
u = x8 + x4
|
||||
x12 ^= u<<13 | u>>(32-13)
|
||||
u = x12 + x8
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x5 + x1
|
||||
x9 ^= u<<7 | u>>(32-7)
|
||||
u = x9 + x5
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
u = x13 + x9
|
||||
x1 ^= u<<13 | u>>(32-13)
|
||||
u = x1 + x13
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x10 + x6
|
||||
x14 ^= u<<7 | u>>(32-7)
|
||||
u = x14 + x10
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
u = x2 + x14
|
||||
x6 ^= u<<13 | u>>(32-13)
|
||||
u = x6 + x2
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x15 + x11
|
||||
x3 ^= u<<7 | u>>(32-7)
|
||||
u = x3 + x15
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
u = x7 + x3
|
||||
x11 ^= u<<13 | u>>(32-13)
|
||||
u = x11 + x7
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x0 + x3
|
||||
x1 ^= u<<7 | u>>(32-7)
|
||||
u = x1 + x0
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
u = x2 + x1
|
||||
x3 ^= u<<13 | u>>(32-13)
|
||||
u = x3 + x2
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x5 + x4
|
||||
x6 ^= u<<7 | u>>(32-7)
|
||||
u = x6 + x5
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
u = x7 + x6
|
||||
x4 ^= u<<13 | u>>(32-13)
|
||||
u = x4 + x7
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x10 + x9
|
||||
x11 ^= u<<7 | u>>(32-7)
|
||||
u = x11 + x10
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
u = x8 + x11
|
||||
x9 ^= u<<13 | u>>(32-13)
|
||||
u = x9 + x8
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x15 + x14
|
||||
x12 ^= u<<7 | u>>(32-7)
|
||||
u = x12 + x15
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
u = x13 + x12
|
||||
x14 ^= u<<13 | u>>(32-13)
|
||||
u = x14 + x13
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
}
|
||||
out[0] = byte(x0)
|
||||
out[1] = byte(x0 >> 8)
|
||||
out[2] = byte(x0 >> 16)
|
||||
out[3] = byte(x0 >> 24)
|
||||
|
||||
out[4] = byte(x5)
|
||||
out[5] = byte(x5 >> 8)
|
||||
out[6] = byte(x5 >> 16)
|
||||
out[7] = byte(x5 >> 24)
|
||||
|
||||
out[8] = byte(x10)
|
||||
out[9] = byte(x10 >> 8)
|
||||
out[10] = byte(x10 >> 16)
|
||||
out[11] = byte(x10 >> 24)
|
||||
|
||||
out[12] = byte(x15)
|
||||
out[13] = byte(x15 >> 8)
|
||||
out[14] = byte(x15 >> 16)
|
||||
out[15] = byte(x15 >> 24)
|
||||
|
||||
out[16] = byte(x6)
|
||||
out[17] = byte(x6 >> 8)
|
||||
out[18] = byte(x6 >> 16)
|
||||
out[19] = byte(x6 >> 24)
|
||||
|
||||
out[20] = byte(x7)
|
||||
out[21] = byte(x7 >> 8)
|
||||
out[22] = byte(x7 >> 16)
|
||||
out[23] = byte(x7 >> 24)
|
||||
|
||||
out[24] = byte(x8)
|
||||
out[25] = byte(x8 >> 8)
|
||||
out[26] = byte(x8 >> 16)
|
||||
out[27] = byte(x8 >> 24)
|
||||
|
||||
out[28] = byte(x9)
|
||||
out[29] = byte(x9 >> 8)
|
||||
out[30] = byte(x9 >> 16)
|
||||
out[31] = byte(x9 >> 24)
|
||||
}
|
||||
889
vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s
generated
vendored
Normal file
889
vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,889 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build amd64,!appengine,!gccgo
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||
|
||||
// func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
|
||||
// This needs up to 64 bytes at 360(SP); hence the non-obvious frame size.
|
||||
TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
|
||||
MOVQ out+0(FP),DI
|
||||
MOVQ in+8(FP),SI
|
||||
MOVQ n+16(FP),DX
|
||||
MOVQ nonce+24(FP),CX
|
||||
MOVQ key+32(FP),R8
|
||||
|
||||
MOVQ SP,R12
|
||||
MOVQ SP,R9
|
||||
ADDQ $31, R9
|
||||
ANDQ $~31, R9
|
||||
MOVQ R9, SP
|
||||
|
||||
MOVQ DX,R9
|
||||
MOVQ CX,DX
|
||||
MOVQ R8,R10
|
||||
CMPQ R9,$0
|
||||
JBE DONE
|
||||
START:
|
||||
MOVL 20(R10),CX
|
||||
MOVL 0(R10),R8
|
||||
MOVL 0(DX),AX
|
||||
MOVL 16(R10),R11
|
||||
MOVL CX,0(SP)
|
||||
MOVL R8, 4 (SP)
|
||||
MOVL AX, 8 (SP)
|
||||
MOVL R11, 12 (SP)
|
||||
MOVL 8(DX),CX
|
||||
MOVL 24(R10),R8
|
||||
MOVL 4(R10),AX
|
||||
MOVL 4(DX),R11
|
||||
MOVL CX,16(SP)
|
||||
MOVL R8, 20 (SP)
|
||||
MOVL AX, 24 (SP)
|
||||
MOVL R11, 28 (SP)
|
||||
MOVL 12(DX),CX
|
||||
MOVL 12(R10),DX
|
||||
MOVL 28(R10),R8
|
||||
MOVL 8(R10),AX
|
||||
MOVL DX,32(SP)
|
||||
MOVL CX, 36 (SP)
|
||||
MOVL R8, 40 (SP)
|
||||
MOVL AX, 44 (SP)
|
||||
MOVQ $1634760805,DX
|
||||
MOVQ $857760878,CX
|
||||
MOVQ $2036477234,R8
|
||||
MOVQ $1797285236,AX
|
||||
MOVL DX,48(SP)
|
||||
MOVL CX, 52 (SP)
|
||||
MOVL R8, 56 (SP)
|
||||
MOVL AX, 60 (SP)
|
||||
CMPQ R9,$256
|
||||
JB BYTESBETWEEN1AND255
|
||||
MOVOA 48(SP),X0
|
||||
PSHUFL $0X55,X0,X1
|
||||
PSHUFL $0XAA,X0,X2
|
||||
PSHUFL $0XFF,X0,X3
|
||||
PSHUFL $0X00,X0,X0
|
||||
MOVOA X1,64(SP)
|
||||
MOVOA X2,80(SP)
|
||||
MOVOA X3,96(SP)
|
||||
MOVOA X0,112(SP)
|
||||
MOVOA 0(SP),X0
|
||||
PSHUFL $0XAA,X0,X1
|
||||
PSHUFL $0XFF,X0,X2
|
||||
PSHUFL $0X00,X0,X3
|
||||
PSHUFL $0X55,X0,X0
|
||||
MOVOA X1,128(SP)
|
||||
MOVOA X2,144(SP)
|
||||
MOVOA X3,160(SP)
|
||||
MOVOA X0,176(SP)
|
||||
MOVOA 16(SP),X0
|
||||
PSHUFL $0XFF,X0,X1
|
||||
PSHUFL $0X55,X0,X2
|
||||
PSHUFL $0XAA,X0,X0
|
||||
MOVOA X1,192(SP)
|
||||
MOVOA X2,208(SP)
|
||||
MOVOA X0,224(SP)
|
||||
MOVOA 32(SP),X0
|
||||
PSHUFL $0X00,X0,X1
|
||||
PSHUFL $0XAA,X0,X2
|
||||
PSHUFL $0XFF,X0,X0
|
||||
MOVOA X1,240(SP)
|
||||
MOVOA X2,256(SP)
|
||||
MOVOA X0,272(SP)
|
||||
BYTESATLEAST256:
|
||||
MOVL 16(SP),DX
|
||||
MOVL 36 (SP),CX
|
||||
MOVL DX,288(SP)
|
||||
MOVL CX,304(SP)
|
||||
ADDQ $1,DX
|
||||
SHLQ $32,CX
|
||||
ADDQ CX,DX
|
||||
MOVQ DX,CX
|
||||
SHRQ $32,CX
|
||||
MOVL DX, 292 (SP)
|
||||
MOVL CX, 308 (SP)
|
||||
ADDQ $1,DX
|
||||
SHLQ $32,CX
|
||||
ADDQ CX,DX
|
||||
MOVQ DX,CX
|
||||
SHRQ $32,CX
|
||||
MOVL DX, 296 (SP)
|
||||
MOVL CX, 312 (SP)
|
||||
ADDQ $1,DX
|
||||
SHLQ $32,CX
|
||||
ADDQ CX,DX
|
||||
MOVQ DX,CX
|
||||
SHRQ $32,CX
|
||||
MOVL DX, 300 (SP)
|
||||
MOVL CX, 316 (SP)
|
||||
ADDQ $1,DX
|
||||
SHLQ $32,CX
|
||||
ADDQ CX,DX
|
||||
MOVQ DX,CX
|
||||
SHRQ $32,CX
|
||||
MOVL DX,16(SP)
|
||||
MOVL CX, 36 (SP)
|
||||
MOVQ R9,352(SP)
|
||||
MOVQ $20,DX
|
||||
MOVOA 64(SP),X0
|
||||
MOVOA 80(SP),X1
|
||||
MOVOA 96(SP),X2
|
||||
MOVOA 256(SP),X3
|
||||
MOVOA 272(SP),X4
|
||||
MOVOA 128(SP),X5
|
||||
MOVOA 144(SP),X6
|
||||
MOVOA 176(SP),X7
|
||||
MOVOA 192(SP),X8
|
||||
MOVOA 208(SP),X9
|
||||
MOVOA 224(SP),X10
|
||||
MOVOA 304(SP),X11
|
||||
MOVOA 112(SP),X12
|
||||
MOVOA 160(SP),X13
|
||||
MOVOA 240(SP),X14
|
||||
MOVOA 288(SP),X15
|
||||
MAINLOOP1:
|
||||
MOVOA X1,320(SP)
|
||||
MOVOA X2,336(SP)
|
||||
MOVOA X13,X1
|
||||
PADDL X12,X1
|
||||
MOVOA X1,X2
|
||||
PSLLL $7,X1
|
||||
PXOR X1,X14
|
||||
PSRLL $25,X2
|
||||
PXOR X2,X14
|
||||
MOVOA X7,X1
|
||||
PADDL X0,X1
|
||||
MOVOA X1,X2
|
||||
PSLLL $7,X1
|
||||
PXOR X1,X11
|
||||
PSRLL $25,X2
|
||||
PXOR X2,X11
|
||||
MOVOA X12,X1
|
||||
PADDL X14,X1
|
||||
MOVOA X1,X2
|
||||
PSLLL $9,X1
|
||||
PXOR X1,X15
|
||||
PSRLL $23,X2
|
||||
PXOR X2,X15
|
||||
MOVOA X0,X1
|
||||
PADDL X11,X1
|
||||
MOVOA X1,X2
|
||||
PSLLL $9,X1
|
||||
PXOR X1,X9
|
||||
PSRLL $23,X2
|
||||
PXOR X2,X9
|
||||
MOVOA X14,X1
|
||||
PADDL X15,X1
|
||||
MOVOA X1,X2
|
||||
PSLLL $13,X1
|
||||
PXOR X1,X13
|
||||
PSRLL $19,X2
|
||||
PXOR X2,X13
|
||||
MOVOA X11,X1
|
||||
PADDL X9,X1
|
||||
MOVOA X1,X2
|
||||
PSLLL $13,X1
|
||||
PXOR X1,X7
|
||||
PSRLL $19,X2
|
||||
PXOR X2,X7
|
||||
MOVOA X15,X1
|
||||
PADDL X13,X1
|
||||
MOVOA X1,X2
|
||||
PSLLL $18,X1
|
||||
PXOR X1,X12
|
||||
PSRLL $14,X2
|
||||
PXOR X2,X12
|
||||
MOVOA 320(SP),X1
|
||||
MOVOA X12,320(SP)
|
||||
MOVOA X9,X2
|
||||
PADDL X7,X2
|
||||
MOVOA X2,X12
|
||||
PSLLL $18,X2
|
||||
PXOR X2,X0
|
||||
PSRLL $14,X12
|
||||
PXOR X12,X0
|
||||
MOVOA X5,X2
|
||||
PADDL X1,X2
|
||||
MOVOA X2,X12
|
||||
PSLLL $7,X2
|
||||
PXOR X2,X3
|
||||
PSRLL $25,X12
|
||||
PXOR X12,X3
|
||||
MOVOA 336(SP),X2
|
||||
MOVOA X0,336(SP)
|
||||
MOVOA X6,X0
|
||||
PADDL X2,X0
|
||||
MOVOA X0,X12
|
||||
PSLLL $7,X0
|
||||
PXOR X0,X4
|
||||
PSRLL $25,X12
|
||||
PXOR X12,X4
|
||||
MOVOA X1,X0
|
||||
PADDL X3,X0
|
||||
MOVOA X0,X12
|
||||
PSLLL $9,X0
|
||||
PXOR X0,X10
|
||||
PSRLL $23,X12
|
||||
PXOR X12,X10
|
||||
MOVOA X2,X0
|
||||
PADDL X4,X0
|
||||
MOVOA X0,X12
|
||||
PSLLL $9,X0
|
||||
PXOR X0,X8
|
||||
PSRLL $23,X12
|
||||
PXOR X12,X8
|
||||
MOVOA X3,X0
|
||||
PADDL X10,X0
|
||||
MOVOA X0,X12
|
||||
PSLLL $13,X0
|
||||
PXOR X0,X5
|
||||
PSRLL $19,X12
|
||||
PXOR X12,X5
|
||||
MOVOA X4,X0
|
||||
PADDL X8,X0
|
||||
MOVOA X0,X12
|
||||
PSLLL $13,X0
|
||||
PXOR X0,X6
|
||||
PSRLL $19,X12
|
||||
PXOR X12,X6
|
||||
MOVOA X10,X0
|
||||
PADDL X5,X0
|
||||
MOVOA X0,X12
|
||||
PSLLL $18,X0
|
||||
PXOR X0,X1
|
||||
PSRLL $14,X12
|
||||
PXOR X12,X1
|
||||
MOVOA 320(SP),X0
|
||||
MOVOA X1,320(SP)
|
||||
MOVOA X4,X1
|
||||
PADDL X0,X1
|
||||
MOVOA X1,X12
|
||||
PSLLL $7,X1
|
||||
PXOR X1,X7
|
||||
PSRLL $25,X12
|
||||
PXOR X12,X7
|
||||
MOVOA X8,X1
|
||||
PADDL X6,X1
|
||||
MOVOA X1,X12
|
||||
PSLLL $18,X1
|
||||
PXOR X1,X2
|
||||
PSRLL $14,X12
|
||||
PXOR X12,X2
|
||||
MOVOA 336(SP),X12
|
||||
MOVOA X2,336(SP)
|
||||
MOVOA X14,X1
|
||||
PADDL X12,X1
|
||||
MOVOA X1,X2
|
||||
PSLLL $7,X1
|
||||
PXOR X1,X5
|
||||
PSRLL $25,X2
|
||||
PXOR X2,X5
|
||||
MOVOA X0,X1
|
||||
PADDL X7,X1
|
||||
MOVOA X1,X2
|
||||
PSLLL $9,X1
|
||||
PXOR X1,X10
|
||||
PSRLL $23,X2
|
||||
PXOR X2,X10
|
||||
MOVOA X12,X1
|
||||
PADDL X5,X1
|
||||
MOVOA X1,X2
|
||||
PSLLL $9,X1
|
||||
PXOR X1,X8
|
||||
PSRLL $23,X2
|
||||
PXOR X2,X8
|
||||
MOVOA X7,X1
|
||||
PADDL X10,X1
|
||||
MOVOA X1,X2
|
||||
PSLLL $13,X1
|
||||
PXOR X1,X4
|
||||
PSRLL $19,X2
|
||||
PXOR X2,X4
|
||||
MOVOA X5,X1
|
||||
PADDL X8,X1
|
||||
MOVOA X1,X2
|
||||
PSLLL $13,X1
|
||||
PXOR X1,X14
|
||||
PSRLL $19,X2
|
||||
PXOR X2,X14
|
||||
MOVOA X10,X1
|
||||
PADDL X4,X1
|
||||
MOVOA X1,X2
|
||||
PSLLL $18,X1
|
||||
PXOR X1,X0
|
||||
PSRLL $14,X2
|
||||
PXOR X2,X0
|
||||
MOVOA 320(SP),X1
|
||||
MOVOA X0,320(SP)
|
||||
MOVOA X8,X0
|
||||
PADDL X14,X0
|
||||
MOVOA X0,X2
|
||||
PSLLL $18,X0
|
||||
PXOR X0,X12
|
||||
PSRLL $14,X2
|
||||
PXOR X2,X12
|
||||
MOVOA X11,X0
|
||||
PADDL X1,X0
|
||||
MOVOA X0,X2
|
||||
PSLLL $7,X0
|
||||
PXOR X0,X6
|
||||
PSRLL $25,X2
|
||||
PXOR X2,X6
|
||||
MOVOA 336(SP),X2
|
||||
MOVOA X12,336(SP)
|
||||
MOVOA X3,X0
|
||||
PADDL X2,X0
|
||||
MOVOA X0,X12
|
||||
PSLLL $7,X0
|
||||
PXOR X0,X13
|
||||
PSRLL $25,X12
|
||||
PXOR X12,X13
|
||||
MOVOA X1,X0
|
||||
PADDL X6,X0
|
||||
MOVOA X0,X12
|
||||
PSLLL $9,X0
|
||||
PXOR X0,X15
|
||||
PSRLL $23,X12
|
||||
PXOR X12,X15
|
||||
MOVOA X2,X0
|
||||
PADDL X13,X0
|
||||
MOVOA X0,X12
|
||||
PSLLL $9,X0
|
||||
PXOR X0,X9
|
||||
PSRLL $23,X12
|
||||
PXOR X12,X9
|
||||
MOVOA X6,X0
|
||||
PADDL X15,X0
|
||||
MOVOA X0,X12
|
||||
PSLLL $13,X0
|
||||
PXOR X0,X11
|
||||
PSRLL $19,X12
|
||||
PXOR X12,X11
|
||||
MOVOA X13,X0
|
||||
PADDL X9,X0
|
||||
MOVOA X0,X12
|
||||
PSLLL $13,X0
|
||||
PXOR X0,X3
|
||||
PSRLL $19,X12
|
||||
PXOR X12,X3
|
||||
MOVOA X15,X0
|
||||
PADDL X11,X0
|
||||
MOVOA X0,X12
|
||||
PSLLL $18,X0
|
||||
PXOR X0,X1
|
||||
PSRLL $14,X12
|
||||
PXOR X12,X1
|
||||
MOVOA X9,X0
|
||||
PADDL X3,X0
|
||||
MOVOA X0,X12
|
||||
PSLLL $18,X0
|
||||
PXOR X0,X2
|
||||
PSRLL $14,X12
|
||||
PXOR X12,X2
|
||||
MOVOA 320(SP),X12
|
||||
MOVOA 336(SP),X0
|
||||
SUBQ $2,DX
|
||||
JA MAINLOOP1
|
||||
PADDL 112(SP),X12
|
||||
PADDL 176(SP),X7
|
||||
PADDL 224(SP),X10
|
||||
PADDL 272(SP),X4
|
||||
MOVD X12,DX
|
||||
MOVD X7,CX
|
||||
MOVD X10,R8
|
||||
MOVD X4,R9
|
||||
PSHUFL $0X39,X12,X12
|
||||
PSHUFL $0X39,X7,X7
|
||||
PSHUFL $0X39,X10,X10
|
||||
PSHUFL $0X39,X4,X4
|
||||
XORL 0(SI),DX
|
||||
XORL 4(SI),CX
|
||||
XORL 8(SI),R8
|
||||
XORL 12(SI),R9
|
||||
MOVL DX,0(DI)
|
||||
MOVL CX,4(DI)
|
||||
MOVL R8,8(DI)
|
||||
MOVL R9,12(DI)
|
||||
MOVD X12,DX
|
||||
MOVD X7,CX
|
||||
MOVD X10,R8
|
||||
MOVD X4,R9
|
||||
PSHUFL $0X39,X12,X12
|
||||
PSHUFL $0X39,X7,X7
|
||||
PSHUFL $0X39,X10,X10
|
||||
PSHUFL $0X39,X4,X4
|
||||
XORL 64(SI),DX
|
||||
XORL 68(SI),CX
|
||||
XORL 72(SI),R8
|
||||
XORL 76(SI),R9
|
||||
MOVL DX,64(DI)
|
||||
MOVL CX,68(DI)
|
||||
MOVL R8,72(DI)
|
||||
MOVL R9,76(DI)
|
||||
MOVD X12,DX
|
||||
MOVD X7,CX
|
||||
MOVD X10,R8
|
||||
MOVD X4,R9
|
||||
PSHUFL $0X39,X12,X12
|
||||
PSHUFL $0X39,X7,X7
|
||||
PSHUFL $0X39,X10,X10
|
||||
PSHUFL $0X39,X4,X4
|
||||
XORL 128(SI),DX
|
||||
XORL 132(SI),CX
|
||||
XORL 136(SI),R8
|
||||
XORL 140(SI),R9
|
||||
MOVL DX,128(DI)
|
||||
MOVL CX,132(DI)
|
||||
MOVL R8,136(DI)
|
||||
MOVL R9,140(DI)
|
||||
MOVD X12,DX
|
||||
MOVD X7,CX
|
||||
MOVD X10,R8
|
||||
MOVD X4,R9
|
||||
XORL 192(SI),DX
|
||||
XORL 196(SI),CX
|
||||
XORL 200(SI),R8
|
||||
XORL 204(SI),R9
|
||||
MOVL DX,192(DI)
|
||||
MOVL CX,196(DI)
|
||||
MOVL R8,200(DI)
|
||||
MOVL R9,204(DI)
|
||||
PADDL 240(SP),X14
|
||||
PADDL 64(SP),X0
|
||||
PADDL 128(SP),X5
|
||||
PADDL 192(SP),X8
|
||||
MOVD X14,DX
|
||||
MOVD X0,CX
|
||||
MOVD X5,R8
|
||||
MOVD X8,R9
|
||||
PSHUFL $0X39,X14,X14
|
||||
PSHUFL $0X39,X0,X0
|
||||
PSHUFL $0X39,X5,X5
|
||||
PSHUFL $0X39,X8,X8
|
||||
XORL 16(SI),DX
|
||||
XORL 20(SI),CX
|
||||
XORL 24(SI),R8
|
||||
XORL 28(SI),R9
|
||||
MOVL DX,16(DI)
|
||||
MOVL CX,20(DI)
|
||||
MOVL R8,24(DI)
|
||||
MOVL R9,28(DI)
|
||||
MOVD X14,DX
|
||||
MOVD X0,CX
|
||||
MOVD X5,R8
|
||||
MOVD X8,R9
|
||||
PSHUFL $0X39,X14,X14
|
||||
PSHUFL $0X39,X0,X0
|
||||
PSHUFL $0X39,X5,X5
|
||||
PSHUFL $0X39,X8,X8
|
||||
XORL 80(SI),DX
|
||||
XORL 84(SI),CX
|
||||
XORL 88(SI),R8
|
||||
XORL 92(SI),R9
|
||||
MOVL DX,80(DI)
|
||||
MOVL CX,84(DI)
|
||||
MOVL R8,88(DI)
|
||||
MOVL R9,92(DI)
|
||||
MOVD X14,DX
|
||||
MOVD X0,CX
|
||||
MOVD X5,R8
|
||||
MOVD X8,R9
|
||||
PSHUFL $0X39,X14,X14
|
||||
PSHUFL $0X39,X0,X0
|
||||
PSHUFL $0X39,X5,X5
|
||||
PSHUFL $0X39,X8,X8
|
||||
XORL 144(SI),DX
|
||||
XORL 148(SI),CX
|
||||
XORL 152(SI),R8
|
||||
XORL 156(SI),R9
|
||||
MOVL DX,144(DI)
|
||||
MOVL CX,148(DI)
|
||||
MOVL R8,152(DI)
|
||||
MOVL R9,156(DI)
|
||||
MOVD X14,DX
|
||||
MOVD X0,CX
|
||||
MOVD X5,R8
|
||||
MOVD X8,R9
|
||||
XORL 208(SI),DX
|
||||
XORL 212(SI),CX
|
||||
XORL 216(SI),R8
|
||||
XORL 220(SI),R9
|
||||
MOVL DX,208(DI)
|
||||
MOVL CX,212(DI)
|
||||
MOVL R8,216(DI)
|
||||
MOVL R9,220(DI)
|
||||
PADDL 288(SP),X15
|
||||
PADDL 304(SP),X11
|
||||
PADDL 80(SP),X1
|
||||
PADDL 144(SP),X6
|
||||
MOVD X15,DX
|
||||
MOVD X11,CX
|
||||
MOVD X1,R8
|
||||
MOVD X6,R9
|
||||
PSHUFL $0X39,X15,X15
|
||||
PSHUFL $0X39,X11,X11
|
||||
PSHUFL $0X39,X1,X1
|
||||
PSHUFL $0X39,X6,X6
|
||||
XORL 32(SI),DX
|
||||
XORL 36(SI),CX
|
||||
XORL 40(SI),R8
|
||||
XORL 44(SI),R9
|
||||
MOVL DX,32(DI)
|
||||
MOVL CX,36(DI)
|
||||
MOVL R8,40(DI)
|
||||
MOVL R9,44(DI)
|
||||
MOVD X15,DX
|
||||
MOVD X11,CX
|
||||
MOVD X1,R8
|
||||
MOVD X6,R9
|
||||
PSHUFL $0X39,X15,X15
|
||||
PSHUFL $0X39,X11,X11
|
||||
PSHUFL $0X39,X1,X1
|
||||
PSHUFL $0X39,X6,X6
|
||||
XORL 96(SI),DX
|
||||
XORL 100(SI),CX
|
||||
XORL 104(SI),R8
|
||||
XORL 108(SI),R9
|
||||
MOVL DX,96(DI)
|
||||
MOVL CX,100(DI)
|
||||
MOVL R8,104(DI)
|
||||
MOVL R9,108(DI)
|
||||
MOVD X15,DX
|
||||
MOVD X11,CX
|
||||
MOVD X1,R8
|
||||
MOVD X6,R9
|
||||
PSHUFL $0X39,X15,X15
|
||||
PSHUFL $0X39,X11,X11
|
||||
PSHUFL $0X39,X1,X1
|
||||
PSHUFL $0X39,X6,X6
|
||||
XORL 160(SI),DX
|
||||
XORL 164(SI),CX
|
||||
XORL 168(SI),R8
|
||||
XORL 172(SI),R9
|
||||
MOVL DX,160(DI)
|
||||
MOVL CX,164(DI)
|
||||
MOVL R8,168(DI)
|
||||
MOVL R9,172(DI)
|
||||
MOVD X15,DX
|
||||
MOVD X11,CX
|
||||
MOVD X1,R8
|
||||
MOVD X6,R9
|
||||
XORL 224(SI),DX
|
||||
XORL 228(SI),CX
|
||||
XORL 232(SI),R8
|
||||
XORL 236(SI),R9
|
||||
MOVL DX,224(DI)
|
||||
MOVL CX,228(DI)
|
||||
MOVL R8,232(DI)
|
||||
MOVL R9,236(DI)
|
||||
PADDL 160(SP),X13
|
||||
PADDL 208(SP),X9
|
||||
PADDL 256(SP),X3
|
||||
PADDL 96(SP),X2
|
||||
MOVD X13,DX
|
||||
MOVD X9,CX
|
||||
MOVD X3,R8
|
||||
MOVD X2,R9
|
||||
PSHUFL $0X39,X13,X13
|
||||
PSHUFL $0X39,X9,X9
|
||||
PSHUFL $0X39,X3,X3
|
||||
PSHUFL $0X39,X2,X2
|
||||
XORL 48(SI),DX
|
||||
XORL 52(SI),CX
|
||||
XORL 56(SI),R8
|
||||
XORL 60(SI),R9
|
||||
MOVL DX,48(DI)
|
||||
MOVL CX,52(DI)
|
||||
MOVL R8,56(DI)
|
||||
MOVL R9,60(DI)
|
||||
MOVD X13,DX
|
||||
MOVD X9,CX
|
||||
MOVD X3,R8
|
||||
MOVD X2,R9
|
||||
PSHUFL $0X39,X13,X13
|
||||
PSHUFL $0X39,X9,X9
|
||||
PSHUFL $0X39,X3,X3
|
||||
PSHUFL $0X39,X2,X2
|
||||
XORL 112(SI),DX
|
||||
XORL 116(SI),CX
|
||||
XORL 120(SI),R8
|
||||
XORL 124(SI),R9
|
||||
MOVL DX,112(DI)
|
||||
MOVL CX,116(DI)
|
||||
MOVL R8,120(DI)
|
||||
MOVL R9,124(DI)
|
||||
MOVD X13,DX
|
||||
MOVD X9,CX
|
||||
MOVD X3,R8
|
||||
MOVD X2,R9
|
||||
PSHUFL $0X39,X13,X13
|
||||
PSHUFL $0X39,X9,X9
|
||||
PSHUFL $0X39,X3,X3
|
||||
PSHUFL $0X39,X2,X2
|
||||
XORL 176(SI),DX
|
||||
XORL 180(SI),CX
|
||||
XORL 184(SI),R8
|
||||
XORL 188(SI),R9
|
||||
MOVL DX,176(DI)
|
||||
MOVL CX,180(DI)
|
||||
MOVL R8,184(DI)
|
||||
MOVL R9,188(DI)
|
||||
MOVD X13,DX
|
||||
MOVD X9,CX
|
||||
MOVD X3,R8
|
||||
MOVD X2,R9
|
||||
XORL 240(SI),DX
|
||||
XORL 244(SI),CX
|
||||
XORL 248(SI),R8
|
||||
XORL 252(SI),R9
|
||||
MOVL DX,240(DI)
|
||||
MOVL CX,244(DI)
|
||||
MOVL R8,248(DI)
|
||||
MOVL R9,252(DI)
|
||||
MOVQ 352(SP),R9
|
||||
SUBQ $256,R9
|
||||
ADDQ $256,SI
|
||||
ADDQ $256,DI
|
||||
CMPQ R9,$256
|
||||
JAE BYTESATLEAST256
|
||||
CMPQ R9,$0
|
||||
JBE DONE
|
||||
BYTESBETWEEN1AND255:
|
||||
CMPQ R9,$64
|
||||
JAE NOCOPY
|
||||
MOVQ DI,DX
|
||||
LEAQ 360(SP),DI
|
||||
MOVQ R9,CX
|
||||
REP; MOVSB
|
||||
LEAQ 360(SP),DI
|
||||
LEAQ 360(SP),SI
|
||||
NOCOPY:
|
||||
MOVQ R9,352(SP)
|
||||
MOVOA 48(SP),X0
|
||||
MOVOA 0(SP),X1
|
||||
MOVOA 16(SP),X2
|
||||
MOVOA 32(SP),X3
|
||||
MOVOA X1,X4
|
||||
MOVQ $20,CX
|
||||
MAINLOOP2:
|
||||
PADDL X0,X4
|
||||
MOVOA X0,X5
|
||||
MOVOA X4,X6
|
||||
PSLLL $7,X4
|
||||
PSRLL $25,X6
|
||||
PXOR X4,X3
|
||||
PXOR X6,X3
|
||||
PADDL X3,X5
|
||||
MOVOA X3,X4
|
||||
MOVOA X5,X6
|
||||
PSLLL $9,X5
|
||||
PSRLL $23,X6
|
||||
PXOR X5,X2
|
||||
PSHUFL $0X93,X3,X3
|
||||
PXOR X6,X2
|
||||
PADDL X2,X4
|
||||
MOVOA X2,X5
|
||||
MOVOA X4,X6
|
||||
PSLLL $13,X4
|
||||
PSRLL $19,X6
|
||||
PXOR X4,X1
|
||||
PSHUFL $0X4E,X2,X2
|
||||
PXOR X6,X1
|
||||
PADDL X1,X5
|
||||
MOVOA X3,X4
|
||||
MOVOA X5,X6
|
||||
PSLLL $18,X5
|
||||
PSRLL $14,X6
|
||||
PXOR X5,X0
|
||||
PSHUFL $0X39,X1,X1
|
||||
PXOR X6,X0
|
||||
PADDL X0,X4
|
||||
MOVOA X0,X5
|
||||
MOVOA X4,X6
|
||||
PSLLL $7,X4
|
||||
PSRLL $25,X6
|
||||
PXOR X4,X1
|
||||
PXOR X6,X1
|
||||
PADDL X1,X5
|
||||
MOVOA X1,X4
|
||||
MOVOA X5,X6
|
||||
PSLLL $9,X5
|
||||
PSRLL $23,X6
|
||||
PXOR X5,X2
|
||||
PSHUFL $0X93,X1,X1
|
||||
PXOR X6,X2
|
||||
PADDL X2,X4
|
||||
MOVOA X2,X5
|
||||
MOVOA X4,X6
|
||||
PSLLL $13,X4
|
||||
PSRLL $19,X6
|
||||
PXOR X4,X3
|
||||
PSHUFL $0X4E,X2,X2
|
||||
PXOR X6,X3
|
||||
PADDL X3,X5
|
||||
MOVOA X1,X4
|
||||
MOVOA X5,X6
|
||||
PSLLL $18,X5
|
||||
PSRLL $14,X6
|
||||
PXOR X5,X0
|
||||
PSHUFL $0X39,X3,X3
|
||||
PXOR X6,X0
|
||||
PADDL X0,X4
|
||||
MOVOA X0,X5
|
||||
MOVOA X4,X6
|
||||
PSLLL $7,X4
|
||||
PSRLL $25,X6
|
||||
PXOR X4,X3
|
||||
PXOR X6,X3
|
||||
PADDL X3,X5
|
||||
MOVOA X3,X4
|
||||
MOVOA X5,X6
|
||||
PSLLL $9,X5
|
||||
PSRLL $23,X6
|
||||
PXOR X5,X2
|
||||
PSHUFL $0X93,X3,X3
|
||||
PXOR X6,X2
|
||||
PADDL X2,X4
|
||||
MOVOA X2,X5
|
||||
MOVOA X4,X6
|
||||
PSLLL $13,X4
|
||||
PSRLL $19,X6
|
||||
PXOR X4,X1
|
||||
PSHUFL $0X4E,X2,X2
|
||||
PXOR X6,X1
|
||||
PADDL X1,X5
|
||||
MOVOA X3,X4
|
||||
MOVOA X5,X6
|
||||
PSLLL $18,X5
|
||||
PSRLL $14,X6
|
||||
PXOR X5,X0
|
||||
PSHUFL $0X39,X1,X1
|
||||
PXOR X6,X0
|
||||
PADDL X0,X4
|
||||
MOVOA X0,X5
|
||||
MOVOA X4,X6
|
||||
PSLLL $7,X4
|
||||
PSRLL $25,X6
|
||||
PXOR X4,X1
|
||||
PXOR X6,X1
|
||||
PADDL X1,X5
|
||||
MOVOA X1,X4
|
||||
MOVOA X5,X6
|
||||
PSLLL $9,X5
|
||||
PSRLL $23,X6
|
||||
PXOR X5,X2
|
||||
PSHUFL $0X93,X1,X1
|
||||
PXOR X6,X2
|
||||
PADDL X2,X4
|
||||
MOVOA X2,X5
|
||||
MOVOA X4,X6
|
||||
PSLLL $13,X4
|
||||
PSRLL $19,X6
|
||||
PXOR X4,X3
|
||||
PSHUFL $0X4E,X2,X2
|
||||
PXOR X6,X3
|
||||
SUBQ $4,CX
|
||||
PADDL X3,X5
|
||||
MOVOA X1,X4
|
||||
MOVOA X5,X6
|
||||
PSLLL $18,X5
|
||||
PXOR X7,X7
|
||||
PSRLL $14,X6
|
||||
PXOR X5,X0
|
||||
PSHUFL $0X39,X3,X3
|
||||
PXOR X6,X0
|
||||
JA MAINLOOP2
|
||||
PADDL 48(SP),X0
|
||||
PADDL 0(SP),X1
|
||||
PADDL 16(SP),X2
|
||||
PADDL 32(SP),X3
|
||||
MOVD X0,CX
|
||||
MOVD X1,R8
|
||||
MOVD X2,R9
|
||||
MOVD X3,AX
|
||||
PSHUFL $0X39,X0,X0
|
||||
PSHUFL $0X39,X1,X1
|
||||
PSHUFL $0X39,X2,X2
|
||||
PSHUFL $0X39,X3,X3
|
||||
XORL 0(SI),CX
|
||||
XORL 48(SI),R8
|
||||
XORL 32(SI),R9
|
||||
XORL 16(SI),AX
|
||||
MOVL CX,0(DI)
|
||||
MOVL R8,48(DI)
|
||||
MOVL R9,32(DI)
|
||||
MOVL AX,16(DI)
|
||||
MOVD X0,CX
|
||||
MOVD X1,R8
|
||||
MOVD X2,R9
|
||||
MOVD X3,AX
|
||||
PSHUFL $0X39,X0,X0
|
||||
PSHUFL $0X39,X1,X1
|
||||
PSHUFL $0X39,X2,X2
|
||||
PSHUFL $0X39,X3,X3
|
||||
XORL 20(SI),CX
|
||||
XORL 4(SI),R8
|
||||
XORL 52(SI),R9
|
||||
XORL 36(SI),AX
|
||||
MOVL CX,20(DI)
|
||||
MOVL R8,4(DI)
|
||||
MOVL R9,52(DI)
|
||||
MOVL AX,36(DI)
|
||||
MOVD X0,CX
|
||||
MOVD X1,R8
|
||||
MOVD X2,R9
|
||||
MOVD X3,AX
|
||||
PSHUFL $0X39,X0,X0
|
||||
PSHUFL $0X39,X1,X1
|
||||
PSHUFL $0X39,X2,X2
|
||||
PSHUFL $0X39,X3,X3
|
||||
XORL 40(SI),CX
|
||||
XORL 24(SI),R8
|
||||
XORL 8(SI),R9
|
||||
XORL 56(SI),AX
|
||||
MOVL CX,40(DI)
|
||||
MOVL R8,24(DI)
|
||||
MOVL R9,8(DI)
|
||||
MOVL AX,56(DI)
|
||||
MOVD X0,CX
|
||||
MOVD X1,R8
|
||||
MOVD X2,R9
|
||||
MOVD X3,AX
|
||||
XORL 60(SI),CX
|
||||
XORL 44(SI),R8
|
||||
XORL 28(SI),R9
|
||||
XORL 12(SI),AX
|
||||
MOVL CX,60(DI)
|
||||
MOVL R8,44(DI)
|
||||
MOVL R9,28(DI)
|
||||
MOVL AX,12(DI)
|
||||
MOVQ 352(SP),R9
|
||||
MOVL 16(SP),CX
|
||||
MOVL 36 (SP),R8
|
||||
ADDQ $1,CX
|
||||
SHLQ $32,R8
|
||||
ADDQ R8,CX
|
||||
MOVQ CX,R8
|
||||
SHRQ $32,R8
|
||||
MOVL CX,16(SP)
|
||||
MOVL R8, 36 (SP)
|
||||
CMPQ R9,$64
|
||||
JA BYTESATLEAST65
|
||||
JAE BYTESATLEAST64
|
||||
MOVQ DI,SI
|
||||
MOVQ DX,DI
|
||||
MOVQ R9,CX
|
||||
REP; MOVSB
|
||||
BYTESATLEAST64:
|
||||
DONE:
|
||||
MOVQ R12,SP
|
||||
RET
|
||||
BYTESATLEAST65:
|
||||
SUBQ $64,R9
|
||||
ADDQ $64,DI
|
||||
ADDQ $64,SI
|
||||
JMP BYTESBETWEEN1AND255
|
||||
199
vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go
generated
vendored
Normal file
199
vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go
generated
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package salsa
|
||||
|
||||
// Core208 applies the Salsa20/8 core function to the 64-byte array in and puts
|
||||
// the result into the 64-byte array out. The input and output may be the same array.
|
||||
func Core208(out *[64]byte, in *[64]byte) {
|
||||
j0 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24
|
||||
j1 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24
|
||||
j2 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24
|
||||
j3 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24
|
||||
j4 := uint32(in[16]) | uint32(in[17])<<8 | uint32(in[18])<<16 | uint32(in[19])<<24
|
||||
j5 := uint32(in[20]) | uint32(in[21])<<8 | uint32(in[22])<<16 | uint32(in[23])<<24
|
||||
j6 := uint32(in[24]) | uint32(in[25])<<8 | uint32(in[26])<<16 | uint32(in[27])<<24
|
||||
j7 := uint32(in[28]) | uint32(in[29])<<8 | uint32(in[30])<<16 | uint32(in[31])<<24
|
||||
j8 := uint32(in[32]) | uint32(in[33])<<8 | uint32(in[34])<<16 | uint32(in[35])<<24
|
||||
j9 := uint32(in[36]) | uint32(in[37])<<8 | uint32(in[38])<<16 | uint32(in[39])<<24
|
||||
j10 := uint32(in[40]) | uint32(in[41])<<8 | uint32(in[42])<<16 | uint32(in[43])<<24
|
||||
j11 := uint32(in[44]) | uint32(in[45])<<8 | uint32(in[46])<<16 | uint32(in[47])<<24
|
||||
j12 := uint32(in[48]) | uint32(in[49])<<8 | uint32(in[50])<<16 | uint32(in[51])<<24
|
||||
j13 := uint32(in[52]) | uint32(in[53])<<8 | uint32(in[54])<<16 | uint32(in[55])<<24
|
||||
j14 := uint32(in[56]) | uint32(in[57])<<8 | uint32(in[58])<<16 | uint32(in[59])<<24
|
||||
j15 := uint32(in[60]) | uint32(in[61])<<8 | uint32(in[62])<<16 | uint32(in[63])<<24
|
||||
|
||||
x0, x1, x2, x3, x4, x5, x6, x7, x8 := j0, j1, j2, j3, j4, j5, j6, j7, j8
|
||||
x9, x10, x11, x12, x13, x14, x15 := j9, j10, j11, j12, j13, j14, j15
|
||||
|
||||
for i := 0; i < 8; i += 2 {
|
||||
u := x0 + x12
|
||||
x4 ^= u<<7 | u>>(32-7)
|
||||
u = x4 + x0
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
u = x8 + x4
|
||||
x12 ^= u<<13 | u>>(32-13)
|
||||
u = x12 + x8
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x5 + x1
|
||||
x9 ^= u<<7 | u>>(32-7)
|
||||
u = x9 + x5
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
u = x13 + x9
|
||||
x1 ^= u<<13 | u>>(32-13)
|
||||
u = x1 + x13
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x10 + x6
|
||||
x14 ^= u<<7 | u>>(32-7)
|
||||
u = x14 + x10
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
u = x2 + x14
|
||||
x6 ^= u<<13 | u>>(32-13)
|
||||
u = x6 + x2
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x15 + x11
|
||||
x3 ^= u<<7 | u>>(32-7)
|
||||
u = x3 + x15
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
u = x7 + x3
|
||||
x11 ^= u<<13 | u>>(32-13)
|
||||
u = x11 + x7
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x0 + x3
|
||||
x1 ^= u<<7 | u>>(32-7)
|
||||
u = x1 + x0
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
u = x2 + x1
|
||||
x3 ^= u<<13 | u>>(32-13)
|
||||
u = x3 + x2
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x5 + x4
|
||||
x6 ^= u<<7 | u>>(32-7)
|
||||
u = x6 + x5
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
u = x7 + x6
|
||||
x4 ^= u<<13 | u>>(32-13)
|
||||
u = x4 + x7
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x10 + x9
|
||||
x11 ^= u<<7 | u>>(32-7)
|
||||
u = x11 + x10
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
u = x8 + x11
|
||||
x9 ^= u<<13 | u>>(32-13)
|
||||
u = x9 + x8
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x15 + x14
|
||||
x12 ^= u<<7 | u>>(32-7)
|
||||
u = x12 + x15
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
u = x13 + x12
|
||||
x14 ^= u<<13 | u>>(32-13)
|
||||
u = x14 + x13
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
}
|
||||
x0 += j0
|
||||
x1 += j1
|
||||
x2 += j2
|
||||
x3 += j3
|
||||
x4 += j4
|
||||
x5 += j5
|
||||
x6 += j6
|
||||
x7 += j7
|
||||
x8 += j8
|
||||
x9 += j9
|
||||
x10 += j10
|
||||
x11 += j11
|
||||
x12 += j12
|
||||
x13 += j13
|
||||
x14 += j14
|
||||
x15 += j15
|
||||
|
||||
out[0] = byte(x0)
|
||||
out[1] = byte(x0 >> 8)
|
||||
out[2] = byte(x0 >> 16)
|
||||
out[3] = byte(x0 >> 24)
|
||||
|
||||
out[4] = byte(x1)
|
||||
out[5] = byte(x1 >> 8)
|
||||
out[6] = byte(x1 >> 16)
|
||||
out[7] = byte(x1 >> 24)
|
||||
|
||||
out[8] = byte(x2)
|
||||
out[9] = byte(x2 >> 8)
|
||||
out[10] = byte(x2 >> 16)
|
||||
out[11] = byte(x2 >> 24)
|
||||
|
||||
out[12] = byte(x3)
|
||||
out[13] = byte(x3 >> 8)
|
||||
out[14] = byte(x3 >> 16)
|
||||
out[15] = byte(x3 >> 24)
|
||||
|
||||
out[16] = byte(x4)
|
||||
out[17] = byte(x4 >> 8)
|
||||
out[18] = byte(x4 >> 16)
|
||||
out[19] = byte(x4 >> 24)
|
||||
|
||||
out[20] = byte(x5)
|
||||
out[21] = byte(x5 >> 8)
|
||||
out[22] = byte(x5 >> 16)
|
||||
out[23] = byte(x5 >> 24)
|
||||
|
||||
out[24] = byte(x6)
|
||||
out[25] = byte(x6 >> 8)
|
||||
out[26] = byte(x6 >> 16)
|
||||
out[27] = byte(x6 >> 24)
|
||||
|
||||
out[28] = byte(x7)
|
||||
out[29] = byte(x7 >> 8)
|
||||
out[30] = byte(x7 >> 16)
|
||||
out[31] = byte(x7 >> 24)
|
||||
|
||||
out[32] = byte(x8)
|
||||
out[33] = byte(x8 >> 8)
|
||||
out[34] = byte(x8 >> 16)
|
||||
out[35] = byte(x8 >> 24)
|
||||
|
||||
out[36] = byte(x9)
|
||||
out[37] = byte(x9 >> 8)
|
||||
out[38] = byte(x9 >> 16)
|
||||
out[39] = byte(x9 >> 24)
|
||||
|
||||
out[40] = byte(x10)
|
||||
out[41] = byte(x10 >> 8)
|
||||
out[42] = byte(x10 >> 16)
|
||||
out[43] = byte(x10 >> 24)
|
||||
|
||||
out[44] = byte(x11)
|
||||
out[45] = byte(x11 >> 8)
|
||||
out[46] = byte(x11 >> 16)
|
||||
out[47] = byte(x11 >> 24)
|
||||
|
||||
out[48] = byte(x12)
|
||||
out[49] = byte(x12 >> 8)
|
||||
out[50] = byte(x12 >> 16)
|
||||
out[51] = byte(x12 >> 24)
|
||||
|
||||
out[52] = byte(x13)
|
||||
out[53] = byte(x13 >> 8)
|
||||
out[54] = byte(x13 >> 16)
|
||||
out[55] = byte(x13 >> 24)
|
||||
|
||||
out[56] = byte(x14)
|
||||
out[57] = byte(x14 >> 8)
|
||||
out[58] = byte(x14 >> 16)
|
||||
out[59] = byte(x14 >> 24)
|
||||
|
||||
out[60] = byte(x15)
|
||||
out[61] = byte(x15 >> 8)
|
||||
out[62] = byte(x15 >> 16)
|
||||
out[63] = byte(x15 >> 24)
|
||||
}
|
||||
23
vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go
generated
vendored
Normal file
23
vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build amd64,!appengine,!gccgo
|
||||
|
||||
package salsa
|
||||
|
||||
// This function is implemented in salsa2020_amd64.s.
|
||||
|
||||
//go:noescape
|
||||
|
||||
func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
|
||||
|
||||
// XORKeyStream crypts bytes from in to out using the given key and counters.
|
||||
// In and out may be the same slice but otherwise should not overlap. Counter
|
||||
// contains the raw salsa20 counter bytes (both nonce and block counter).
|
||||
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
|
||||
if len(in) == 0 {
|
||||
return
|
||||
}
|
||||
salsa2020XORKeyStream(&out[0], &in[0], uint64(len(in)), &counter[0], &key[0])
|
||||
}
|
||||
234
vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go
generated
vendored
Normal file
234
vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go
generated
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !amd64 appengine gccgo
|
||||
|
||||
package salsa
|
||||
|
||||
const rounds = 20
|
||||
|
||||
// core applies the Salsa20 core function to 16-byte input in, 32-byte key k,
|
||||
// and 16-byte constant c, and puts the result into 64-byte array out.
|
||||
func core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
|
||||
j0 := uint32(c[0]) | uint32(c[1])<<8 | uint32(c[2])<<16 | uint32(c[3])<<24
|
||||
j1 := uint32(k[0]) | uint32(k[1])<<8 | uint32(k[2])<<16 | uint32(k[3])<<24
|
||||
j2 := uint32(k[4]) | uint32(k[5])<<8 | uint32(k[6])<<16 | uint32(k[7])<<24
|
||||
j3 := uint32(k[8]) | uint32(k[9])<<8 | uint32(k[10])<<16 | uint32(k[11])<<24
|
||||
j4 := uint32(k[12]) | uint32(k[13])<<8 | uint32(k[14])<<16 | uint32(k[15])<<24
|
||||
j5 := uint32(c[4]) | uint32(c[5])<<8 | uint32(c[6])<<16 | uint32(c[7])<<24
|
||||
j6 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24
|
||||
j7 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24
|
||||
j8 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24
|
||||
j9 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24
|
||||
j10 := uint32(c[8]) | uint32(c[9])<<8 | uint32(c[10])<<16 | uint32(c[11])<<24
|
||||
j11 := uint32(k[16]) | uint32(k[17])<<8 | uint32(k[18])<<16 | uint32(k[19])<<24
|
||||
j12 := uint32(k[20]) | uint32(k[21])<<8 | uint32(k[22])<<16 | uint32(k[23])<<24
|
||||
j13 := uint32(k[24]) | uint32(k[25])<<8 | uint32(k[26])<<16 | uint32(k[27])<<24
|
||||
j14 := uint32(k[28]) | uint32(k[29])<<8 | uint32(k[30])<<16 | uint32(k[31])<<24
|
||||
j15 := uint32(c[12]) | uint32(c[13])<<8 | uint32(c[14])<<16 | uint32(c[15])<<24
|
||||
|
||||
x0, x1, x2, x3, x4, x5, x6, x7, x8 := j0, j1, j2, j3, j4, j5, j6, j7, j8
|
||||
x9, x10, x11, x12, x13, x14, x15 := j9, j10, j11, j12, j13, j14, j15
|
||||
|
||||
for i := 0; i < rounds; i += 2 {
|
||||
u := x0 + x12
|
||||
x4 ^= u<<7 | u>>(32-7)
|
||||
u = x4 + x0
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
u = x8 + x4
|
||||
x12 ^= u<<13 | u>>(32-13)
|
||||
u = x12 + x8
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x5 + x1
|
||||
x9 ^= u<<7 | u>>(32-7)
|
||||
u = x9 + x5
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
u = x13 + x9
|
||||
x1 ^= u<<13 | u>>(32-13)
|
||||
u = x1 + x13
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x10 + x6
|
||||
x14 ^= u<<7 | u>>(32-7)
|
||||
u = x14 + x10
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
u = x2 + x14
|
||||
x6 ^= u<<13 | u>>(32-13)
|
||||
u = x6 + x2
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x15 + x11
|
||||
x3 ^= u<<7 | u>>(32-7)
|
||||
u = x3 + x15
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
u = x7 + x3
|
||||
x11 ^= u<<13 | u>>(32-13)
|
||||
u = x11 + x7
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x0 + x3
|
||||
x1 ^= u<<7 | u>>(32-7)
|
||||
u = x1 + x0
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
u = x2 + x1
|
||||
x3 ^= u<<13 | u>>(32-13)
|
||||
u = x3 + x2
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x5 + x4
|
||||
x6 ^= u<<7 | u>>(32-7)
|
||||
u = x6 + x5
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
u = x7 + x6
|
||||
x4 ^= u<<13 | u>>(32-13)
|
||||
u = x4 + x7
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x10 + x9
|
||||
x11 ^= u<<7 | u>>(32-7)
|
||||
u = x11 + x10
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
u = x8 + x11
|
||||
x9 ^= u<<13 | u>>(32-13)
|
||||
u = x9 + x8
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
|
||||
u = x15 + x14
|
||||
x12 ^= u<<7 | u>>(32-7)
|
||||
u = x12 + x15
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
u = x13 + x12
|
||||
x14 ^= u<<13 | u>>(32-13)
|
||||
u = x14 + x13
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
}
|
||||
x0 += j0
|
||||
x1 += j1
|
||||
x2 += j2
|
||||
x3 += j3
|
||||
x4 += j4
|
||||
x5 += j5
|
||||
x6 += j6
|
||||
x7 += j7
|
||||
x8 += j8
|
||||
x9 += j9
|
||||
x10 += j10
|
||||
x11 += j11
|
||||
x12 += j12
|
||||
x13 += j13
|
||||
x14 += j14
|
||||
x15 += j15
|
||||
|
||||
out[0] = byte(x0)
|
||||
out[1] = byte(x0 >> 8)
|
||||
out[2] = byte(x0 >> 16)
|
||||
out[3] = byte(x0 >> 24)
|
||||
|
||||
out[4] = byte(x1)
|
||||
out[5] = byte(x1 >> 8)
|
||||
out[6] = byte(x1 >> 16)
|
||||
out[7] = byte(x1 >> 24)
|
||||
|
||||
out[8] = byte(x2)
|
||||
out[9] = byte(x2 >> 8)
|
||||
out[10] = byte(x2 >> 16)
|
||||
out[11] = byte(x2 >> 24)
|
||||
|
||||
out[12] = byte(x3)
|
||||
out[13] = byte(x3 >> 8)
|
||||
out[14] = byte(x3 >> 16)
|
||||
out[15] = byte(x3 >> 24)
|
||||
|
||||
out[16] = byte(x4)
|
||||
out[17] = byte(x4 >> 8)
|
||||
out[18] = byte(x4 >> 16)
|
||||
out[19] = byte(x4 >> 24)
|
||||
|
||||
out[20] = byte(x5)
|
||||
out[21] = byte(x5 >> 8)
|
||||
out[22] = byte(x5 >> 16)
|
||||
out[23] = byte(x5 >> 24)
|
||||
|
||||
out[24] = byte(x6)
|
||||
out[25] = byte(x6 >> 8)
|
||||
out[26] = byte(x6 >> 16)
|
||||
out[27] = byte(x6 >> 24)
|
||||
|
||||
out[28] = byte(x7)
|
||||
out[29] = byte(x7 >> 8)
|
||||
out[30] = byte(x7 >> 16)
|
||||
out[31] = byte(x7 >> 24)
|
||||
|
||||
out[32] = byte(x8)
|
||||
out[33] = byte(x8 >> 8)
|
||||
out[34] = byte(x8 >> 16)
|
||||
out[35] = byte(x8 >> 24)
|
||||
|
||||
out[36] = byte(x9)
|
||||
out[37] = byte(x9 >> 8)
|
||||
out[38] = byte(x9 >> 16)
|
||||
out[39] = byte(x9 >> 24)
|
||||
|
||||
out[40] = byte(x10)
|
||||
out[41] = byte(x10 >> 8)
|
||||
out[42] = byte(x10 >> 16)
|
||||
out[43] = byte(x10 >> 24)
|
||||
|
||||
out[44] = byte(x11)
|
||||
out[45] = byte(x11 >> 8)
|
||||
out[46] = byte(x11 >> 16)
|
||||
out[47] = byte(x11 >> 24)
|
||||
|
||||
out[48] = byte(x12)
|
||||
out[49] = byte(x12 >> 8)
|
||||
out[50] = byte(x12 >> 16)
|
||||
out[51] = byte(x12 >> 24)
|
||||
|
||||
out[52] = byte(x13)
|
||||
out[53] = byte(x13 >> 8)
|
||||
out[54] = byte(x13 >> 16)
|
||||
out[55] = byte(x13 >> 24)
|
||||
|
||||
out[56] = byte(x14)
|
||||
out[57] = byte(x14 >> 8)
|
||||
out[58] = byte(x14 >> 16)
|
||||
out[59] = byte(x14 >> 24)
|
||||
|
||||
out[60] = byte(x15)
|
||||
out[61] = byte(x15 >> 8)
|
||||
out[62] = byte(x15 >> 16)
|
||||
out[63] = byte(x15 >> 24)
|
||||
}
|
||||
|
||||
// XORKeyStream crypts bytes from in to out using the given key and counters.
|
||||
// In and out may be the same slice but otherwise should not overlap. Counter
|
||||
// contains the raw salsa20 counter bytes (both nonce and block counter).
|
||||
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
|
||||
var block [64]byte
|
||||
var counterCopy [16]byte
|
||||
copy(counterCopy[:], counter[:])
|
||||
|
||||
for len(in) >= 64 {
|
||||
core(&block, &counterCopy, key, &Sigma)
|
||||
for i, x := range block {
|
||||
out[i] = in[i] ^ x
|
||||
}
|
||||
u := uint32(1)
|
||||
for i := 8; i < 16; i++ {
|
||||
u += uint32(counterCopy[i])
|
||||
counterCopy[i] = byte(u)
|
||||
u >>= 8
|
||||
}
|
||||
in = in[64:]
|
||||
out = out[64:]
|
||||
}
|
||||
|
||||
if len(in) > 0 {
|
||||
core(&block, &counterCopy, key, &Sigma)
|
||||
for i, v := range in {
|
||||
out[i] = v ^ block[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
35
vendor/golang.org/x/crypto/salsa20/salsa/salsa_test.go
generated
vendored
Normal file
35
vendor/golang.org/x/crypto/salsa20/salsa/salsa_test.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package salsa
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCore208(t *testing.T) {
|
||||
in := [64]byte{
|
||||
0x7e, 0x87, 0x9a, 0x21, 0x4f, 0x3e, 0xc9, 0x86,
|
||||
0x7c, 0xa9, 0x40, 0xe6, 0x41, 0x71, 0x8f, 0x26,
|
||||
0xba, 0xee, 0x55, 0x5b, 0x8c, 0x61, 0xc1, 0xb5,
|
||||
0x0d, 0xf8, 0x46, 0x11, 0x6d, 0xcd, 0x3b, 0x1d,
|
||||
0xee, 0x24, 0xf3, 0x19, 0xdf, 0x9b, 0x3d, 0x85,
|
||||
0x14, 0x12, 0x1e, 0x4b, 0x5a, 0xc5, 0xaa, 0x32,
|
||||
0x76, 0x02, 0x1d, 0x29, 0x09, 0xc7, 0x48, 0x29,
|
||||
0xed, 0xeb, 0xc6, 0x8d, 0xb8, 0xb8, 0xc2, 0x5e}
|
||||
|
||||
out := [64]byte{
|
||||
0xa4, 0x1f, 0x85, 0x9c, 0x66, 0x08, 0xcc, 0x99,
|
||||
0x3b, 0x81, 0xca, 0xcb, 0x02, 0x0c, 0xef, 0x05,
|
||||
0x04, 0x4b, 0x21, 0x81, 0xa2, 0xfd, 0x33, 0x7d,
|
||||
0xfd, 0x7b, 0x1c, 0x63, 0x96, 0x68, 0x2f, 0x29,
|
||||
0xb4, 0x39, 0x31, 0x68, 0xe3, 0xc9, 0xe6, 0xbc,
|
||||
0xfe, 0x6b, 0xc5, 0xb7, 0xa0, 0x6d, 0x96, 0xba,
|
||||
0xe4, 0x24, 0xcc, 0x10, 0x2c, 0x91, 0x74, 0x5c,
|
||||
0x24, 0xad, 0x67, 0x3d, 0xc7, 0x61, 0x8f, 0x81,
|
||||
}
|
||||
|
||||
Core208(&in, &in)
|
||||
if in != out {
|
||||
t.Errorf("expected %x, got %x", out, in)
|
||||
}
|
||||
}
|
||||
54
vendor/golang.org/x/crypto/salsa20/salsa20.go
generated
vendored
Normal file
54
vendor/golang.org/x/crypto/salsa20/salsa20.go
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package salsa20 implements the Salsa20 stream cipher as specified in http://cr.yp.to/snuffle/spec.pdf.
|
||||
|
||||
Salsa20 differs from many other stream ciphers in that it is message orientated
|
||||
rather than byte orientated. Keystream blocks are not preserved between calls,
|
||||
therefore each side must encrypt/decrypt data with the same segmentation.
|
||||
|
||||
Another aspect of this difference is that part of the counter is exposed as
|
||||
an nonce in each call. Encrypting two different messages with the same (key,
|
||||
nonce) pair leads to trivial plaintext recovery. This is analogous to
|
||||
encrypting two different messages with the same key with a traditional stream
|
||||
cipher.
|
||||
|
||||
This package also implements XSalsa20: a version of Salsa20 with a 24-byte
|
||||
nonce as specified in http://cr.yp.to/snuffle/xsalsa-20081128.pdf. Simply
|
||||
passing a 24-byte slice as the nonce triggers XSalsa20.
|
||||
*/
|
||||
package salsa20 // import "golang.org/x/crypto/salsa20"
|
||||
|
||||
// TODO(agl): implement XORKeyStream12 and XORKeyStream8 - the reduced round variants of Salsa20.
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/salsa20/salsa"
|
||||
)
|
||||
|
||||
// XORKeyStream crypts bytes from in to out using the given key and nonce. In
|
||||
// and out may be the same slice but otherwise should not overlap. Nonce must
|
||||
// be either 8 or 24 bytes long.
|
||||
func XORKeyStream(out, in []byte, nonce []byte, key *[32]byte) {
|
||||
if len(out) < len(in) {
|
||||
in = in[:len(out)]
|
||||
}
|
||||
|
||||
var subNonce [16]byte
|
||||
|
||||
if len(nonce) == 24 {
|
||||
var subKey [32]byte
|
||||
var hNonce [16]byte
|
||||
copy(hNonce[:], nonce[:16])
|
||||
salsa.HSalsa20(&subKey, &hNonce, key, &salsa.Sigma)
|
||||
copy(subNonce[:], nonce[16:])
|
||||
key = &subKey
|
||||
} else if len(nonce) == 8 {
|
||||
copy(subNonce[:], nonce[:])
|
||||
} else {
|
||||
panic("salsa20: nonce must be 8 or 24 bytes")
|
||||
}
|
||||
|
||||
salsa.XORKeyStream(out, in, &subNonce, key)
|
||||
}
|
||||
139
vendor/golang.org/x/crypto/salsa20/salsa20_test.go
generated
vendored
Normal file
139
vendor/golang.org/x/crypto/salsa20/salsa20_test.go
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package salsa20
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func fromHex(s string) []byte {
|
||||
ret, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// testVectors was taken from set 6 of the ECRYPT test vectors:
|
||||
// http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/salsa20/full/verified.test-vectors?logsort=rev&rev=210&view=markup
|
||||
var testVectors = []struct {
|
||||
key []byte
|
||||
iv []byte
|
||||
numBytes int
|
||||
xor []byte
|
||||
}{
|
||||
{
|
||||
fromHex("0053A6F94C9FF24598EB3E91E4378ADD3083D6297CCF2275C81B6EC11467BA0D"),
|
||||
fromHex("0D74DB42A91077DE"),
|
||||
131072,
|
||||
fromHex("C349B6A51A3EC9B712EAED3F90D8BCEE69B7628645F251A996F55260C62EF31FD6C6B0AEA94E136C9D984AD2DF3578F78E457527B03A0450580DD874F63B1AB9"),
|
||||
},
|
||||
{
|
||||
fromHex("0558ABFE51A4F74A9DF04396E93C8FE23588DB2E81D4277ACD2073C6196CBF12"),
|
||||
fromHex("167DE44BB21980E7"),
|
||||
131072,
|
||||
fromHex("C3EAAF32836BACE32D04E1124231EF47E101367D6305413A0EEB07C60698A2876E4D031870A739D6FFDDD208597AFF0A47AC17EDB0167DD67EBA84F1883D4DFD"),
|
||||
},
|
||||
{
|
||||
fromHex("0A5DB00356A9FC4FA2F5489BEE4194E73A8DE03386D92C7FD22578CB1E71C417"),
|
||||
fromHex("1F86ED54BB2289F0"),
|
||||
131072,
|
||||
fromHex("3CD23C3DC90201ACC0CF49B440B6C417F0DC8D8410A716D5314C059E14B1A8D9A9FB8EA3D9C8DAE12B21402F674AA95C67B1FC514E994C9D3F3A6E41DFF5BBA6"),
|
||||
},
|
||||
{
|
||||
fromHex("0F62B5085BAE0154A7FA4DA0F34699EC3F92E5388BDE3184D72A7DD02376C91C"),
|
||||
fromHex("288FF65DC42B92F9"),
|
||||
131072,
|
||||
fromHex("E00EBCCD70D69152725F9987982178A2E2E139C7BCBE04CA8A0E99E318D9AB76F988C8549F75ADD790BA4F81C176DA653C1A043F11A958E169B6D2319F4EEC1A"),
|
||||
},
|
||||
}
|
||||
|
||||
func TestSalsa20(t *testing.T) {
|
||||
var inBuf, outBuf []byte
|
||||
var key [32]byte
|
||||
|
||||
for i, test := range testVectors {
|
||||
if test.numBytes%64 != 0 {
|
||||
t.Errorf("#%d: numBytes is not a multiple of 64", i)
|
||||
continue
|
||||
}
|
||||
|
||||
if test.numBytes > len(inBuf) {
|
||||
inBuf = make([]byte, test.numBytes)
|
||||
outBuf = make([]byte, test.numBytes)
|
||||
}
|
||||
in := inBuf[:test.numBytes]
|
||||
out := outBuf[:test.numBytes]
|
||||
copy(key[:], test.key)
|
||||
XORKeyStream(out, in, test.iv, &key)
|
||||
|
||||
var xor [64]byte
|
||||
for len(out) > 0 {
|
||||
for i := 0; i < 64; i++ {
|
||||
xor[i] ^= out[i]
|
||||
}
|
||||
out = out[64:]
|
||||
}
|
||||
|
||||
if !bytes.Equal(xor[:], test.xor) {
|
||||
t.Errorf("#%d: bad result", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var xSalsa20TestData = []struct {
|
||||
in, nonce, key, out []byte
|
||||
}{
|
||||
{
|
||||
[]byte("Hello world!"),
|
||||
[]byte("24-byte nonce for xsalsa"),
|
||||
[]byte("this is 32-byte key for xsalsa20"),
|
||||
[]byte{0x00, 0x2d, 0x45, 0x13, 0x84, 0x3f, 0xc2, 0x40, 0xc4, 0x01, 0xe5, 0x41},
|
||||
},
|
||||
{
|
||||
make([]byte, 64),
|
||||
[]byte("24-byte nonce for xsalsa"),
|
||||
[]byte("this is 32-byte key for xsalsa20"),
|
||||
[]byte{0x48, 0x48, 0x29, 0x7f, 0xeb, 0x1f, 0xb5, 0x2f, 0xb6,
|
||||
0x6d, 0x81, 0x60, 0x9b, 0xd5, 0x47, 0xfa, 0xbc, 0xbe, 0x70,
|
||||
0x26, 0xed, 0xc8, 0xb5, 0xe5, 0xe4, 0x49, 0xd0, 0x88, 0xbf,
|
||||
0xa6, 0x9c, 0x08, 0x8f, 0x5d, 0x8d, 0xa1, 0xd7, 0x91, 0x26,
|
||||
0x7c, 0x2c, 0x19, 0x5a, 0x7f, 0x8c, 0xae, 0x9c, 0x4b, 0x40,
|
||||
0x50, 0xd0, 0x8c, 0xe6, 0xd3, 0xa1, 0x51, 0xec, 0x26, 0x5f,
|
||||
0x3a, 0x58, 0xe4, 0x76, 0x48},
|
||||
},
|
||||
}
|
||||
|
||||
func TestXSalsa20(t *testing.T) {
|
||||
var key [32]byte
|
||||
|
||||
for i, test := range xSalsa20TestData {
|
||||
out := make([]byte, len(test.in))
|
||||
copy(key[:], test.key)
|
||||
XORKeyStream(out, test.in, test.nonce, &key)
|
||||
if !bytes.Equal(out, test.out) {
|
||||
t.Errorf("%d: expected %x, got %x", i, test.out, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
keyArray [32]byte
|
||||
key = &keyArray
|
||||
nonce [8]byte
|
||||
msg = make([]byte, 1<<10)
|
||||
)
|
||||
|
||||
func BenchmarkXOR1K(b *testing.B) {
|
||||
b.StopTimer()
|
||||
out := make([]byte, 1024)
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
XORKeyStream(out, msg[:1024], nonce[:], key)
|
||||
}
|
||||
b.SetBytes(1024)
|
||||
}
|
||||
109
vendor/golang.org/x/crypto/tea/cipher.go
generated
vendored
Normal file
109
vendor/golang.org/x/crypto/tea/cipher.go
generated
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package tea implements the TEA algorithm, as defined in Needham and
|
||||
// Wheeler's 1994 technical report, “TEA, a Tiny Encryption Algorithm”. See
|
||||
// http://www.cix.co.uk/~klockstone/tea.pdf for details.
|
||||
|
||||
package tea
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
)
|
||||
|
||||
const (
|
||||
// BlockSize is the size of a TEA block, in bytes.
|
||||
BlockSize = 8
|
||||
|
||||
// KeySize is the size of a TEA key, in bytes.
|
||||
KeySize = 16
|
||||
|
||||
// delta is the TEA key schedule constant.
|
||||
delta = 0x9e3779b9
|
||||
|
||||
// numRounds is the standard number of rounds in TEA.
|
||||
numRounds = 64
|
||||
)
|
||||
|
||||
// tea is an instance of the TEA cipher with a particular key.
|
||||
type tea struct {
|
||||
key [16]byte
|
||||
rounds int
|
||||
}
|
||||
|
||||
// NewCipher returns an instance of the TEA cipher with the standard number of
|
||||
// rounds. The key argument must be 16 bytes long.
|
||||
func NewCipher(key []byte) (cipher.Block, error) {
|
||||
return NewCipherWithRounds(key, numRounds)
|
||||
}
|
||||
|
||||
// NewCipherWithRounds returns an instance of the TEA cipher with a given
|
||||
// number of rounds, which must be even. The key argument must be 16 bytes
|
||||
// long.
|
||||
func NewCipherWithRounds(key []byte, rounds int) (cipher.Block, error) {
|
||||
if len(key) != 16 {
|
||||
return nil, errors.New("tea: incorrect key size")
|
||||
}
|
||||
|
||||
if rounds&1 != 0 {
|
||||
return nil, errors.New("tea: odd number of rounds specified")
|
||||
}
|
||||
|
||||
c := &tea{
|
||||
rounds: rounds,
|
||||
}
|
||||
copy(c.key[:], key)
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// BlockSize returns the TEA block size, which is eight bytes. It is necessary
|
||||
// to satisfy the Block interface in the package "crypto/cipher".
|
||||
func (*tea) BlockSize() int {
|
||||
return BlockSize
|
||||
}
|
||||
|
||||
// Encrypt encrypts the 8 byte buffer src using the key in t and stores the
|
||||
// result in dst. Note that for amounts of data larger than a block, it is not
|
||||
// safe to just call Encrypt on successive blocks; instead, use an encryption
|
||||
// mode like CBC (see crypto/cipher/cbc.go).
|
||||
func (t *tea) Encrypt(dst, src []byte) {
|
||||
e := binary.BigEndian
|
||||
v0, v1 := e.Uint32(src), e.Uint32(src[4:])
|
||||
k0, k1, k2, k3 := e.Uint32(t.key[0:]), e.Uint32(t.key[4:]), e.Uint32(t.key[8:]), e.Uint32(t.key[12:])
|
||||
|
||||
sum := uint32(0)
|
||||
delta := uint32(delta)
|
||||
|
||||
for i := 0; i < t.rounds/2; i++ {
|
||||
sum += delta
|
||||
v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1)
|
||||
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3)
|
||||
}
|
||||
|
||||
e.PutUint32(dst, v0)
|
||||
e.PutUint32(dst[4:], v1)
|
||||
}
|
||||
|
||||
// Decrypt decrypts the 8 byte buffer src using the key in t and stores the
|
||||
// result in dst.
|
||||
func (t *tea) Decrypt(dst, src []byte) {
|
||||
e := binary.BigEndian
|
||||
v0, v1 := e.Uint32(src), e.Uint32(src[4:])
|
||||
k0, k1, k2, k3 := e.Uint32(t.key[0:]), e.Uint32(t.key[4:]), e.Uint32(t.key[8:]), e.Uint32(t.key[12:])
|
||||
|
||||
delta := uint32(delta)
|
||||
sum := delta * uint32(t.rounds/2) // in general, sum = delta * n
|
||||
|
||||
for i := 0; i < t.rounds/2; i++ {
|
||||
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3)
|
||||
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1)
|
||||
sum -= delta
|
||||
}
|
||||
|
||||
e.PutUint32(dst, v0)
|
||||
e.PutUint32(dst[4:], v1)
|
||||
}
|
||||
93
vendor/golang.org/x/crypto/tea/tea_test.go
generated
vendored
Normal file
93
vendor/golang.org/x/crypto/tea/tea_test.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package tea
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// A sample test key for when we just want to initialize a cipher
|
||||
var testKey = []byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}
|
||||
|
||||
// Test that the block size for tea is correct
|
||||
func TestBlocksize(t *testing.T) {
|
||||
c, err := NewCipher(testKey)
|
||||
if err != nil {
|
||||
t.Fatalf("NewCipher returned error: %s", err)
|
||||
}
|
||||
|
||||
if result := c.BlockSize(); result != BlockSize {
|
||||
t.Errorf("cipher.BlockSize returned %d, but expected %d", result, BlockSize)
|
||||
}
|
||||
}
|
||||
|
||||
// Test that invalid key sizes return an error
|
||||
func TestInvalidKeySize(t *testing.T) {
|
||||
var key [KeySize + 1]byte
|
||||
|
||||
if _, err := NewCipher(key[:]); err == nil {
|
||||
t.Errorf("invalid key size %d didn't result in an error.", len(key))
|
||||
}
|
||||
|
||||
if _, err := NewCipher(key[:KeySize-1]); err == nil {
|
||||
t.Errorf("invalid key size %d didn't result in an error.", KeySize-1)
|
||||
}
|
||||
}
|
||||
|
||||
// Test Vectors
|
||||
type teaTest struct {
|
||||
rounds int
|
||||
key []byte
|
||||
plaintext []byte
|
||||
ciphertext []byte
|
||||
}
|
||||
|
||||
var teaTests = []teaTest{
|
||||
// These were sourced from https://github.com/froydnj/ironclad/blob/master/testing/test-vectors/tea.testvec
|
||||
{
|
||||
numRounds,
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x41, 0xea, 0x3a, 0x0a, 0x94, 0xba, 0xa9, 0x40},
|
||||
},
|
||||
{
|
||||
numRounds,
|
||||
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||||
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||||
[]byte{0x31, 0x9b, 0xbe, 0xfb, 0x01, 0x6a, 0xbd, 0xb2},
|
||||
},
|
||||
{
|
||||
16,
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0xed, 0x28, 0x5d, 0xa1, 0x45, 0x5b, 0x33, 0xc1},
|
||||
},
|
||||
}
|
||||
|
||||
// Test encryption
|
||||
func TestCipherEncrypt(t *testing.T) {
|
||||
// Test encryption with standard 64 rounds
|
||||
for i, test := range teaTests {
|
||||
c, err := NewCipherWithRounds(test.key, test.rounds)
|
||||
if err != nil {
|
||||
t.Fatalf("#%d: NewCipher returned error: %s", i, err)
|
||||
}
|
||||
|
||||
var ciphertext [BlockSize]byte
|
||||
c.Encrypt(ciphertext[:], test.plaintext)
|
||||
|
||||
if !bytes.Equal(ciphertext[:], test.ciphertext) {
|
||||
t.Errorf("#%d: incorrect ciphertext. Got %x, wanted %x", i, ciphertext, test.ciphertext)
|
||||
}
|
||||
|
||||
var plaintext2 [BlockSize]byte
|
||||
c.Decrypt(plaintext2[:], ciphertext[:])
|
||||
|
||||
if !bytes.Equal(plaintext2[:], test.plaintext) {
|
||||
t.Errorf("#%d: incorrect plaintext. Got %x, wanted %x", i, plaintext2, test.plaintext)
|
||||
}
|
||||
}
|
||||
}
|
||||
342
vendor/golang.org/x/crypto/twofish/twofish.go
generated
vendored
Normal file
342
vendor/golang.org/x/crypto/twofish/twofish.go
generated
vendored
Normal file
@@ -0,0 +1,342 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package twofish implements Bruce Schneier's Twofish encryption algorithm.
|
||||
package twofish // import "golang.org/x/crypto/twofish"
|
||||
|
||||
// Twofish is defined in http://www.schneier.com/paper-twofish-paper.pdf [TWOFISH]
|
||||
|
||||
// This code is a port of the LibTom C implementation.
|
||||
// See http://libtom.org/?page=features&newsitems=5&whatfile=crypt.
|
||||
// LibTomCrypt is free for all purposes under the public domain.
|
||||
// It was heavily inspired by the go blowfish package.
|
||||
|
||||
import "strconv"
|
||||
|
||||
// BlockSize is the constant block size of Twofish.
|
||||
const BlockSize = 16
|
||||
|
||||
const mdsPolynomial = 0x169 // x^8 + x^6 + x^5 + x^3 + 1, see [TWOFISH] 4.2
|
||||
const rsPolynomial = 0x14d // x^8 + x^6 + x^3 + x^2 + 1, see [TWOFISH] 4.3
|
||||
|
||||
// A Cipher is an instance of Twofish encryption using a particular key.
|
||||
type Cipher struct {
|
||||
s [4][256]uint32
|
||||
k [40]uint32
|
||||
}
|
||||
|
||||
type KeySizeError int
|
||||
|
||||
func (k KeySizeError) Error() string {
|
||||
return "crypto/twofish: invalid key size " + strconv.Itoa(int(k))
|
||||
}
|
||||
|
||||
// NewCipher creates and returns a Cipher.
|
||||
// The key argument should be the Twofish key, 16, 24 or 32 bytes.
|
||||
func NewCipher(key []byte) (*Cipher, error) {
|
||||
keylen := len(key)
|
||||
|
||||
if keylen != 16 && keylen != 24 && keylen != 32 {
|
||||
return nil, KeySizeError(keylen)
|
||||
}
|
||||
|
||||
// k is the number of 64 bit words in key
|
||||
k := keylen / 8
|
||||
|
||||
// Create the S[..] words
|
||||
var S [4 * 4]byte
|
||||
for i := 0; i < k; i++ {
|
||||
// Computes [y0 y1 y2 y3] = rs . [x0 x1 x2 x3 x4 x5 x6 x7]
|
||||
for j, rsRow := range rs {
|
||||
for k, rsVal := range rsRow {
|
||||
S[4*i+j] ^= gfMult(key[8*i+k], rsVal, rsPolynomial)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate subkeys
|
||||
c := new(Cipher)
|
||||
var tmp [4]byte
|
||||
for i := byte(0); i < 20; i++ {
|
||||
// A = h(p * 2x, Me)
|
||||
for j := range tmp {
|
||||
tmp[j] = 2 * i
|
||||
}
|
||||
A := h(tmp[:], key, 0)
|
||||
|
||||
// B = rolc(h(p * (2x + 1), Mo), 8)
|
||||
for j := range tmp {
|
||||
tmp[j] = 2*i + 1
|
||||
}
|
||||
B := h(tmp[:], key, 1)
|
||||
B = rol(B, 8)
|
||||
|
||||
c.k[2*i] = A + B
|
||||
|
||||
// K[2i+1] = (A + 2B) <<< 9
|
||||
c.k[2*i+1] = rol(2*B+A, 9)
|
||||
}
|
||||
|
||||
// Calculate sboxes
|
||||
switch k {
|
||||
case 2:
|
||||
for i := range c.s[0] {
|
||||
c.s[0][i] = mdsColumnMult(sbox[1][sbox[0][sbox[0][byte(i)]^S[0]]^S[4]], 0)
|
||||
c.s[1][i] = mdsColumnMult(sbox[0][sbox[0][sbox[1][byte(i)]^S[1]]^S[5]], 1)
|
||||
c.s[2][i] = mdsColumnMult(sbox[1][sbox[1][sbox[0][byte(i)]^S[2]]^S[6]], 2)
|
||||
c.s[3][i] = mdsColumnMult(sbox[0][sbox[1][sbox[1][byte(i)]^S[3]]^S[7]], 3)
|
||||
}
|
||||
case 3:
|
||||
for i := range c.s[0] {
|
||||
c.s[0][i] = mdsColumnMult(sbox[1][sbox[0][sbox[0][sbox[1][byte(i)]^S[0]]^S[4]]^S[8]], 0)
|
||||
c.s[1][i] = mdsColumnMult(sbox[0][sbox[0][sbox[1][sbox[1][byte(i)]^S[1]]^S[5]]^S[9]], 1)
|
||||
c.s[2][i] = mdsColumnMult(sbox[1][sbox[1][sbox[0][sbox[0][byte(i)]^S[2]]^S[6]]^S[10]], 2)
|
||||
c.s[3][i] = mdsColumnMult(sbox[0][sbox[1][sbox[1][sbox[0][byte(i)]^S[3]]^S[7]]^S[11]], 3)
|
||||
}
|
||||
default:
|
||||
for i := range c.s[0] {
|
||||
c.s[0][i] = mdsColumnMult(sbox[1][sbox[0][sbox[0][sbox[1][sbox[1][byte(i)]^S[0]]^S[4]]^S[8]]^S[12]], 0)
|
||||
c.s[1][i] = mdsColumnMult(sbox[0][sbox[0][sbox[1][sbox[1][sbox[0][byte(i)]^S[1]]^S[5]]^S[9]]^S[13]], 1)
|
||||
c.s[2][i] = mdsColumnMult(sbox[1][sbox[1][sbox[0][sbox[0][sbox[0][byte(i)]^S[2]]^S[6]]^S[10]]^S[14]], 2)
|
||||
c.s[3][i] = mdsColumnMult(sbox[0][sbox[1][sbox[1][sbox[0][sbox[1][byte(i)]^S[3]]^S[7]]^S[11]]^S[15]], 3)
|
||||
}
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// BlockSize returns the Twofish block size, 16 bytes.
|
||||
func (c *Cipher) BlockSize() int { return BlockSize }
|
||||
|
||||
// store32l stores src in dst in little-endian form.
|
||||
func store32l(dst []byte, src uint32) {
|
||||
dst[0] = byte(src)
|
||||
dst[1] = byte(src >> 8)
|
||||
dst[2] = byte(src >> 16)
|
||||
dst[3] = byte(src >> 24)
|
||||
return
|
||||
}
|
||||
|
||||
// load32l reads a little-endian uint32 from src.
|
||||
func load32l(src []byte) uint32 {
|
||||
return uint32(src[0]) | uint32(src[1])<<8 | uint32(src[2])<<16 | uint32(src[3])<<24
|
||||
}
|
||||
|
||||
// rol returns x after a left circular rotation of y bits.
|
||||
func rol(x, y uint32) uint32 {
|
||||
return (x << (y & 31)) | (x >> (32 - (y & 31)))
|
||||
}
|
||||
|
||||
// ror returns x after a right circular rotation of y bits.
|
||||
func ror(x, y uint32) uint32 {
|
||||
return (x >> (y & 31)) | (x << (32 - (y & 31)))
|
||||
}
|
||||
|
||||
// The RS matrix. See [TWOFISH] 4.3
|
||||
var rs = [4][8]byte{
|
||||
{0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E},
|
||||
{0xA4, 0x56, 0x82, 0xF3, 0x1E, 0xC6, 0x68, 0xE5},
|
||||
{0x02, 0xA1, 0xFC, 0xC1, 0x47, 0xAE, 0x3D, 0x19},
|
||||
{0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E, 0x03},
|
||||
}
|
||||
|
||||
// sbox tables
|
||||
var sbox = [2][256]byte{
|
||||
{
|
||||
0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92, 0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38,
|
||||
0x0d, 0xc6, 0x35, 0x98, 0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13, 0x94, 0x48,
|
||||
0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23, 0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82,
|
||||
0x63, 0x01, 0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe, 0x16, 0x0c, 0xe3, 0x61,
|
||||
0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c, 0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1,
|
||||
0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95, 0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7,
|
||||
0xfb, 0xc3, 0x8e, 0xb5, 0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9, 0x62, 0x71,
|
||||
0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8, 0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7,
|
||||
0xa1, 0x1d, 0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11, 0x31, 0xc2, 0x27, 0x90,
|
||||
0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c, 0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef,
|
||||
0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87, 0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64,
|
||||
0x2a, 0xce, 0xcb, 0x2f, 0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e, 0xa7, 0x5a,
|
||||
0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02, 0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d,
|
||||
0x57, 0xc7, 0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
|
||||
0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc, 0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4,
|
||||
0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d, 0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0,
|
||||
},
|
||||
{
|
||||
0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3, 0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b,
|
||||
0xd6, 0x32, 0xd8, 0xfd, 0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa, 0x06, 0x3f,
|
||||
0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d, 0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5,
|
||||
0xa0, 0x84, 0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54, 0x92, 0x74, 0x36, 0x51,
|
||||
0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60, 0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c,
|
||||
0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3, 0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8,
|
||||
0xa6, 0x83, 0x20, 0xff, 0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7, 0x2b, 0xe2,
|
||||
0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9, 0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17,
|
||||
0x66, 0x94, 0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c, 0xef, 0xd1, 0x53, 0x3e,
|
||||
0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76, 0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9,
|
||||
0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23, 0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48,
|
||||
0x4f, 0xf2, 0x65, 0x8e, 0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f, 0x05, 0x64,
|
||||
0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5, 0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69,
|
||||
0x29, 0x2e, 0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34, 0x35, 0x6a, 0xcf, 0xdc,
|
||||
0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4, 0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9,
|
||||
0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xbe, 0x91,
|
||||
},
|
||||
}
|
||||
|
||||
// gfMult returns a·b in GF(2^8)/p
|
||||
func gfMult(a, b byte, p uint32) byte {
|
||||
B := [2]uint32{0, uint32(b)}
|
||||
P := [2]uint32{0, p}
|
||||
var result uint32
|
||||
|
||||
// branchless GF multiplier
|
||||
for i := 0; i < 7; i++ {
|
||||
result ^= B[a&1]
|
||||
a >>= 1
|
||||
B[1] = P[B[1]>>7] ^ (B[1] << 1)
|
||||
}
|
||||
result ^= B[a&1]
|
||||
return byte(result)
|
||||
}
|
||||
|
||||
// mdsColumnMult calculates y{col} where [y0 y1 y2 y3] = MDS · [x0]
|
||||
func mdsColumnMult(in byte, col int) uint32 {
|
||||
mul01 := in
|
||||
mul5B := gfMult(in, 0x5B, mdsPolynomial)
|
||||
mulEF := gfMult(in, 0xEF, mdsPolynomial)
|
||||
|
||||
switch col {
|
||||
case 0:
|
||||
return uint32(mul01) | uint32(mul5B)<<8 | uint32(mulEF)<<16 | uint32(mulEF)<<24
|
||||
case 1:
|
||||
return uint32(mulEF) | uint32(mulEF)<<8 | uint32(mul5B)<<16 | uint32(mul01)<<24
|
||||
case 2:
|
||||
return uint32(mul5B) | uint32(mulEF)<<8 | uint32(mul01)<<16 | uint32(mulEF)<<24
|
||||
case 3:
|
||||
return uint32(mul5B) | uint32(mul01)<<8 | uint32(mulEF)<<16 | uint32(mul5B)<<24
|
||||
}
|
||||
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// h implements the S-box generation function. See [TWOFISH] 4.3.5
|
||||
func h(in, key []byte, offset int) uint32 {
|
||||
var y [4]byte
|
||||
for x := range y {
|
||||
y[x] = in[x]
|
||||
}
|
||||
switch len(key) / 8 {
|
||||
case 4:
|
||||
y[0] = sbox[1][y[0]] ^ key[4*(6+offset)+0]
|
||||
y[1] = sbox[0][y[1]] ^ key[4*(6+offset)+1]
|
||||
y[2] = sbox[0][y[2]] ^ key[4*(6+offset)+2]
|
||||
y[3] = sbox[1][y[3]] ^ key[4*(6+offset)+3]
|
||||
fallthrough
|
||||
case 3:
|
||||
y[0] = sbox[1][y[0]] ^ key[4*(4+offset)+0]
|
||||
y[1] = sbox[1][y[1]] ^ key[4*(4+offset)+1]
|
||||
y[2] = sbox[0][y[2]] ^ key[4*(4+offset)+2]
|
||||
y[3] = sbox[0][y[3]] ^ key[4*(4+offset)+3]
|
||||
fallthrough
|
||||
case 2:
|
||||
y[0] = sbox[1][sbox[0][sbox[0][y[0]]^key[4*(2+offset)+0]]^key[4*(0+offset)+0]]
|
||||
y[1] = sbox[0][sbox[0][sbox[1][y[1]]^key[4*(2+offset)+1]]^key[4*(0+offset)+1]]
|
||||
y[2] = sbox[1][sbox[1][sbox[0][y[2]]^key[4*(2+offset)+2]]^key[4*(0+offset)+2]]
|
||||
y[3] = sbox[0][sbox[1][sbox[1][y[3]]^key[4*(2+offset)+3]]^key[4*(0+offset)+3]]
|
||||
}
|
||||
// [y0 y1 y2 y3] = MDS . [x0 x1 x2 x3]
|
||||
var mdsMult uint32
|
||||
for i := range y {
|
||||
mdsMult ^= mdsColumnMult(y[i], i)
|
||||
}
|
||||
return mdsMult
|
||||
}
|
||||
|
||||
// Encrypt encrypts a 16-byte block from src to dst, which may overlap.
|
||||
// Note that for amounts of data larger than a block,
|
||||
// it is not safe to just call Encrypt on successive blocks;
|
||||
// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
|
||||
func (c *Cipher) Encrypt(dst, src []byte) {
|
||||
S1 := c.s[0]
|
||||
S2 := c.s[1]
|
||||
S3 := c.s[2]
|
||||
S4 := c.s[3]
|
||||
|
||||
// Load input
|
||||
ia := load32l(src[0:4])
|
||||
ib := load32l(src[4:8])
|
||||
ic := load32l(src[8:12])
|
||||
id := load32l(src[12:16])
|
||||
|
||||
// Pre-whitening
|
||||
ia ^= c.k[0]
|
||||
ib ^= c.k[1]
|
||||
ic ^= c.k[2]
|
||||
id ^= c.k[3]
|
||||
|
||||
for i := 0; i < 8; i++ {
|
||||
k := c.k[8+i*4 : 12+i*4]
|
||||
t2 := S2[byte(ib)] ^ S3[byte(ib>>8)] ^ S4[byte(ib>>16)] ^ S1[byte(ib>>24)]
|
||||
t1 := S1[byte(ia)] ^ S2[byte(ia>>8)] ^ S3[byte(ia>>16)] ^ S4[byte(ia>>24)] + t2
|
||||
ic = ror(ic^(t1+k[0]), 1)
|
||||
id = rol(id, 1) ^ (t2 + t1 + k[1])
|
||||
|
||||
t2 = S2[byte(id)] ^ S3[byte(id>>8)] ^ S4[byte(id>>16)] ^ S1[byte(id>>24)]
|
||||
t1 = S1[byte(ic)] ^ S2[byte(ic>>8)] ^ S3[byte(ic>>16)] ^ S4[byte(ic>>24)] + t2
|
||||
ia = ror(ia^(t1+k[2]), 1)
|
||||
ib = rol(ib, 1) ^ (t2 + t1 + k[3])
|
||||
}
|
||||
|
||||
// Output with "undo last swap"
|
||||
ta := ic ^ c.k[4]
|
||||
tb := id ^ c.k[5]
|
||||
tc := ia ^ c.k[6]
|
||||
td := ib ^ c.k[7]
|
||||
|
||||
store32l(dst[0:4], ta)
|
||||
store32l(dst[4:8], tb)
|
||||
store32l(dst[8:12], tc)
|
||||
store32l(dst[12:16], td)
|
||||
}
|
||||
|
||||
// Decrypt decrypts a 16-byte block from src to dst, which may overlap.
|
||||
func (c *Cipher) Decrypt(dst, src []byte) {
|
||||
S1 := c.s[0]
|
||||
S2 := c.s[1]
|
||||
S3 := c.s[2]
|
||||
S4 := c.s[3]
|
||||
|
||||
// Load input
|
||||
ta := load32l(src[0:4])
|
||||
tb := load32l(src[4:8])
|
||||
tc := load32l(src[8:12])
|
||||
td := load32l(src[12:16])
|
||||
|
||||
// Undo undo final swap
|
||||
ia := tc ^ c.k[6]
|
||||
ib := td ^ c.k[7]
|
||||
ic := ta ^ c.k[4]
|
||||
id := tb ^ c.k[5]
|
||||
|
||||
for i := 8; i > 0; i-- {
|
||||
k := c.k[4+i*4 : 8+i*4]
|
||||
t2 := S2[byte(id)] ^ S3[byte(id>>8)] ^ S4[byte(id>>16)] ^ S1[byte(id>>24)]
|
||||
t1 := S1[byte(ic)] ^ S2[byte(ic>>8)] ^ S3[byte(ic>>16)] ^ S4[byte(ic>>24)] + t2
|
||||
ia = rol(ia, 1) ^ (t1 + k[2])
|
||||
ib = ror(ib^(t2+t1+k[3]), 1)
|
||||
|
||||
t2 = S2[byte(ib)] ^ S3[byte(ib>>8)] ^ S4[byte(ib>>16)] ^ S1[byte(ib>>24)]
|
||||
t1 = S1[byte(ia)] ^ S2[byte(ia>>8)] ^ S3[byte(ia>>16)] ^ S4[byte(ia>>24)] + t2
|
||||
ic = rol(ic, 1) ^ (t1 + k[0])
|
||||
id = ror(id^(t2+t1+k[1]), 1)
|
||||
}
|
||||
|
||||
// Undo pre-whitening
|
||||
ia ^= c.k[0]
|
||||
ib ^= c.k[1]
|
||||
ic ^= c.k[2]
|
||||
id ^= c.k[3]
|
||||
|
||||
store32l(dst[0:4], ia)
|
||||
store32l(dst[4:8], ib)
|
||||
store32l(dst[8:12], ic)
|
||||
store32l(dst[12:16], id)
|
||||
}
|
||||
129
vendor/golang.org/x/crypto/twofish/twofish_test.go
generated
vendored
Normal file
129
vendor/golang.org/x/crypto/twofish/twofish_test.go
generated
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package twofish
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var qbox = [2][4][16]byte{
|
||||
{
|
||||
{0x8, 0x1, 0x7, 0xD, 0x6, 0xF, 0x3, 0x2, 0x0, 0xB, 0x5, 0x9, 0xE, 0xC, 0xA, 0x4},
|
||||
{0xE, 0xC, 0xB, 0x8, 0x1, 0x2, 0x3, 0x5, 0xF, 0x4, 0xA, 0x6, 0x7, 0x0, 0x9, 0xD},
|
||||
{0xB, 0xA, 0x5, 0xE, 0x6, 0xD, 0x9, 0x0, 0xC, 0x8, 0xF, 0x3, 0x2, 0x4, 0x7, 0x1},
|
||||
{0xD, 0x7, 0xF, 0x4, 0x1, 0x2, 0x6, 0xE, 0x9, 0xB, 0x3, 0x0, 0x8, 0x5, 0xC, 0xA},
|
||||
},
|
||||
{
|
||||
{0x2, 0x8, 0xB, 0xD, 0xF, 0x7, 0x6, 0xE, 0x3, 0x1, 0x9, 0x4, 0x0, 0xA, 0xC, 0x5},
|
||||
{0x1, 0xE, 0x2, 0xB, 0x4, 0xC, 0x3, 0x7, 0x6, 0xD, 0xA, 0x5, 0xF, 0x9, 0x0, 0x8},
|
||||
{0x4, 0xC, 0x7, 0x5, 0x1, 0x6, 0x9, 0xA, 0x0, 0xE, 0xD, 0x8, 0x2, 0xB, 0x3, 0xF},
|
||||
{0xB, 0x9, 0x5, 0x1, 0xC, 0x3, 0xD, 0xE, 0x6, 0x4, 0x7, 0xF, 0x2, 0x0, 0x8, 0xA},
|
||||
},
|
||||
}
|
||||
|
||||
// genSbox generates the variable sbox
|
||||
func genSbox(qi int, x byte) byte {
|
||||
a0, b0 := x/16, x%16
|
||||
for i := 0; i < 2; i++ {
|
||||
a1 := a0 ^ b0
|
||||
b1 := (a0 ^ ((b0 << 3) | (b0 >> 1)) ^ (a0 << 3)) & 15
|
||||
a0 = qbox[qi][2*i][a1]
|
||||
b0 = qbox[qi][2*i+1][b1]
|
||||
}
|
||||
return (b0 << 4) + a0
|
||||
}
|
||||
|
||||
func TestSbox(t *testing.T) {
|
||||
for n := range sbox {
|
||||
for m := range sbox[n] {
|
||||
if genSbox(n, byte(m)) != sbox[n][m] {
|
||||
t.Errorf("#%d|%d: sbox value = %d want %d", n, m, sbox[n][m], genSbox(n, byte(m)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var testVectors = []struct {
|
||||
key []byte
|
||||
dec []byte
|
||||
enc []byte
|
||||
}{
|
||||
// These tests are extracted from LibTom
|
||||
{
|
||||
[]byte{0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A},
|
||||
[]byte{0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E, 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19},
|
||||
[]byte{0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85, 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3},
|
||||
},
|
||||
{
|
||||
[]byte{0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36, 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88,
|
||||
0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44},
|
||||
[]byte{0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2},
|
||||
[]byte{0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65},
|
||||
},
|
||||
{
|
||||
[]byte{0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
|
||||
0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F},
|
||||
[]byte{0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6},
|
||||
[]byte{0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA},
|
||||
},
|
||||
// These test are derived from http://www.schneier.com/code/ecb_ival.txt
|
||||
{
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A},
|
||||
},
|
||||
{
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
},
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0xCF, 0xD1, 0xD2, 0xE5, 0xA9, 0xBE, 0x9C, 0xDF, 0x50, 0x1F, 0x13, 0xB8, 0x92, 0xBD, 0x22, 0x48},
|
||||
},
|
||||
{
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||
},
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x37, 0x52, 0x7B, 0xE0, 0x05, 0x23, 0x34, 0xB8, 0x9F, 0x0C, 0xFC, 0xCA, 0xE8, 0x7C, 0xFA, 0x20},
|
||||
},
|
||||
}
|
||||
|
||||
func TestCipher(t *testing.T) {
|
||||
for n, tt := range testVectors {
|
||||
// Test if the plaintext (dec) is encrypts to the given
|
||||
// ciphertext (enc) using the given key. Test also if enc can
|
||||
// be decrypted again into dec.
|
||||
c, err := NewCipher(tt.key)
|
||||
if err != nil {
|
||||
t.Errorf("#%d: NewCipher: %v", n, err)
|
||||
return
|
||||
}
|
||||
|
||||
buf := make([]byte, 16)
|
||||
c.Encrypt(buf, tt.dec)
|
||||
if !bytes.Equal(buf, tt.enc) {
|
||||
t.Errorf("#%d: encrypt = %x want %x", n, buf, tt.enc)
|
||||
}
|
||||
c.Decrypt(buf, tt.enc)
|
||||
if !bytes.Equal(buf, tt.dec) {
|
||||
t.Errorf("#%d: decrypt = %x want %x", n, buf, tt.dec)
|
||||
}
|
||||
|
||||
// Test that 16 zero bytes, encrypted 1000 times then decrypted
|
||||
// 1000 times results in zero bytes again.
|
||||
zero := make([]byte, 16)
|
||||
buf = make([]byte, 16)
|
||||
for i := 0; i < 1000; i++ {
|
||||
c.Encrypt(buf, buf)
|
||||
}
|
||||
for i := 0; i < 1000; i++ {
|
||||
c.Decrypt(buf, buf)
|
||||
}
|
||||
if !bytes.Equal(buf, zero) {
|
||||
t.Errorf("#%d: encrypt/decrypt 1000: have %x want %x", n, buf, zero)
|
||||
}
|
||||
}
|
||||
}
|
||||
66
vendor/golang.org/x/crypto/xtea/block.go
generated
vendored
Normal file
66
vendor/golang.org/x/crypto/xtea/block.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Implementation adapted from Needham and Wheeler's paper:
|
||||
http://www.cix.co.uk/~klockstone/xtea.pdf
|
||||
|
||||
A precalculated look up table is used during encryption/decryption for values that are based purely on the key.
|
||||
*/
|
||||
|
||||
package xtea
|
||||
|
||||
// XTEA is based on 64 rounds.
|
||||
const numRounds = 64
|
||||
|
||||
// blockToUint32 reads an 8 byte slice into two uint32s.
|
||||
// The block is treated as big endian.
|
||||
func blockToUint32(src []byte) (uint32, uint32) {
|
||||
r0 := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
|
||||
r1 := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// uint32ToBlock writes two uint32s into an 8 byte data block.
|
||||
// Values are written as big endian.
|
||||
func uint32ToBlock(v0, v1 uint32, dst []byte) {
|
||||
dst[0] = byte(v0 >> 24)
|
||||
dst[1] = byte(v0 >> 16)
|
||||
dst[2] = byte(v0 >> 8)
|
||||
dst[3] = byte(v0)
|
||||
dst[4] = byte(v1 >> 24)
|
||||
dst[5] = byte(v1 >> 16)
|
||||
dst[6] = byte(v1 >> 8)
|
||||
dst[7] = byte(v1 >> 0)
|
||||
}
|
||||
|
||||
// encryptBlock encrypts a single 8 byte block using XTEA.
|
||||
func encryptBlock(c *Cipher, dst, src []byte) {
|
||||
v0, v1 := blockToUint32(src)
|
||||
|
||||
// Two rounds of XTEA applied per loop
|
||||
for i := 0; i < numRounds; {
|
||||
v0 += ((v1<<4 ^ v1>>5) + v1) ^ c.table[i]
|
||||
i++
|
||||
v1 += ((v0<<4 ^ v0>>5) + v0) ^ c.table[i]
|
||||
i++
|
||||
}
|
||||
|
||||
uint32ToBlock(v0, v1, dst)
|
||||
}
|
||||
|
||||
// decryptBlock decrypt a single 8 byte block using XTEA.
|
||||
func decryptBlock(c *Cipher, dst, src []byte) {
|
||||
v0, v1 := blockToUint32(src)
|
||||
|
||||
// Two rounds of XTEA applied per loop
|
||||
for i := numRounds; i > 0; {
|
||||
i--
|
||||
v1 -= ((v0<<4 ^ v0>>5) + v0) ^ c.table[i]
|
||||
i--
|
||||
v0 -= ((v1<<4 ^ v1>>5) + v1) ^ c.table[i]
|
||||
}
|
||||
|
||||
uint32ToBlock(v0, v1, dst)
|
||||
}
|
||||
82
vendor/golang.org/x/crypto/xtea/cipher.go
generated
vendored
Normal file
82
vendor/golang.org/x/crypto/xtea/cipher.go
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package xtea implements XTEA encryption, as defined in Needham and Wheeler's
|
||||
// 1997 technical report, "Tea extensions."
|
||||
package xtea // import "golang.org/x/crypto/xtea"
|
||||
|
||||
// For details, see http://www.cix.co.uk/~klockstone/xtea.pdf
|
||||
|
||||
import "strconv"
|
||||
|
||||
// The XTEA block size in bytes.
|
||||
const BlockSize = 8
|
||||
|
||||
// A Cipher is an instance of an XTEA cipher using a particular key.
|
||||
// table contains a series of precalculated values that are used each round.
|
||||
type Cipher struct {
|
||||
table [64]uint32
|
||||
}
|
||||
|
||||
type KeySizeError int
|
||||
|
||||
func (k KeySizeError) Error() string {
|
||||
return "crypto/xtea: invalid key size " + strconv.Itoa(int(k))
|
||||
}
|
||||
|
||||
// NewCipher creates and returns a new Cipher.
|
||||
// The key argument should be the XTEA key.
|
||||
// XTEA only supports 128 bit (16 byte) keys.
|
||||
func NewCipher(key []byte) (*Cipher, error) {
|
||||
k := len(key)
|
||||
switch k {
|
||||
default:
|
||||
return nil, KeySizeError(k)
|
||||
case 16:
|
||||
break
|
||||
}
|
||||
|
||||
c := new(Cipher)
|
||||
initCipher(c, key)
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// BlockSize returns the XTEA block size, 8 bytes.
|
||||
// It is necessary to satisfy the Block interface in the
|
||||
// package "crypto/cipher".
|
||||
func (c *Cipher) BlockSize() int { return BlockSize }
|
||||
|
||||
// Encrypt encrypts the 8 byte buffer src using the key and stores the result in dst.
|
||||
// Note that for amounts of data larger than a block,
|
||||
// it is not safe to just call Encrypt on successive blocks;
|
||||
// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
|
||||
func (c *Cipher) Encrypt(dst, src []byte) { encryptBlock(c, dst, src) }
|
||||
|
||||
// Decrypt decrypts the 8 byte buffer src using the key k and stores the result in dst.
|
||||
func (c *Cipher) Decrypt(dst, src []byte) { decryptBlock(c, dst, src) }
|
||||
|
||||
// initCipher initializes the cipher context by creating a look up table
|
||||
// of precalculated values that are based on the key.
|
||||
func initCipher(c *Cipher, key []byte) {
|
||||
// Load the key into four uint32s
|
||||
var k [4]uint32
|
||||
for i := 0; i < len(k); i++ {
|
||||
j := i << 2 // Multiply by 4
|
||||
k[i] = uint32(key[j+0])<<24 | uint32(key[j+1])<<16 | uint32(key[j+2])<<8 | uint32(key[j+3])
|
||||
}
|
||||
|
||||
// Precalculate the table
|
||||
const delta = 0x9E3779B9
|
||||
var sum uint32 = 0
|
||||
|
||||
// Two rounds of XTEA applied per loop
|
||||
for i := 0; i < numRounds; {
|
||||
c.table[i] = sum + k[sum&3]
|
||||
i++
|
||||
sum += delta
|
||||
c.table[i] = sum + k[(sum>>11)&3]
|
||||
i++
|
||||
}
|
||||
}
|
||||
229
vendor/golang.org/x/crypto/xtea/xtea_test.go
generated
vendored
Normal file
229
vendor/golang.org/x/crypto/xtea/xtea_test.go
generated
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xtea
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// A sample test key for when we just want to initialize a cipher
|
||||
var testKey = []byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}
|
||||
|
||||
// Test that the block size for XTEA is correct
|
||||
func TestBlocksize(t *testing.T) {
|
||||
if BlockSize != 8 {
|
||||
t.Errorf("BlockSize constant - expected 8, got %d", BlockSize)
|
||||
return
|
||||
}
|
||||
|
||||
c, err := NewCipher(testKey)
|
||||
if err != nil {
|
||||
t.Errorf("NewCipher(%d bytes) = %s", len(testKey), err)
|
||||
return
|
||||
}
|
||||
|
||||
result := c.BlockSize()
|
||||
if result != 8 {
|
||||
t.Errorf("BlockSize function - expected 8, got %d", result)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// A series of test values to confirm that the Cipher.table array was initialized correctly
|
||||
var testTable = []uint32{
|
||||
0x00112233, 0x6B1568B8, 0xE28CE030, 0xC5089E2D, 0xC5089E2D, 0x1EFBD3A2, 0xA7845C2A, 0x78EF0917,
|
||||
0x78EF0917, 0x172682D0, 0x5B6AC714, 0x822AC955, 0x3DE68511, 0xDC1DFECA, 0x2062430E, 0x3611343F,
|
||||
0xF1CCEFFB, 0x900469B4, 0xD448ADF8, 0x2E3BE36D, 0xB6C46BF5, 0x994029F2, 0x994029F2, 0xF3335F67,
|
||||
0x6AAAD6DF, 0x4D2694DC, 0x4D2694DC, 0xEB5E0E95, 0x2FA252D9, 0x4551440A, 0x121E10D6, 0xB0558A8F,
|
||||
0xE388BDC3, 0x0A48C004, 0xC6047BC0, 0x643BF579, 0xA88039BD, 0x02736F32, 0x8AFBF7BA, 0x5C66A4A7,
|
||||
0x5C66A4A7, 0xC76AEB2C, 0x3EE262A4, 0x215E20A1, 0x215E20A1, 0x7B515616, 0x03D9DE9E, 0x1988CFCF,
|
||||
0xD5448B8B, 0x737C0544, 0xB7C04988, 0xDE804BC9, 0x9A3C0785, 0x3873813E, 0x7CB7C582, 0xD6AAFAF7,
|
||||
0x4E22726F, 0x309E306C, 0x309E306C, 0x8A9165E1, 0x1319EE69, 0xF595AC66, 0xF595AC66, 0x4F88E1DB,
|
||||
}
|
||||
|
||||
// Test that the cipher context is initialized correctly
|
||||
func TestCipherInit(t *testing.T) {
|
||||
c, err := NewCipher(testKey)
|
||||
if err != nil {
|
||||
t.Errorf("NewCipher(%d bytes) = %s", len(testKey), err)
|
||||
return
|
||||
}
|
||||
|
||||
for i := 0; i < len(c.table); i++ {
|
||||
if c.table[i] != testTable[i] {
|
||||
t.Errorf("NewCipher() failed to initialize Cipher.table[%d] correctly. Expected %08X, got %08X", i, testTable[i], c.table[i])
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test that invalid key sizes return an error
|
||||
func TestInvalidKeySize(t *testing.T) {
|
||||
// Test a long key
|
||||
key := []byte{
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
|
||||
}
|
||||
|
||||
_, err := NewCipher(key)
|
||||
if err == nil {
|
||||
t.Errorf("Invalid key size %d didn't result in an error.", len(key))
|
||||
}
|
||||
|
||||
// Test a short key
|
||||
key = []byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}
|
||||
|
||||
_, err = NewCipher(key)
|
||||
if err == nil {
|
||||
t.Errorf("Invalid key size %d didn't result in an error.", len(key))
|
||||
}
|
||||
}
|
||||
|
||||
// Test that we can correctly decode some bytes we have encoded
|
||||
func TestEncodeDecode(t *testing.T) {
|
||||
original := []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}
|
||||
input := original
|
||||
output := make([]byte, BlockSize)
|
||||
|
||||
c, err := NewCipher(testKey)
|
||||
if err != nil {
|
||||
t.Errorf("NewCipher(%d bytes) = %s", len(testKey), err)
|
||||
return
|
||||
}
|
||||
|
||||
// Encrypt the input block
|
||||
c.Encrypt(output, input)
|
||||
|
||||
// Check that the output does not match the input
|
||||
differs := false
|
||||
for i := 0; i < len(input); i++ {
|
||||
if output[i] != input[i] {
|
||||
differs = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if differs == false {
|
||||
t.Error("Cipher.Encrypt: Failed to encrypt the input block.")
|
||||
return
|
||||
}
|
||||
|
||||
// Decrypt the block we just encrypted
|
||||
input = output
|
||||
output = make([]byte, BlockSize)
|
||||
c.Decrypt(output, input)
|
||||
|
||||
// Check that the output from decrypt matches our initial input
|
||||
for i := 0; i < len(input); i++ {
|
||||
if output[i] != original[i] {
|
||||
t.Errorf("Decrypted byte %d differed. Expected %02X, got %02X\n", i, original[i], output[i])
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test Vectors
|
||||
type CryptTest struct {
|
||||
key []byte
|
||||
plainText []byte
|
||||
cipherText []byte
|
||||
}
|
||||
|
||||
var CryptTests = []CryptTest{
|
||||
// These were sourced from http://www.freemedialibrary.com/index.php/XTEA_test_vectors
|
||||
{
|
||||
[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
|
||||
[]byte{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48},
|
||||
[]byte{0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5},
|
||||
},
|
||||
{
|
||||
[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
|
||||
[]byte{0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41},
|
||||
[]byte{0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8},
|
||||
},
|
||||
{
|
||||
[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
|
||||
[]byte{0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f},
|
||||
[]byte{0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41},
|
||||
},
|
||||
{
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48},
|
||||
[]byte{0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5},
|
||||
},
|
||||
{
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41},
|
||||
[]byte{0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d},
|
||||
},
|
||||
{
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55},
|
||||
[]byte{0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41},
|
||||
},
|
||||
|
||||
// These vectors are from http://wiki.secondlife.com/wiki/XTEA_Strong_Encryption_Implementation#Bouncy_Castle_C.23_API
|
||||
{
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0xDE, 0xE9, 0xD4, 0xD8, 0xF7, 0x13, 0x1E, 0xD9},
|
||||
},
|
||||
{
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},
|
||||
[]byte{0x06, 0x5C, 0x1B, 0x89, 0x75, 0xC6, 0xA8, 0x16},
|
||||
},
|
||||
{
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A},
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x1F, 0xF9, 0xA0, 0x26, 0x1A, 0xC6, 0x42, 0x64},
|
||||
},
|
||||
{
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A},
|
||||
[]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},
|
||||
[]byte{0x8C, 0x67, 0x15, 0x5B, 0x2E, 0xF9, 0x1E, 0xAD},
|
||||
},
|
||||
}
|
||||
|
||||
// Test encryption
|
||||
func TestCipherEncrypt(t *testing.T) {
|
||||
for i, tt := range CryptTests {
|
||||
c, err := NewCipher(tt.key)
|
||||
if err != nil {
|
||||
t.Errorf("NewCipher(%d bytes), vector %d = %s", len(tt.key), i, err)
|
||||
continue
|
||||
}
|
||||
|
||||
out := make([]byte, len(tt.plainText))
|
||||
c.Encrypt(out, tt.plainText)
|
||||
|
||||
for j := 0; j < len(out); j++ {
|
||||
if out[j] != tt.cipherText[j] {
|
||||
t.Errorf("Cipher.Encrypt %d: out[%d] = %02X, expected %02X", i, j, out[j], tt.cipherText[j])
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test decryption
|
||||
func TestCipherDecrypt(t *testing.T) {
|
||||
for i, tt := range CryptTests {
|
||||
c, err := NewCipher(tt.key)
|
||||
if err != nil {
|
||||
t.Errorf("NewCipher(%d bytes), vector %d = %s", len(tt.key), i, err)
|
||||
continue
|
||||
}
|
||||
|
||||
out := make([]byte, len(tt.cipherText))
|
||||
c.Decrypt(out, tt.cipherText)
|
||||
|
||||
for j := 0; j < len(out); j++ {
|
||||
if out[j] != tt.plainText[j] {
|
||||
t.Errorf("Cipher.Decrypt %d: out[%d] = %02X, expected %02X", i, j, out[j], tt.plainText[j])
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
184
vendor/golang.org/x/net/bpf/instructions_test.go
generated
vendored
Normal file
184
vendor/golang.org/x/net/bpf/instructions_test.go
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bpf
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// This is a direct translation of the program in
|
||||
// testdata/all_instructions.txt.
|
||||
var allInstructions = []Instruction{
|
||||
LoadConstant{Dst: RegA, Val: 42},
|
||||
LoadConstant{Dst: RegX, Val: 42},
|
||||
|
||||
LoadScratch{Dst: RegA, N: 3},
|
||||
LoadScratch{Dst: RegX, N: 3},
|
||||
|
||||
LoadAbsolute{Off: 42, Size: 1},
|
||||
LoadAbsolute{Off: 42, Size: 2},
|
||||
LoadAbsolute{Off: 42, Size: 4},
|
||||
|
||||
LoadIndirect{Off: 42, Size: 1},
|
||||
LoadIndirect{Off: 42, Size: 2},
|
||||
LoadIndirect{Off: 42, Size: 4},
|
||||
|
||||
LoadMemShift{Off: 42},
|
||||
|
||||
LoadExtension{Num: ExtLen},
|
||||
LoadExtension{Num: ExtProto},
|
||||
LoadExtension{Num: ExtType},
|
||||
LoadExtension{Num: ExtRand},
|
||||
|
||||
StoreScratch{Src: RegA, N: 3},
|
||||
StoreScratch{Src: RegX, N: 3},
|
||||
|
||||
ALUOpConstant{Op: ALUOpAdd, Val: 42},
|
||||
ALUOpConstant{Op: ALUOpSub, Val: 42},
|
||||
ALUOpConstant{Op: ALUOpMul, Val: 42},
|
||||
ALUOpConstant{Op: ALUOpDiv, Val: 42},
|
||||
ALUOpConstant{Op: ALUOpOr, Val: 42},
|
||||
ALUOpConstant{Op: ALUOpAnd, Val: 42},
|
||||
ALUOpConstant{Op: ALUOpShiftLeft, Val: 42},
|
||||
ALUOpConstant{Op: ALUOpShiftRight, Val: 42},
|
||||
ALUOpConstant{Op: ALUOpMod, Val: 42},
|
||||
ALUOpConstant{Op: ALUOpXor, Val: 42},
|
||||
|
||||
ALUOpX{Op: ALUOpAdd},
|
||||
ALUOpX{Op: ALUOpSub},
|
||||
ALUOpX{Op: ALUOpMul},
|
||||
ALUOpX{Op: ALUOpDiv},
|
||||
ALUOpX{Op: ALUOpOr},
|
||||
ALUOpX{Op: ALUOpAnd},
|
||||
ALUOpX{Op: ALUOpShiftLeft},
|
||||
ALUOpX{Op: ALUOpShiftRight},
|
||||
ALUOpX{Op: ALUOpMod},
|
||||
ALUOpX{Op: ALUOpXor},
|
||||
|
||||
NegateA{},
|
||||
|
||||
Jump{Skip: 10},
|
||||
JumpIf{Cond: JumpEqual, Val: 42, SkipTrue: 8, SkipFalse: 9},
|
||||
JumpIf{Cond: JumpNotEqual, Val: 42, SkipTrue: 8},
|
||||
JumpIf{Cond: JumpLessThan, Val: 42, SkipTrue: 7},
|
||||
JumpIf{Cond: JumpLessOrEqual, Val: 42, SkipTrue: 6},
|
||||
JumpIf{Cond: JumpGreaterThan, Val: 42, SkipTrue: 4, SkipFalse: 5},
|
||||
JumpIf{Cond: JumpGreaterOrEqual, Val: 42, SkipTrue: 3, SkipFalse: 4},
|
||||
JumpIf{Cond: JumpBitsSet, Val: 42, SkipTrue: 2, SkipFalse: 3},
|
||||
|
||||
TAX{},
|
||||
TXA{},
|
||||
|
||||
RetA{},
|
||||
RetConstant{Val: 42},
|
||||
}
|
||||
var allInstructionsExpected = "testdata/all_instructions.bpf"
|
||||
|
||||
// Check that we produce the same output as the canonical bpf_asm
|
||||
// linux kernel tool.
|
||||
func TestInterop(t *testing.T) {
|
||||
out, err := Assemble(allInstructions)
|
||||
if err != nil {
|
||||
t.Fatalf("assembly of allInstructions program failed: %s", err)
|
||||
}
|
||||
t.Logf("Assembled program is %d instructions long", len(out))
|
||||
|
||||
bs, err := ioutil.ReadFile(allInstructionsExpected)
|
||||
if err != nil {
|
||||
t.Fatalf("reading %s: %s", allInstructionsExpected, err)
|
||||
}
|
||||
// First statement is the number of statements, last statement is
|
||||
// empty. We just ignore both and rely on slice length.
|
||||
stmts := strings.Split(string(bs), ",")
|
||||
if len(stmts)-2 != len(out) {
|
||||
t.Fatalf("test program lengths don't match: %s has %d, Go implementation has %d", allInstructionsExpected, len(stmts)-2, len(allInstructions))
|
||||
}
|
||||
|
||||
for i, stmt := range stmts[1 : len(stmts)-2] {
|
||||
nums := strings.Split(stmt, " ")
|
||||
if len(nums) != 4 {
|
||||
t.Fatalf("malformed instruction %d in %s: %s", i+1, allInstructionsExpected, stmt)
|
||||
}
|
||||
|
||||
actual := out[i]
|
||||
|
||||
op, err := strconv.ParseUint(nums[0], 10, 16)
|
||||
if err != nil {
|
||||
t.Fatalf("malformed opcode %s in instruction %d of %s", nums[0], i+1, allInstructionsExpected)
|
||||
}
|
||||
if actual.Op != uint16(op) {
|
||||
t.Errorf("opcode mismatch on instruction %d (%#v): got 0x%02x, want 0x%02x", i+1, allInstructions[i], actual.Op, op)
|
||||
}
|
||||
|
||||
jt, err := strconv.ParseUint(nums[1], 10, 8)
|
||||
if err != nil {
|
||||
t.Fatalf("malformed jt offset %s in instruction %d of %s", nums[1], i+1, allInstructionsExpected)
|
||||
}
|
||||
if actual.Jt != uint8(jt) {
|
||||
t.Errorf("jt mismatch on instruction %d (%#v): got %d, want %d", i+1, allInstructions[i], actual.Jt, jt)
|
||||
}
|
||||
|
||||
jf, err := strconv.ParseUint(nums[2], 10, 8)
|
||||
if err != nil {
|
||||
t.Fatalf("malformed jf offset %s in instruction %d of %s", nums[2], i+1, allInstructionsExpected)
|
||||
}
|
||||
if actual.Jf != uint8(jf) {
|
||||
t.Errorf("jf mismatch on instruction %d (%#v): got %d, want %d", i+1, allInstructions[i], actual.Jf, jf)
|
||||
}
|
||||
|
||||
k, err := strconv.ParseUint(nums[3], 10, 32)
|
||||
if err != nil {
|
||||
t.Fatalf("malformed constant %s in instruction %d of %s", nums[3], i+1, allInstructionsExpected)
|
||||
}
|
||||
if actual.K != uint32(k) {
|
||||
t.Errorf("constant mismatch on instruction %d (%#v): got %d, want %d", i+1, allInstructions[i], actual.K, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that assembly and disassembly match each other.
|
||||
//
|
||||
// Because we offer "fake" jump conditions that don't appear in the
|
||||
// machine code, disassembly won't be a 1:1 match with the original
|
||||
// source, although the behavior will be identical. However,
|
||||
// reassembling the disassembly should produce an identical program.
|
||||
func TestAsmDisasm(t *testing.T) {
|
||||
prog1, err := Assemble(allInstructions)
|
||||
if err != nil {
|
||||
t.Fatalf("assembly of allInstructions program failed: %s", err)
|
||||
}
|
||||
t.Logf("Assembled program is %d instructions long", len(prog1))
|
||||
|
||||
src, allDecoded := Disassemble(prog1)
|
||||
if !allDecoded {
|
||||
t.Errorf("Disassemble(Assemble(allInstructions)) produced unrecognized instructions:")
|
||||
for i, inst := range src {
|
||||
if r, ok := inst.(RawInstruction); ok {
|
||||
t.Logf(" insn %d, %#v --> %#v", i+1, allInstructions[i], r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prog2, err := Assemble(src)
|
||||
if err != nil {
|
||||
t.Fatalf("assembly of Disassemble(Assemble(allInstructions)) failed: %s", err)
|
||||
}
|
||||
|
||||
if len(prog2) != len(prog1) {
|
||||
t.Fatalf("disassembly changed program size: %d insns before, %d insns after", len(prog1), len(prog2))
|
||||
}
|
||||
if !reflect.DeepEqual(prog1, prog2) {
|
||||
t.Errorf("program mutated by disassembly:")
|
||||
for i := range prog2 {
|
||||
if !reflect.DeepEqual(prog1[i], prog2[i]) {
|
||||
t.Logf(" insn %d, s: %#v, p1: %#v, p2: %#v", i+1, allInstructions[i], prog1[i], prog2[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
vendor/golang.org/x/net/bpf/testdata/all_instructions.bpf
generated
vendored
Normal file
1
vendor/golang.org/x/net/bpf/testdata/all_instructions.bpf
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
50,0 0 0 42,1 0 0 42,96 0 0 3,97 0 0 3,48 0 0 42,40 0 0 42,32 0 0 42,80 0 0 42,72 0 0 42,64 0 0 42,177 0 0 42,128 0 0 0,32 0 0 4294963200,32 0 0 4294963204,32 0 0 4294963256,2 0 0 3,3 0 0 3,4 0 0 42,20 0 0 42,36 0 0 42,52 0 0 42,68 0 0 42,84 0 0 42,100 0 0 42,116 0 0 42,148 0 0 42,164 0 0 42,12 0 0 0,28 0 0 0,44 0 0 0,60 0 0 0,76 0 0 0,92 0 0 0,108 0 0 0,124 0 0 0,156 0 0 0,172 0 0 0,132 0 0 0,5 0 0 10,21 8 9 42,21 0 8 42,53 0 7 42,37 0 6 42,37 4 5 42,53 3 4 42,69 2 3 42,7 0 0 0,135 0 0 0,22 0 0 0,6 0 0 0,
|
||||
79
vendor/golang.org/x/net/bpf/testdata/all_instructions.txt
generated
vendored
Normal file
79
vendor/golang.org/x/net/bpf/testdata/all_instructions.txt
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
# This filter is compiled to all_instructions.bpf by the `bpf_asm`
|
||||
# tool, which can be found in the linux kernel source tree under
|
||||
# tools/net.
|
||||
|
||||
# Load immediate
|
||||
ld #42
|
||||
ldx #42
|
||||
|
||||
# Load scratch
|
||||
ld M[3]
|
||||
ldx M[3]
|
||||
|
||||
# Load absolute
|
||||
ldb [42]
|
||||
ldh [42]
|
||||
ld [42]
|
||||
|
||||
# Load indirect
|
||||
ldb [x + 42]
|
||||
ldh [x + 42]
|
||||
ld [x + 42]
|
||||
|
||||
# Load IPv4 header length
|
||||
ldx 4*([42]&0xf)
|
||||
|
||||
# Run extension function
|
||||
ld #len
|
||||
ld #proto
|
||||
ld #type
|
||||
ld #rand
|
||||
|
||||
# Store scratch
|
||||
st M[3]
|
||||
stx M[3]
|
||||
|
||||
# A <op> constant
|
||||
add #42
|
||||
sub #42
|
||||
mul #42
|
||||
div #42
|
||||
or #42
|
||||
and #42
|
||||
lsh #42
|
||||
rsh #42
|
||||
mod #42
|
||||
xor #42
|
||||
|
||||
# A <op> X
|
||||
add x
|
||||
sub x
|
||||
mul x
|
||||
div x
|
||||
or x
|
||||
and x
|
||||
lsh x
|
||||
rsh x
|
||||
mod x
|
||||
xor x
|
||||
|
||||
# !A
|
||||
neg
|
||||
|
||||
# Jumps
|
||||
ja end
|
||||
jeq #42,prev,end
|
||||
jne #42,end
|
||||
jlt #42,end
|
||||
jle #42,end
|
||||
jgt #42,prev,end
|
||||
jge #42,prev,end
|
||||
jset #42,prev,end
|
||||
|
||||
# Register transfers
|
||||
tax
|
||||
txa
|
||||
|
||||
# Returns
|
||||
prev: ret a
|
||||
end: ret #42
|
||||
512
vendor/golang.org/x/net/bpf/vm_aluop_test.go
generated
vendored
Normal file
512
vendor/golang.org/x/net/bpf/vm_aluop_test.go
generated
vendored
Normal file
@@ -0,0 +1,512 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bpf_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
)
|
||||
|
||||
func TestVMALUOpAdd(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.ALUOpConstant{
|
||||
Op: bpf.ALUOpAdd,
|
||||
Val: 3,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
8, 2, 3,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 3, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMALUOpSub(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.TAX{},
|
||||
bpf.ALUOpX{
|
||||
Op: bpf.ALUOpSub,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
1, 2, 3,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 0, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMALUOpMul(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.ALUOpConstant{
|
||||
Op: bpf.ALUOpMul,
|
||||
Val: 2,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
6, 2, 3, 4,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 4, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMALUOpDiv(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.ALUOpConstant{
|
||||
Op: bpf.ALUOpDiv,
|
||||
Val: 2,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
20, 2, 3, 4,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 2, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMALUOpDivByZeroALUOpConstant(t *testing.T) {
|
||||
_, _, err := testVM(t, []bpf.Instruction{
|
||||
bpf.ALUOpConstant{
|
||||
Op: bpf.ALUOpDiv,
|
||||
Val: 0,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if errStr(err) != "cannot divide by zero using ALUOpConstant" {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMALUOpDivByZeroALUOpX(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
// Load byte 0 into X
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.TAX{},
|
||||
// Load byte 1 into A
|
||||
bpf.LoadAbsolute{
|
||||
Off: 9,
|
||||
Size: 1,
|
||||
},
|
||||
// Attempt to perform 1/0
|
||||
bpf.ALUOpX{
|
||||
Op: bpf.ALUOpDiv,
|
||||
},
|
||||
// Return 4 bytes if program does not terminate
|
||||
bpf.LoadConstant{
|
||||
Val: 12,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0, 1, 3, 4,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 0, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMALUOpOr(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 2,
|
||||
},
|
||||
bpf.ALUOpConstant{
|
||||
Op: bpf.ALUOpOr,
|
||||
Val: 0x01,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x10, 0x03, 0x04,
|
||||
0x05, 0x06, 0x07, 0x08,
|
||||
0x09, 0xff,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 9, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMALUOpAnd(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 2,
|
||||
},
|
||||
bpf.ALUOpConstant{
|
||||
Op: bpf.ALUOpAnd,
|
||||
Val: 0x0019,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xaa, 0x09,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 1, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMALUOpShiftLeft(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.ALUOpConstant{
|
||||
Op: bpf.ALUOpShiftLeft,
|
||||
Val: 0x01,
|
||||
},
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpEqual,
|
||||
Val: 0x02,
|
||||
SkipTrue: 1,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 9,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0x01, 0xaa,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 1, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMALUOpShiftRight(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.ALUOpConstant{
|
||||
Op: bpf.ALUOpShiftRight,
|
||||
Val: 0x01,
|
||||
},
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpEqual,
|
||||
Val: 0x04,
|
||||
SkipTrue: 1,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 9,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0x08, 0xff, 0xff,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 1, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMALUOpMod(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.ALUOpConstant{
|
||||
Op: bpf.ALUOpMod,
|
||||
Val: 20,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
30, 0, 0,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 2, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMALUOpModByZeroALUOpConstant(t *testing.T) {
|
||||
_, _, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.ALUOpConstant{
|
||||
Op: bpf.ALUOpMod,
|
||||
Val: 0,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if errStr(err) != "cannot divide by zero using ALUOpConstant" {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMALUOpModByZeroALUOpX(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
// Load byte 0 into X
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.TAX{},
|
||||
// Load byte 1 into A
|
||||
bpf.LoadAbsolute{
|
||||
Off: 9,
|
||||
Size: 1,
|
||||
},
|
||||
// Attempt to perform 1%0
|
||||
bpf.ALUOpX{
|
||||
Op: bpf.ALUOpMod,
|
||||
},
|
||||
// Return 4 bytes if program does not terminate
|
||||
bpf.LoadConstant{
|
||||
Val: 12,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0, 1, 3, 4,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 0, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMALUOpXor(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.ALUOpConstant{
|
||||
Op: bpf.ALUOpXor,
|
||||
Val: 0x0a,
|
||||
},
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpEqual,
|
||||
Val: 0x01,
|
||||
SkipTrue: 1,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 9,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0x0b, 0x00, 0x00, 0x00,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 1, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMALUOpUnknown(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.ALUOpConstant{
|
||||
Op: bpf.ALUOpAdd,
|
||||
Val: 1,
|
||||
},
|
||||
// Verify that an unknown operation is a no-op
|
||||
bpf.ALUOpConstant{
|
||||
Op: 100,
|
||||
},
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpEqual,
|
||||
Val: 0x02,
|
||||
SkipTrue: 1,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 9,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
1,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 1, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
192
vendor/golang.org/x/net/bpf/vm_bpf_test.go
generated
vendored
Normal file
192
vendor/golang.org/x/net/bpf/vm_bpf_test.go
generated
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bpf_test
|
||||
|
||||
import (
|
||||
"net"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
// A virtualMachine is a BPF virtual machine which can process an
|
||||
// input packet against a BPF program and render a verdict.
|
||||
type virtualMachine interface {
|
||||
Run(in []byte) (int, error)
|
||||
}
|
||||
|
||||
// canUseOSVM indicates if the OS BPF VM is available on this platform.
|
||||
func canUseOSVM() bool {
|
||||
// OS BPF VM can only be used on platforms where x/net/ipv4 supports
|
||||
// attaching a BPF program to a socket.
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// All BPF tests against both the Go VM and OS VM are assumed to
|
||||
// be used with a UDP socket. As a result, the entire contents
|
||||
// of a UDP datagram is sent through the BPF program, but only
|
||||
// the body after the UDP header will ever be returned in output.
|
||||
|
||||
// testVM sets up a Go BPF VM, and if available, a native OS BPF VM
|
||||
// for integration testing.
|
||||
func testVM(t *testing.T, filter []bpf.Instruction) (virtualMachine, func(), error) {
|
||||
goVM, err := bpf.NewVM(filter)
|
||||
if err != nil {
|
||||
// Some tests expect an error, so this error must be returned
|
||||
// instead of fatally exiting the test
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
mvm := &multiVirtualMachine{
|
||||
goVM: goVM,
|
||||
|
||||
t: t,
|
||||
}
|
||||
|
||||
// If available, add the OS VM for tests which verify that both the Go
|
||||
// VM and OS VM have exactly the same output for the same input program
|
||||
// and packet.
|
||||
done := func() {}
|
||||
if canUseOSVM() {
|
||||
osVM, osVMDone := testOSVM(t, filter)
|
||||
done = func() { osVMDone() }
|
||||
mvm.osVM = osVM
|
||||
}
|
||||
|
||||
return mvm, done, nil
|
||||
}
|
||||
|
||||
// udpHeaderLen is the length of a UDP header.
|
||||
const udpHeaderLen = 8
|
||||
|
||||
// A multiVirtualMachine is a virtualMachine which can call out to both the Go VM
|
||||
// and the native OS VM, if the OS VM is available.
|
||||
type multiVirtualMachine struct {
|
||||
goVM virtualMachine
|
||||
osVM virtualMachine
|
||||
|
||||
t *testing.T
|
||||
}
|
||||
|
||||
func (mvm *multiVirtualMachine) Run(in []byte) (int, error) {
|
||||
if len(in) < udpHeaderLen {
|
||||
mvm.t.Fatalf("input must be at least length of UDP header (%d), got: %d",
|
||||
udpHeaderLen, len(in))
|
||||
}
|
||||
|
||||
// All tests have a UDP header as part of input, because the OS VM
|
||||
// packets always will. For the Go VM, this output is trimmed before
|
||||
// being sent back to tests.
|
||||
goOut, goErr := mvm.goVM.Run(in)
|
||||
if goOut >= udpHeaderLen {
|
||||
goOut -= udpHeaderLen
|
||||
}
|
||||
|
||||
// If Go output is larger than the size of the packet, packet filtering
|
||||
// interop tests must trim the output bytes to the length of the packet.
|
||||
// The BPF VM should not do this on its own, as other uses of it do
|
||||
// not trim the output byte count.
|
||||
trim := len(in) - udpHeaderLen
|
||||
if goOut > trim {
|
||||
goOut = trim
|
||||
}
|
||||
|
||||
// When the OS VM is not available, process using the Go VM alone
|
||||
if mvm.osVM == nil {
|
||||
return goOut, goErr
|
||||
}
|
||||
|
||||
// The OS VM will apply its own UDP header, so remove the pseudo header
|
||||
// that the Go VM needs.
|
||||
osOut, err := mvm.osVM.Run(in[udpHeaderLen:])
|
||||
if err != nil {
|
||||
mvm.t.Fatalf("error while running OS VM: %v", err)
|
||||
}
|
||||
|
||||
// Verify both VMs return same number of bytes
|
||||
var mismatch bool
|
||||
if goOut != osOut {
|
||||
mismatch = true
|
||||
mvm.t.Logf("output byte count does not match:\n- go: %v\n- os: %v", goOut, osOut)
|
||||
}
|
||||
|
||||
if mismatch {
|
||||
mvm.t.Fatal("Go BPF and OS BPF packet outputs do not match")
|
||||
}
|
||||
|
||||
return goOut, goErr
|
||||
}
|
||||
|
||||
// An osVirtualMachine is a virtualMachine which uses the OS's BPF VM for
|
||||
// processing BPF programs.
|
||||
type osVirtualMachine struct {
|
||||
l net.PacketConn
|
||||
s net.Conn
|
||||
}
|
||||
|
||||
// testOSVM creates a virtualMachine which uses the OS's BPF VM by injecting
|
||||
// packets into a UDP listener with a BPF program attached to it.
|
||||
func testOSVM(t *testing.T, filter []bpf.Instruction) (virtualMachine, func()) {
|
||||
l, err := net.ListenPacket("udp4", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open OS VM UDP listener: %v", err)
|
||||
}
|
||||
|
||||
prog, err := bpf.Assemble(filter)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to compile BPF program: %v", err)
|
||||
}
|
||||
|
||||
p := ipv4.NewPacketConn(l)
|
||||
if err = p.SetBPF(prog); err != nil {
|
||||
t.Fatalf("failed to attach BPF program to listener: %v", err)
|
||||
}
|
||||
|
||||
s, err := net.Dial("udp4", l.LocalAddr().String())
|
||||
if err != nil {
|
||||
t.Fatalf("failed to dial connection to listener: %v", err)
|
||||
}
|
||||
|
||||
done := func() {
|
||||
_ = s.Close()
|
||||
_ = l.Close()
|
||||
}
|
||||
|
||||
return &osVirtualMachine{
|
||||
l: l,
|
||||
s: s,
|
||||
}, done
|
||||
}
|
||||
|
||||
// Run sends the input bytes into the OS's BPF VM and returns its verdict.
|
||||
func (vm *osVirtualMachine) Run(in []byte) (int, error) {
|
||||
go func() {
|
||||
_, _ = vm.s.Write(in)
|
||||
}()
|
||||
|
||||
vm.l.SetDeadline(time.Now().Add(50 * time.Millisecond))
|
||||
|
||||
var b [512]byte
|
||||
n, _, err := vm.l.ReadFrom(b[:])
|
||||
if err != nil {
|
||||
// A timeout indicates that BPF filtered out the packet, and thus,
|
||||
// no input should be returned.
|
||||
if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
|
||||
return n, nil
|
||||
}
|
||||
|
||||
return n, err
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
49
vendor/golang.org/x/net/bpf/vm_extension_test.go
generated
vendored
Normal file
49
vendor/golang.org/x/net/bpf/vm_extension_test.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bpf_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
)
|
||||
|
||||
func TestVMLoadExtensionNotImplemented(t *testing.T) {
|
||||
_, _, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadExtension{
|
||||
Num: 100,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if errStr(err) != "extension 100 not implemented" {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMLoadExtensionExtLen(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadExtension{
|
||||
Num: bpf.ExtLen,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0, 1, 2, 3,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 4, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
380
vendor/golang.org/x/net/bpf/vm_jump_test.go
generated
vendored
Normal file
380
vendor/golang.org/x/net/bpf/vm_jump_test.go
generated
vendored
Normal file
@@ -0,0 +1,380 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bpf_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
)
|
||||
|
||||
func TestVMJumpOne(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.Jump{
|
||||
Skip: 1,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 9,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
1,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 1, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMJumpOutOfProgram(t *testing.T) {
|
||||
_, _, err := testVM(t, []bpf.Instruction{
|
||||
bpf.Jump{
|
||||
Skip: 1,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if errStr(err) != "cannot jump 1 instructions; jumping past program bounds" {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMJumpIfTrueOutOfProgram(t *testing.T) {
|
||||
_, _, err := testVM(t, []bpf.Instruction{
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpEqual,
|
||||
SkipTrue: 2,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if errStr(err) != "cannot jump 2 instructions in true case; jumping past program bounds" {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMJumpIfFalseOutOfProgram(t *testing.T) {
|
||||
_, _, err := testVM(t, []bpf.Instruction{
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpEqual,
|
||||
SkipFalse: 3,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if errStr(err) != "cannot jump 3 instructions in false case; jumping past program bounds" {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMJumpIfEqual(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpEqual,
|
||||
Val: 1,
|
||||
SkipTrue: 1,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 9,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
1,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 1, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMJumpIfNotEqual(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpNotEqual,
|
||||
Val: 1,
|
||||
SkipFalse: 1,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 9,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
1,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 1, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMJumpIfGreaterThan(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 4,
|
||||
},
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpGreaterThan,
|
||||
Val: 0x00010202,
|
||||
SkipTrue: 1,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 12,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0, 1, 2, 3,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 4, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMJumpIfLessThan(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 4,
|
||||
},
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpLessThan,
|
||||
Val: 0xff010203,
|
||||
SkipTrue: 1,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 12,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0, 1, 2, 3,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 4, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMJumpIfGreaterOrEqual(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 4,
|
||||
},
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpGreaterOrEqual,
|
||||
Val: 0x00010203,
|
||||
SkipTrue: 1,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 12,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0, 1, 2, 3,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 4, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMJumpIfLessOrEqual(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 4,
|
||||
},
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpLessOrEqual,
|
||||
Val: 0xff010203,
|
||||
SkipTrue: 1,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 12,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0, 1, 2, 3,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 4, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMJumpIfBitsSet(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 2,
|
||||
},
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpBitsSet,
|
||||
Val: 0x1122,
|
||||
SkipTrue: 1,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 10,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0x01, 0x02,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 2, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMJumpIfBitsNotSet(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 2,
|
||||
},
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpBitsNotSet,
|
||||
Val: 0x1221,
|
||||
SkipTrue: 1,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
bpf.RetConstant{
|
||||
Val: 10,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0x01, 0x02,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 2, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
246
vendor/golang.org/x/net/bpf/vm_load_test.go
generated
vendored
Normal file
246
vendor/golang.org/x/net/bpf/vm_load_test.go
generated
vendored
Normal file
@@ -0,0 +1,246 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bpf_test
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
func TestVMLoadAbsoluteOffsetOutOfBounds(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 100,
|
||||
Size: 2,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0, 1, 2, 3,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 0, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMLoadAbsoluteOffsetPlusSizeOutOfBounds(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 2,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 0, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMLoadAbsoluteBadInstructionSize(t *testing.T) {
|
||||
_, _, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Size: 5,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if errStr(err) != "assembling instruction 1: invalid load byte length 0" {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMLoadConstantOK(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadConstant{
|
||||
Dst: bpf.RegX,
|
||||
Val: 9,
|
||||
},
|
||||
bpf.TXA{},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 1, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMLoadIndirectOutOfBounds(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadIndirect{
|
||||
Off: 100,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 0, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMLoadMemShiftOutOfBounds(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadMemShift{
|
||||
Off: 100,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 0, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
dhcp4Port = 53
|
||||
)
|
||||
|
||||
func TestVMLoadMemShiftLoadIndirectNoResult(t *testing.T) {
|
||||
vm, in, done := testDHCPv4(t)
|
||||
defer done()
|
||||
|
||||
// Append mostly empty UDP header with incorrect DHCPv4 port
|
||||
in = append(in, []byte{
|
||||
0, 0,
|
||||
0, dhcp4Port + 1,
|
||||
0, 0,
|
||||
0, 0,
|
||||
}...)
|
||||
|
||||
out, err := vm.Run(in)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 0, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMLoadMemShiftLoadIndirectOK(t *testing.T) {
|
||||
vm, in, done := testDHCPv4(t)
|
||||
defer done()
|
||||
|
||||
// Append mostly empty UDP header with correct DHCPv4 port
|
||||
in = append(in, []byte{
|
||||
0, 0,
|
||||
0, dhcp4Port,
|
||||
0, 0,
|
||||
0, 0,
|
||||
}...)
|
||||
|
||||
out, err := vm.Run(in)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := len(in)-8, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func testDHCPv4(t *testing.T) (virtualMachine, []byte, func()) {
|
||||
// DHCPv4 test data courtesy of David Anderson:
|
||||
// https://github.com/google/netboot/blob/master/dhcp4/conn_linux.go#L59-L70
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
// Load IPv4 packet length
|
||||
bpf.LoadMemShift{Off: 8},
|
||||
// Get UDP dport
|
||||
bpf.LoadIndirect{Off: 8 + 2, Size: 2},
|
||||
// Correct dport?
|
||||
bpf.JumpIf{Cond: bpf.JumpEqual, Val: dhcp4Port, SkipFalse: 1},
|
||||
// Accept
|
||||
bpf.RetConstant{Val: 1500},
|
||||
// Ignore
|
||||
bpf.RetConstant{Val: 0},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
|
||||
// Minimal requirements to make a valid IPv4 header
|
||||
h := &ipv4.Header{
|
||||
Len: ipv4.HeaderLen,
|
||||
Src: net.IPv4(192, 168, 1, 1),
|
||||
Dst: net.IPv4(192, 168, 1, 2),
|
||||
}
|
||||
hb, err := h.Marshal()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to marshal IPv4 header: %v", err)
|
||||
}
|
||||
|
||||
hb = append([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
}, hb...)
|
||||
|
||||
return vm, hb, done
|
||||
}
|
||||
115
vendor/golang.org/x/net/bpf/vm_ret_test.go
generated
vendored
Normal file
115
vendor/golang.org/x/net/bpf/vm_ret_test.go
generated
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bpf_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
)
|
||||
|
||||
func TestVMRetA(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
9,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 1, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMRetALargerThanInput(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 2,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0, 255,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 2, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMRetConstant(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.RetConstant{
|
||||
Val: 9,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0, 1,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 1, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMRetConstantLargerThanInput(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.RetConstant{
|
||||
Val: 16,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0, 1,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 2, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
247
vendor/golang.org/x/net/bpf/vm_scratch_test.go
generated
vendored
Normal file
247
vendor/golang.org/x/net/bpf/vm_scratch_test.go
generated
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bpf_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
)
|
||||
|
||||
func TestVMStoreScratchInvalidScratchRegisterTooSmall(t *testing.T) {
|
||||
_, _, err := testVM(t, []bpf.Instruction{
|
||||
bpf.StoreScratch{
|
||||
Src: bpf.RegA,
|
||||
N: -1,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if errStr(err) != "assembling instruction 1: invalid scratch slot -1" {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMStoreScratchInvalidScratchRegisterTooLarge(t *testing.T) {
|
||||
_, _, err := testVM(t, []bpf.Instruction{
|
||||
bpf.StoreScratch{
|
||||
Src: bpf.RegA,
|
||||
N: 16,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if errStr(err) != "assembling instruction 1: invalid scratch slot 16" {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMStoreScratchUnknownSourceRegister(t *testing.T) {
|
||||
_, _, err := testVM(t, []bpf.Instruction{
|
||||
bpf.StoreScratch{
|
||||
Src: 100,
|
||||
N: 0,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if errStr(err) != "assembling instruction 1: invalid source register 100" {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMLoadScratchInvalidScratchRegisterTooSmall(t *testing.T) {
|
||||
_, _, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadScratch{
|
||||
Dst: bpf.RegX,
|
||||
N: -1,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if errStr(err) != "assembling instruction 1: invalid scratch slot -1" {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMLoadScratchInvalidScratchRegisterTooLarge(t *testing.T) {
|
||||
_, _, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadScratch{
|
||||
Dst: bpf.RegX,
|
||||
N: 16,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if errStr(err) != "assembling instruction 1: invalid scratch slot 16" {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMLoadScratchUnknownDestinationRegister(t *testing.T) {
|
||||
_, _, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadScratch{
|
||||
Dst: 100,
|
||||
N: 0,
|
||||
},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if errStr(err) != "assembling instruction 1: invalid target register 100" {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMStoreScratchLoadScratchOneValue(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
// Load byte 255
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
// Copy to X and store in scratch[0]
|
||||
bpf.TAX{},
|
||||
bpf.StoreScratch{
|
||||
Src: bpf.RegX,
|
||||
N: 0,
|
||||
},
|
||||
// Load byte 1
|
||||
bpf.LoadAbsolute{
|
||||
Off: 9,
|
||||
Size: 1,
|
||||
},
|
||||
// Overwrite 1 with 255 from scratch[0]
|
||||
bpf.LoadScratch{
|
||||
Dst: bpf.RegA,
|
||||
N: 0,
|
||||
},
|
||||
// Return 255
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
255, 1, 2,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 3, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMStoreScratchLoadScratchMultipleValues(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
// Load byte 10
|
||||
bpf.LoadAbsolute{
|
||||
Off: 8,
|
||||
Size: 1,
|
||||
},
|
||||
// Store in scratch[0]
|
||||
bpf.StoreScratch{
|
||||
Src: bpf.RegA,
|
||||
N: 0,
|
||||
},
|
||||
// Load byte 20
|
||||
bpf.LoadAbsolute{
|
||||
Off: 9,
|
||||
Size: 1,
|
||||
},
|
||||
// Store in scratch[1]
|
||||
bpf.StoreScratch{
|
||||
Src: bpf.RegA,
|
||||
N: 1,
|
||||
},
|
||||
// Load byte 30
|
||||
bpf.LoadAbsolute{
|
||||
Off: 10,
|
||||
Size: 1,
|
||||
},
|
||||
// Store in scratch[2]
|
||||
bpf.StoreScratch{
|
||||
Src: bpf.RegA,
|
||||
N: 2,
|
||||
},
|
||||
// Load byte 1
|
||||
bpf.LoadAbsolute{
|
||||
Off: 11,
|
||||
Size: 1,
|
||||
},
|
||||
// Store in scratch[3]
|
||||
bpf.StoreScratch{
|
||||
Src: bpf.RegA,
|
||||
N: 3,
|
||||
},
|
||||
// Load in byte 10 to X
|
||||
bpf.LoadScratch{
|
||||
Dst: bpf.RegX,
|
||||
N: 0,
|
||||
},
|
||||
// Copy X -> A
|
||||
bpf.TXA{},
|
||||
// Verify value is 10
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpEqual,
|
||||
Val: 10,
|
||||
SkipTrue: 1,
|
||||
},
|
||||
// Fail test if incorrect
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
// Load in byte 20 to A
|
||||
bpf.LoadScratch{
|
||||
Dst: bpf.RegA,
|
||||
N: 1,
|
||||
},
|
||||
// Verify value is 20
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpEqual,
|
||||
Val: 20,
|
||||
SkipTrue: 1,
|
||||
},
|
||||
// Fail test if incorrect
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
// Load in byte 30 to A
|
||||
bpf.LoadScratch{
|
||||
Dst: bpf.RegA,
|
||||
N: 2,
|
||||
},
|
||||
// Verify value is 30
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpEqual,
|
||||
Val: 30,
|
||||
SkipTrue: 1,
|
||||
},
|
||||
// Fail test if incorrect
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
// Return first two bytes on success
|
||||
bpf.RetConstant{
|
||||
Val: 10,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load BPF program: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
out, err := vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
10, 20, 30, 1,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
if want, got := 2, out; want != got {
|
||||
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
|
||||
want, got)
|
||||
}
|
||||
}
|
||||
144
vendor/golang.org/x/net/bpf/vm_test.go
generated
vendored
Normal file
144
vendor/golang.org/x/net/bpf/vm_test.go
generated
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bpf_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
)
|
||||
|
||||
var _ bpf.Instruction = unknown{}
|
||||
|
||||
type unknown struct{}
|
||||
|
||||
func (unknown) Assemble() (bpf.RawInstruction, error) {
|
||||
return bpf.RawInstruction{}, nil
|
||||
}
|
||||
|
||||
func TestVMUnknownInstruction(t *testing.T) {
|
||||
vm, done, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadConstant{
|
||||
Dst: bpf.RegA,
|
||||
Val: 100,
|
||||
},
|
||||
// Should terminate the program with an error immediately
|
||||
unknown{},
|
||||
bpf.RetA{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
defer done()
|
||||
|
||||
_, err = vm.Run([]byte{
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00,
|
||||
})
|
||||
if errStr(err) != "unknown Instruction at index 1: bpf_test.unknown" {
|
||||
t.Fatalf("unexpected error while running program: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMNoReturnInstruction(t *testing.T) {
|
||||
_, _, err := testVM(t, []bpf.Instruction{
|
||||
bpf.LoadConstant{
|
||||
Dst: bpf.RegA,
|
||||
Val: 1,
|
||||
},
|
||||
})
|
||||
if errStr(err) != "BPF program must end with RetA or RetConstant" {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMNoInputInstructions(t *testing.T) {
|
||||
_, _, err := testVM(t, []bpf.Instruction{})
|
||||
if errStr(err) != "one or more Instructions must be specified" {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// ExampleNewVM demonstrates usage of a VM, using an Ethernet frame
|
||||
// as input and checking its EtherType to determine if it should be accepted.
|
||||
func ExampleNewVM() {
|
||||
// Offset | Length | Comment
|
||||
// -------------------------
|
||||
// 00 | 06 | Ethernet destination MAC address
|
||||
// 06 | 06 | Ethernet source MAC address
|
||||
// 12 | 02 | Ethernet EtherType
|
||||
const (
|
||||
etOff = 12
|
||||
etLen = 2
|
||||
|
||||
etARP = 0x0806
|
||||
)
|
||||
|
||||
// Set up a VM to filter traffic based on if its EtherType
|
||||
// matches the ARP EtherType.
|
||||
vm, err := bpf.NewVM([]bpf.Instruction{
|
||||
// Load EtherType value from Ethernet header
|
||||
bpf.LoadAbsolute{
|
||||
Off: etOff,
|
||||
Size: etLen,
|
||||
},
|
||||
// If EtherType is equal to the ARP EtherType, jump to allow
|
||||
// packet to be accepted
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpEqual,
|
||||
Val: etARP,
|
||||
SkipTrue: 1,
|
||||
},
|
||||
// EtherType does not match the ARP EtherType
|
||||
bpf.RetConstant{
|
||||
Val: 0,
|
||||
},
|
||||
// EtherType matches the ARP EtherType, accept up to 1500
|
||||
// bytes of packet
|
||||
bpf.RetConstant{
|
||||
Val: 1500,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to load BPF program: %v", err))
|
||||
}
|
||||
|
||||
// Create an Ethernet frame with the ARP EtherType for testing
|
||||
frame := []byte{
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
|
||||
0x08, 0x06,
|
||||
// Payload omitted for brevity
|
||||
}
|
||||
|
||||
// Run our VM's BPF program using the Ethernet frame as input
|
||||
out, err := vm.Run(frame)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to accept Ethernet frame: %v", err))
|
||||
}
|
||||
|
||||
// BPF VM can return a byte count greater than the number of input
|
||||
// bytes, so trim the output to match the input byte length
|
||||
if out > len(frame) {
|
||||
out = len(frame)
|
||||
}
|
||||
|
||||
fmt.Printf("out: %d bytes", out)
|
||||
|
||||
// Output:
|
||||
// out: 14 bytes
|
||||
}
|
||||
|
||||
// errStr returns the string representation of an error, or
|
||||
// "<nil>" if it is nil.
|
||||
func errStr(err error) string {
|
||||
if err == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
|
||||
return err.Error()
|
||||
}
|
||||
93
vendor/golang.org/x/net/ipv4/bpf_test.go
generated
vendored
Normal file
93
vendor/golang.org/x/net/ipv4/bpf_test.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv4_test
|
||||
|
||||
import (
|
||||
"net"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
func TestBPF(t *testing.T) {
|
||||
if runtime.GOOS != "linux" {
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
l, err := net.ListenPacket("udp4", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer l.Close()
|
||||
|
||||
p := ipv4.NewPacketConn(l)
|
||||
|
||||
// This filter accepts UDP packets whose first payload byte is
|
||||
// even.
|
||||
prog, err := bpf.Assemble([]bpf.Instruction{
|
||||
// Load the first byte of the payload (skipping UDP header).
|
||||
bpf.LoadAbsolute{Off: 8, Size: 1},
|
||||
// Select LSB of the byte.
|
||||
bpf.ALUOpConstant{Op: bpf.ALUOpAnd, Val: 1},
|
||||
// Byte is even?
|
||||
bpf.JumpIf{Cond: bpf.JumpEqual, Val: 0, SkipFalse: 1},
|
||||
// Accept.
|
||||
bpf.RetConstant{Val: 4096},
|
||||
// Ignore.
|
||||
bpf.RetConstant{Val: 0},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("compiling BPF: %s", err)
|
||||
}
|
||||
|
||||
if err = p.SetBPF(prog); err != nil {
|
||||
t.Fatalf("attaching filter to Conn: %s", err)
|
||||
}
|
||||
|
||||
s, err := net.Dial("udp4", l.LocalAddr().String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer s.Close()
|
||||
go func() {
|
||||
for i := byte(0); i < 10; i++ {
|
||||
s.Write([]byte{i})
|
||||
}
|
||||
}()
|
||||
|
||||
l.SetDeadline(time.Now().Add(2 * time.Second))
|
||||
seen := make([]bool, 5)
|
||||
for {
|
||||
var b [512]byte
|
||||
n, _, err := l.ReadFrom(b[:])
|
||||
if err != nil {
|
||||
t.Fatalf("reading from listener: %s", err)
|
||||
}
|
||||
if n != 1 {
|
||||
t.Fatalf("unexpected packet length, want 1, got %d", n)
|
||||
}
|
||||
if b[0] >= 10 {
|
||||
t.Fatalf("unexpected byte, want 0-9, got %d", b[0])
|
||||
}
|
||||
if b[0]%2 != 0 {
|
||||
t.Fatalf("got odd byte %d, wanted only even bytes", b[0])
|
||||
}
|
||||
seen[b[0]/2] = true
|
||||
|
||||
seenAll := true
|
||||
for _, v := range seen {
|
||||
if !v {
|
||||
seenAll = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if seenAll {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
8
vendor/golang.org/x/net/ipv4/doc.go
generated
vendored
8
vendor/golang.org/x/net/ipv4/doc.go
generated
vendored
@@ -23,8 +23,8 @@
|
||||
// net.UDPConn and net.IPConn which are created as network connections
|
||||
// that use the IPv4 transport. When a single TCP connection carrying
|
||||
// a data flow of multiple packets needs to indicate the flow is
|
||||
// important, ipv4.Conn is used to set the type-of-service field on
|
||||
// the IPv4 header for each packet.
|
||||
// important, Conn is used to set the type-of-service field on the
|
||||
// IPv4 header for each packet.
|
||||
//
|
||||
// ln, err := net.Listen("tcp4", "0.0.0.0:1024")
|
||||
// if err != nil {
|
||||
@@ -96,8 +96,8 @@
|
||||
// The application might set per packet control message transmissions
|
||||
// between the protocol stack within the kernel. When the application
|
||||
// needs a destination address on an incoming packet,
|
||||
// SetControlMessage of ipv4.PacketConn is used to enable control
|
||||
// message transmissions.
|
||||
// SetControlMessage of PacketConn is used to enable control message
|
||||
// transmissions.
|
||||
//
|
||||
// if err := p.SetControlMessage(ipv4.FlagDst, true); err != nil {
|
||||
// // error handling
|
||||
|
||||
224
vendor/golang.org/x/net/ipv4/example_test.go
generated
vendored
Normal file
224
vendor/golang.org/x/net/ipv4/example_test.go
generated
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv4_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/icmp"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
func ExampleConn_markingTCP() {
|
||||
ln, err := net.Listen("tcp", "0.0.0.0:1024")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer ln.Close()
|
||||
|
||||
for {
|
||||
c, err := ln.Accept()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
go func(c net.Conn) {
|
||||
defer c.Close()
|
||||
if c.RemoteAddr().(*net.TCPAddr).IP.To4() != nil {
|
||||
p := ipv4.NewConn(c)
|
||||
if err := p.SetTOS(0x28); err != nil { // DSCP AF11
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := p.SetTTL(128); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
if _, err := c.Write([]byte("HELLO-R-U-THERE-ACK")); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}(c)
|
||||
}
|
||||
}
|
||||
|
||||
func ExamplePacketConn_servingOneShotMulticastDNS() {
|
||||
c, err := net.ListenPacket("udp4", "0.0.0.0:5353") // mDNS over UDP
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
p := ipv4.NewPacketConn(c)
|
||||
|
||||
en0, err := net.InterfaceByName("en0")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
mDNSLinkLocal := net.UDPAddr{IP: net.IPv4(224, 0, 0, 251)}
|
||||
if err := p.JoinGroup(en0, &mDNSLinkLocal); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer p.LeaveGroup(en0, &mDNSLinkLocal)
|
||||
if err := p.SetControlMessage(ipv4.FlagDst, true); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
b := make([]byte, 1500)
|
||||
for {
|
||||
_, cm, peer, err := p.ReadFrom(b)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if !cm.Dst.IsMulticast() || !cm.Dst.Equal(mDNSLinkLocal.IP) {
|
||||
continue
|
||||
}
|
||||
answers := []byte("FAKE-MDNS-ANSWERS") // fake mDNS answers, you need to implement this
|
||||
if _, err := p.WriteTo(answers, nil, peer); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ExamplePacketConn_tracingIPPacketRoute() {
|
||||
// Tracing an IP packet route to www.google.com.
|
||||
|
||||
const host = "www.google.com"
|
||||
ips, err := net.LookupIP(host)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
var dst net.IPAddr
|
||||
for _, ip := range ips {
|
||||
if ip.To4() != nil {
|
||||
dst.IP = ip
|
||||
fmt.Printf("using %v for tracing an IP packet route to %s\n", dst.IP, host)
|
||||
break
|
||||
}
|
||||
}
|
||||
if dst.IP == nil {
|
||||
log.Fatal("no A record found")
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("ip4:1", "0.0.0.0") // ICMP for IPv4
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
p := ipv4.NewPacketConn(c)
|
||||
|
||||
if err := p.SetControlMessage(ipv4.FlagTTL|ipv4.FlagSrc|ipv4.FlagDst|ipv4.FlagInterface, true); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
wm := icmp.Message{
|
||||
Type: ipv4.ICMPTypeEcho, Code: 0,
|
||||
Body: &icmp.Echo{
|
||||
ID: os.Getpid() & 0xffff,
|
||||
Data: []byte("HELLO-R-U-THERE"),
|
||||
},
|
||||
}
|
||||
|
||||
rb := make([]byte, 1500)
|
||||
for i := 1; i <= 64; i++ { // up to 64 hops
|
||||
wm.Body.(*icmp.Echo).Seq = i
|
||||
wb, err := wm.Marshal(nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := p.SetTTL(i); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// In the real world usually there are several
|
||||
// multiple traffic-engineered paths for each hop.
|
||||
// You may need to probe a few times to each hop.
|
||||
begin := time.Now()
|
||||
if _, err := p.WriteTo(wb, nil, &dst); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := p.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
n, cm, peer, err := p.ReadFrom(rb)
|
||||
if err != nil {
|
||||
if err, ok := err.(net.Error); ok && err.Timeout() {
|
||||
fmt.Printf("%v\t*\n", i)
|
||||
continue
|
||||
}
|
||||
log.Fatal(err)
|
||||
}
|
||||
rm, err := icmp.ParseMessage(1, rb[:n])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
rtt := time.Since(begin)
|
||||
|
||||
// In the real world you need to determine whether the
|
||||
// received message is yours using ControlMessage.Src,
|
||||
// ControlMessage.Dst, icmp.Echo.ID and icmp.Echo.Seq.
|
||||
switch rm.Type {
|
||||
case ipv4.ICMPTypeTimeExceeded:
|
||||
names, _ := net.LookupAddr(peer.String())
|
||||
fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, cm)
|
||||
case ipv4.ICMPTypeEchoReply:
|
||||
names, _ := net.LookupAddr(peer.String())
|
||||
fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, cm)
|
||||
return
|
||||
default:
|
||||
log.Printf("unknown ICMP message: %+v\n", rm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleRawConn_advertisingOSPFHello() {
|
||||
c, err := net.ListenPacket("ip4:89", "0.0.0.0") // OSPF for IPv4
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
r, err := ipv4.NewRawConn(c)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
en0, err := net.InterfaceByName("en0")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
allSPFRouters := net.IPAddr{IP: net.IPv4(224, 0, 0, 5)}
|
||||
if err := r.JoinGroup(en0, &allSPFRouters); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer r.LeaveGroup(en0, &allSPFRouters)
|
||||
|
||||
hello := make([]byte, 24) // fake hello data, you need to implement this
|
||||
ospf := make([]byte, 24) // fake ospf header, you need to implement this
|
||||
ospf[0] = 2 // version 2
|
||||
ospf[1] = 1 // hello packet
|
||||
ospf = append(ospf, hello...)
|
||||
iph := &ipv4.Header{
|
||||
Version: ipv4.Version,
|
||||
Len: ipv4.HeaderLen,
|
||||
TOS: 0xc0, // DSCP CS6
|
||||
TotalLen: ipv4.HeaderLen + len(ospf),
|
||||
TTL: 1,
|
||||
Protocol: 89,
|
||||
Dst: allSPFRouters.IP.To4(),
|
||||
}
|
||||
|
||||
var cm *ipv4.ControlMessage
|
||||
switch runtime.GOOS {
|
||||
case "darwin", "linux":
|
||||
cm = &ipv4.ControlMessage{IfIndex: en0.Index}
|
||||
default:
|
||||
if err := r.SetMulticastInterface(en0); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := r.WriteTo(iph, ospf, cm); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
152
vendor/golang.org/x/net/ipv4/header_test.go
generated
vendored
Normal file
152
vendor/golang.org/x/net/ipv4/header_test.go
generated
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv4
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"net"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type headerTest struct {
|
||||
wireHeaderFromKernel [HeaderLen]byte
|
||||
wireHeaderToKernel [HeaderLen]byte
|
||||
wireHeaderFromTradBSDKernel [HeaderLen]byte
|
||||
wireHeaderToTradBSDKernel [HeaderLen]byte
|
||||
wireHeaderFromFreeBSD10Kernel [HeaderLen]byte
|
||||
wireHeaderToFreeBSD10Kernel [HeaderLen]byte
|
||||
*Header
|
||||
}
|
||||
|
||||
var headerLittleEndianTest = headerTest{
|
||||
// TODO(mikio): Add platform dependent wire header formats when
|
||||
// we support new platforms.
|
||||
wireHeaderFromKernel: [HeaderLen]byte{
|
||||
0x45, 0x01, 0xbe, 0xef,
|
||||
0xca, 0xfe, 0x45, 0xdc,
|
||||
0xff, 0x01, 0xde, 0xad,
|
||||
172, 16, 254, 254,
|
||||
192, 168, 0, 1,
|
||||
},
|
||||
wireHeaderToKernel: [HeaderLen]byte{
|
||||
0x45, 0x01, 0xbe, 0xef,
|
||||
0xca, 0xfe, 0x45, 0xdc,
|
||||
0xff, 0x01, 0xde, 0xad,
|
||||
172, 16, 254, 254,
|
||||
192, 168, 0, 1,
|
||||
},
|
||||
wireHeaderFromTradBSDKernel: [HeaderLen]byte{
|
||||
0x45, 0x01, 0xdb, 0xbe,
|
||||
0xca, 0xfe, 0xdc, 0x45,
|
||||
0xff, 0x01, 0xde, 0xad,
|
||||
172, 16, 254, 254,
|
||||
192, 168, 0, 1,
|
||||
},
|
||||
wireHeaderToTradBSDKernel: [HeaderLen]byte{
|
||||
0x45, 0x01, 0xef, 0xbe,
|
||||
0xca, 0xfe, 0xdc, 0x45,
|
||||
0xff, 0x01, 0xde, 0xad,
|
||||
172, 16, 254, 254,
|
||||
192, 168, 0, 1,
|
||||
},
|
||||
wireHeaderFromFreeBSD10Kernel: [HeaderLen]byte{
|
||||
0x45, 0x01, 0xef, 0xbe,
|
||||
0xca, 0xfe, 0xdc, 0x45,
|
||||
0xff, 0x01, 0xde, 0xad,
|
||||
172, 16, 254, 254,
|
||||
192, 168, 0, 1,
|
||||
},
|
||||
wireHeaderToFreeBSD10Kernel: [HeaderLen]byte{
|
||||
0x45, 0x01, 0xef, 0xbe,
|
||||
0xca, 0xfe, 0xdc, 0x45,
|
||||
0xff, 0x01, 0xde, 0xad,
|
||||
172, 16, 254, 254,
|
||||
192, 168, 0, 1,
|
||||
},
|
||||
Header: &Header{
|
||||
Version: Version,
|
||||
Len: HeaderLen,
|
||||
TOS: 1,
|
||||
TotalLen: 0xbeef,
|
||||
ID: 0xcafe,
|
||||
Flags: DontFragment,
|
||||
FragOff: 1500,
|
||||
TTL: 255,
|
||||
Protocol: 1,
|
||||
Checksum: 0xdead,
|
||||
Src: net.IPv4(172, 16, 254, 254),
|
||||
Dst: net.IPv4(192, 168, 0, 1),
|
||||
},
|
||||
}
|
||||
|
||||
func TestMarshalHeader(t *testing.T) {
|
||||
tt := &headerLittleEndianTest
|
||||
if nativeEndian != binary.LittleEndian {
|
||||
t.Skip("no test for non-little endian machine yet")
|
||||
}
|
||||
|
||||
b, err := tt.Header.Marshal()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var wh []byte
|
||||
switch runtime.GOOS {
|
||||
case "darwin", "dragonfly", "netbsd":
|
||||
wh = tt.wireHeaderToTradBSDKernel[:]
|
||||
case "freebsd":
|
||||
switch {
|
||||
case freebsdVersion < 1000000:
|
||||
wh = tt.wireHeaderToTradBSDKernel[:]
|
||||
case 1000000 <= freebsdVersion && freebsdVersion < 1100000:
|
||||
wh = tt.wireHeaderToFreeBSD10Kernel[:]
|
||||
default:
|
||||
wh = tt.wireHeaderToKernel[:]
|
||||
}
|
||||
default:
|
||||
wh = tt.wireHeaderToKernel[:]
|
||||
}
|
||||
if !bytes.Equal(b, wh) {
|
||||
t.Fatalf("got %#v; want %#v", b, wh)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseHeader(t *testing.T) {
|
||||
tt := &headerLittleEndianTest
|
||||
if nativeEndian != binary.LittleEndian {
|
||||
t.Skip("no test for big endian machine yet")
|
||||
}
|
||||
|
||||
var wh []byte
|
||||
switch runtime.GOOS {
|
||||
case "darwin", "dragonfly", "netbsd":
|
||||
wh = tt.wireHeaderFromTradBSDKernel[:]
|
||||
case "freebsd":
|
||||
switch {
|
||||
case freebsdVersion < 1000000:
|
||||
wh = tt.wireHeaderFromTradBSDKernel[:]
|
||||
case 1000000 <= freebsdVersion && freebsdVersion < 1100000:
|
||||
wh = tt.wireHeaderFromFreeBSD10Kernel[:]
|
||||
default:
|
||||
wh = tt.wireHeaderFromKernel[:]
|
||||
}
|
||||
default:
|
||||
wh = tt.wireHeaderFromKernel[:]
|
||||
}
|
||||
h, err := ParseHeader(wh)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(h, tt.Header) {
|
||||
t.Fatalf("got %#v; want %#v", h, tt.Header)
|
||||
}
|
||||
s := h.String()
|
||||
if strings.Contains(s, ",") {
|
||||
t.Fatalf("should be space-separated values: %s", s)
|
||||
}
|
||||
}
|
||||
95
vendor/golang.org/x/net/ipv4/icmp_test.go
generated
vendored
Normal file
95
vendor/golang.org/x/net/ipv4/icmp_test.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv4_test
|
||||
|
||||
import (
|
||||
"net"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/internal/nettest"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
var icmpStringTests = []struct {
|
||||
in ipv4.ICMPType
|
||||
out string
|
||||
}{
|
||||
{ipv4.ICMPTypeDestinationUnreachable, "destination unreachable"},
|
||||
|
||||
{256, "<nil>"},
|
||||
}
|
||||
|
||||
func TestICMPString(t *testing.T) {
|
||||
for _, tt := range icmpStringTests {
|
||||
s := tt.in.String()
|
||||
if s != tt.out {
|
||||
t.Errorf("got %s; want %s", s, tt.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestICMPFilter(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
default:
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
var f ipv4.ICMPFilter
|
||||
for _, toggle := range []bool{false, true} {
|
||||
f.SetAll(toggle)
|
||||
for _, typ := range []ipv4.ICMPType{
|
||||
ipv4.ICMPTypeDestinationUnreachable,
|
||||
ipv4.ICMPTypeEchoReply,
|
||||
ipv4.ICMPTypeTimeExceeded,
|
||||
ipv4.ICMPTypeParameterProblem,
|
||||
} {
|
||||
f.Accept(typ)
|
||||
if f.WillBlock(typ) {
|
||||
t.Errorf("ipv4.ICMPFilter.Set(%v, false) failed", typ)
|
||||
}
|
||||
f.Block(typ)
|
||||
if !f.WillBlock(typ) {
|
||||
t.Errorf("ipv4.ICMPFilter.Set(%v, true) failed", typ)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetICMPFilter(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
default:
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
||||
t.Skip(m)
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("ip4:icmp", "127.0.0.1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
p := ipv4.NewPacketConn(c)
|
||||
|
||||
var f ipv4.ICMPFilter
|
||||
f.SetAll(true)
|
||||
f.Accept(ipv4.ICMPTypeEcho)
|
||||
f.Accept(ipv4.ICMPTypeEchoReply)
|
||||
if err := p.SetICMPFilter(&f); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
kf, err := p.ICMPFilter()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(kf, &f) {
|
||||
t.Fatalf("got %#v; want %#v", kf, f)
|
||||
}
|
||||
}
|
||||
334
vendor/golang.org/x/net/ipv4/multicast_test.go
generated
vendored
Normal file
334
vendor/golang.org/x/net/ipv4/multicast_test.go
generated
vendored
Normal file
@@ -0,0 +1,334 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv4_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/icmp"
|
||||
"golang.org/x/net/internal/iana"
|
||||
"golang.org/x/net/internal/nettest"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
var packetConnReadWriteMulticastUDPTests = []struct {
|
||||
addr string
|
||||
grp, src *net.UDPAddr
|
||||
}{
|
||||
{"224.0.0.0:0", &net.UDPAddr{IP: net.IPv4(224, 0, 0, 254)}, nil}, // see RFC 4727
|
||||
|
||||
{"232.0.1.0:0", &net.UDPAddr{IP: net.IPv4(232, 0, 1, 254)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
|
||||
}
|
||||
|
||||
func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
|
||||
if ifi == nil {
|
||||
t.Skipf("not available on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
for _, tt := range packetConnReadWriteMulticastUDPTests {
|
||||
c, err := net.ListenPacket("udp4", tt.addr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
grp := *tt.grp
|
||||
grp.Port = c.LocalAddr().(*net.UDPAddr).Port
|
||||
p := ipv4.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
if tt.src == nil {
|
||||
if err := p.JoinGroup(ifi, &grp); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer p.LeaveGroup(ifi, &grp)
|
||||
} else {
|
||||
if err := p.JoinSourceSpecificGroup(ifi, &grp, tt.src); err != nil {
|
||||
switch runtime.GOOS {
|
||||
case "freebsd", "linux":
|
||||
default: // platforms that don't support IGMPv2/3 fail here
|
||||
t.Logf("not supported on %s", runtime.GOOS)
|
||||
continue
|
||||
}
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer p.LeaveSourceSpecificGroup(ifi, &grp, tt.src)
|
||||
}
|
||||
if err := p.SetMulticastInterface(ifi); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := p.MulticastInterface(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := p.SetMulticastLoopback(true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := p.MulticastLoopback(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
|
||||
wb := []byte("HELLO-R-U-THERE")
|
||||
|
||||
for i, toggle := range []bool{true, false, true} {
|
||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
||||
if nettest.ProtocolNotSupported(err) {
|
||||
t.Logf("not supported on %s", runtime.GOOS)
|
||||
continue
|
||||
}
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
p.SetMulticastTTL(i + 1)
|
||||
if n, err := p.WriteTo(wb, nil, &grp); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if n != len(wb) {
|
||||
t.Fatalf("got %v; want %v", n, len(wb))
|
||||
}
|
||||
rb := make([]byte, 128)
|
||||
if n, _, _, err := p.ReadFrom(rb); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !bytes.Equal(rb[:n], wb) {
|
||||
t.Fatalf("got %v; want %v", rb[:n], wb)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var packetConnReadWriteMulticastICMPTests = []struct {
|
||||
grp, src *net.IPAddr
|
||||
}{
|
||||
{&net.IPAddr{IP: net.IPv4(224, 0, 0, 254)}, nil}, // see RFC 4727
|
||||
|
||||
{&net.IPAddr{IP: net.IPv4(232, 0, 1, 254)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
|
||||
}
|
||||
|
||||
func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "solaris", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
||||
t.Skip(m)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
|
||||
if ifi == nil {
|
||||
t.Skipf("not available on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
for _, tt := range packetConnReadWriteMulticastICMPTests {
|
||||
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
p := ipv4.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
if tt.src == nil {
|
||||
if err := p.JoinGroup(ifi, tt.grp); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer p.LeaveGroup(ifi, tt.grp)
|
||||
} else {
|
||||
if err := p.JoinSourceSpecificGroup(ifi, tt.grp, tt.src); err != nil {
|
||||
switch runtime.GOOS {
|
||||
case "freebsd", "linux":
|
||||
default: // platforms that don't support IGMPv2/3 fail here
|
||||
t.Logf("not supported on %s", runtime.GOOS)
|
||||
continue
|
||||
}
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer p.LeaveSourceSpecificGroup(ifi, tt.grp, tt.src)
|
||||
}
|
||||
if err := p.SetMulticastInterface(ifi); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := p.MulticastInterface(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := p.SetMulticastLoopback(true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := p.MulticastLoopback(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cf := ipv4.FlagDst | ipv4.FlagInterface
|
||||
if runtime.GOOS != "solaris" {
|
||||
// Solaris never allows to modify ICMP properties.
|
||||
cf |= ipv4.FlagTTL
|
||||
}
|
||||
|
||||
for i, toggle := range []bool{true, false, true} {
|
||||
wb, err := (&icmp.Message{
|
||||
Type: ipv4.ICMPTypeEcho, Code: 0,
|
||||
Body: &icmp.Echo{
|
||||
ID: os.Getpid() & 0xffff, Seq: i + 1,
|
||||
Data: []byte("HELLO-R-U-THERE"),
|
||||
},
|
||||
}).Marshal(nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
||||
if nettest.ProtocolNotSupported(err) {
|
||||
t.Logf("not supported on %s", runtime.GOOS)
|
||||
continue
|
||||
}
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
p.SetMulticastTTL(i + 1)
|
||||
if n, err := p.WriteTo(wb, nil, tt.grp); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if n != len(wb) {
|
||||
t.Fatalf("got %v; want %v", n, len(wb))
|
||||
}
|
||||
rb := make([]byte, 128)
|
||||
if n, _, _, err := p.ReadFrom(rb); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
m, err := icmp.ParseMessage(iana.ProtocolICMP, rb[:n])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
switch {
|
||||
case m.Type == ipv4.ICMPTypeEchoReply && m.Code == 0: // net.inet.icmp.bmcastecho=1
|
||||
case m.Type == ipv4.ICMPTypeEcho && m.Code == 0: // net.inet.icmp.bmcastecho=0
|
||||
default:
|
||||
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var rawConnReadWriteMulticastICMPTests = []struct {
|
||||
grp, src *net.IPAddr
|
||||
}{
|
||||
{&net.IPAddr{IP: net.IPv4(224, 0, 0, 254)}, nil}, // see RFC 4727
|
||||
|
||||
{&net.IPAddr{IP: net.IPv4(232, 0, 1, 254)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
|
||||
}
|
||||
|
||||
func TestRawConnReadWriteMulticastICMP(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("to avoid external network")
|
||||
}
|
||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
||||
t.Skip(m)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
|
||||
if ifi == nil {
|
||||
t.Skipf("not available on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
for _, tt := range rawConnReadWriteMulticastICMPTests {
|
||||
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
r, err := ipv4.NewRawConn(c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer r.Close()
|
||||
if tt.src == nil {
|
||||
if err := r.JoinGroup(ifi, tt.grp); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer r.LeaveGroup(ifi, tt.grp)
|
||||
} else {
|
||||
if err := r.JoinSourceSpecificGroup(ifi, tt.grp, tt.src); err != nil {
|
||||
switch runtime.GOOS {
|
||||
case "freebsd", "linux":
|
||||
default: // platforms that don't support IGMPv2/3 fail here
|
||||
t.Logf("not supported on %s", runtime.GOOS)
|
||||
continue
|
||||
}
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer r.LeaveSourceSpecificGroup(ifi, tt.grp, tt.src)
|
||||
}
|
||||
if err := r.SetMulticastInterface(ifi); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := r.MulticastInterface(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := r.SetMulticastLoopback(true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := r.MulticastLoopback(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
|
||||
|
||||
for i, toggle := range []bool{true, false, true} {
|
||||
wb, err := (&icmp.Message{
|
||||
Type: ipv4.ICMPTypeEcho, Code: 0,
|
||||
Body: &icmp.Echo{
|
||||
ID: os.Getpid() & 0xffff, Seq: i + 1,
|
||||
Data: []byte("HELLO-R-U-THERE"),
|
||||
},
|
||||
}).Marshal(nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
wh := &ipv4.Header{
|
||||
Version: ipv4.Version,
|
||||
Len: ipv4.HeaderLen,
|
||||
TOS: i + 1,
|
||||
TotalLen: ipv4.HeaderLen + len(wb),
|
||||
Protocol: 1,
|
||||
Dst: tt.grp.IP,
|
||||
}
|
||||
if err := r.SetControlMessage(cf, toggle); err != nil {
|
||||
if nettest.ProtocolNotSupported(err) {
|
||||
t.Logf("not supported on %s", runtime.GOOS)
|
||||
continue
|
||||
}
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := r.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r.SetMulticastTTL(i + 1)
|
||||
if err := r.WriteTo(wh, wb, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rb := make([]byte, ipv4.HeaderLen+128)
|
||||
if rh, b, _, err := r.ReadFrom(rb); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
m, err := icmp.ParseMessage(iana.ProtocolICMP, b)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
switch {
|
||||
case (rh.Dst.IsLoopback() || rh.Dst.IsLinkLocalUnicast() || rh.Dst.IsGlobalUnicast()) && m.Type == ipv4.ICMPTypeEchoReply && m.Code == 0: // net.inet.icmp.bmcastecho=1
|
||||
case rh.Dst.IsMulticast() && m.Type == ipv4.ICMPTypeEcho && m.Code == 0: // net.inet.icmp.bmcastecho=0
|
||||
default:
|
||||
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
249
vendor/golang.org/x/net/ipv4/multicastlistener_test.go
generated
vendored
Normal file
249
vendor/golang.org/x/net/ipv4/multicastlistener_test.go
generated
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv4_test
|
||||
|
||||
import (
|
||||
"net"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/internal/nettest"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
var udpMultipleGroupListenerTests = []net.Addr{
|
||||
&net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}, // see RFC 4727
|
||||
&net.UDPAddr{IP: net.IPv4(224, 0, 0, 250)},
|
||||
&net.UDPAddr{IP: net.IPv4(224, 0, 0, 254)},
|
||||
}
|
||||
|
||||
func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if testing.Short() {
|
||||
t.Skip("to avoid external network")
|
||||
}
|
||||
|
||||
for _, gaddr := range udpMultipleGroupListenerTests {
|
||||
c, err := net.ListenPacket("udp4", "0.0.0.0:0") // wildcard address with no reusable port
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
p := ipv4.NewPacketConn(c)
|
||||
var mift []*net.Interface
|
||||
|
||||
ift, err := net.Interfaces()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i, ifi := range ift {
|
||||
if _, ok := nettest.IsMulticastCapable("ip4", &ifi); !ok {
|
||||
continue
|
||||
}
|
||||
if err := p.JoinGroup(&ifi, gaddr); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
mift = append(mift, &ift[i])
|
||||
}
|
||||
for _, ifi := range mift {
|
||||
if err := p.LeaveGroup(ifi, gaddr); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if testing.Short() {
|
||||
t.Skip("to avoid external network")
|
||||
}
|
||||
|
||||
for _, gaddr := range udpMultipleGroupListenerTests {
|
||||
c1, err := net.ListenPacket("udp4", "224.0.0.0:1024") // wildcard address with reusable port
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c1.Close()
|
||||
|
||||
c2, err := net.ListenPacket("udp4", "224.0.0.0:1024") // wildcard address with reusable port
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c2.Close()
|
||||
|
||||
var ps [2]*ipv4.PacketConn
|
||||
ps[0] = ipv4.NewPacketConn(c1)
|
||||
ps[1] = ipv4.NewPacketConn(c2)
|
||||
var mift []*net.Interface
|
||||
|
||||
ift, err := net.Interfaces()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i, ifi := range ift {
|
||||
if _, ok := nettest.IsMulticastCapable("ip4", &ifi); !ok {
|
||||
continue
|
||||
}
|
||||
for _, p := range ps {
|
||||
if err := p.JoinGroup(&ifi, gaddr); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
mift = append(mift, &ift[i])
|
||||
}
|
||||
for _, ifi := range mift {
|
||||
for _, p := range ps {
|
||||
if err := p.LeaveGroup(ifi, gaddr); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if testing.Short() {
|
||||
t.Skip("to avoid external network")
|
||||
}
|
||||
|
||||
gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
|
||||
type ml struct {
|
||||
c *ipv4.PacketConn
|
||||
ifi *net.Interface
|
||||
}
|
||||
var mlt []*ml
|
||||
|
||||
ift, err := net.Interfaces()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i, ifi := range ift {
|
||||
ip, ok := nettest.IsMulticastCapable("ip4", &ifi)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
c, err := net.ListenPacket("udp4", ip.String()+":"+"1024") // unicast address with non-reusable port
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
p := ipv4.NewPacketConn(c)
|
||||
if err := p.JoinGroup(&ifi, &gaddr); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
mlt = append(mlt, &ml{p, &ift[i]})
|
||||
}
|
||||
for _, m := range mlt {
|
||||
if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPSingleRawConnWithSingleGroupListener(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if testing.Short() {
|
||||
t.Skip("to avoid external network")
|
||||
}
|
||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
||||
t.Skip(m)
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") // wildcard address
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
r, err := ipv4.NewRawConn(c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
|
||||
var mift []*net.Interface
|
||||
|
||||
ift, err := net.Interfaces()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i, ifi := range ift {
|
||||
if _, ok := nettest.IsMulticastCapable("ip4", &ifi); !ok {
|
||||
continue
|
||||
}
|
||||
if err := r.JoinGroup(&ifi, &gaddr); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
mift = append(mift, &ift[i])
|
||||
}
|
||||
for _, ifi := range mift {
|
||||
if err := r.LeaveGroup(ifi, &gaddr); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPPerInterfaceSingleRawConnWithSingleGroupListener(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if testing.Short() {
|
||||
t.Skip("to avoid external network")
|
||||
}
|
||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
||||
t.Skip(m)
|
||||
}
|
||||
|
||||
gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
|
||||
type ml struct {
|
||||
c *ipv4.RawConn
|
||||
ifi *net.Interface
|
||||
}
|
||||
var mlt []*ml
|
||||
|
||||
ift, err := net.Interfaces()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i, ifi := range ift {
|
||||
ip, ok := nettest.IsMulticastCapable("ip4", &ifi)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
c, err := net.ListenPacket("ip4:253", ip.String()) // unicast address
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
r, err := ipv4.NewRawConn(c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := r.JoinGroup(&ifi, &gaddr); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
mlt = append(mlt, &ml{r, &ift[i]})
|
||||
}
|
||||
for _, m := range mlt {
|
||||
if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
195
vendor/golang.org/x/net/ipv4/multicastsockopt_test.go
generated
vendored
Normal file
195
vendor/golang.org/x/net/ipv4/multicastsockopt_test.go
generated
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv4_test
|
||||
|
||||
import (
|
||||
"net"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/internal/nettest"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
var packetConnMulticastSocketOptionTests = []struct {
|
||||
net, proto, addr string
|
||||
grp, src net.Addr
|
||||
}{
|
||||
{"udp4", "", "224.0.0.0:0", &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}, nil}, // see RFC 4727
|
||||
{"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil}, // see RFC 4727
|
||||
|
||||
{"udp4", "", "232.0.0.0:0", &net.UDPAddr{IP: net.IPv4(232, 0, 1, 249)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
|
||||
{"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
|
||||
}
|
||||
|
||||
func TestPacketConnMulticastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
|
||||
if ifi == nil {
|
||||
t.Skipf("not available on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
m, ok := nettest.SupportsRawIPSocket()
|
||||
for _, tt := range packetConnMulticastSocketOptionTests {
|
||||
if tt.net == "ip4" && !ok {
|
||||
t.Log(m)
|
||||
continue
|
||||
}
|
||||
c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
p := ipv4.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
|
||||
if tt.src == nil {
|
||||
testMulticastSocketOptions(t, p, ifi, tt.grp)
|
||||
} else {
|
||||
testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var rawConnMulticastSocketOptionTests = []struct {
|
||||
grp, src net.Addr
|
||||
}{
|
||||
{&net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil}, // see RFC 4727
|
||||
|
||||
{&net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
|
||||
}
|
||||
|
||||
func TestRawConnMulticastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
||||
t.Skip(m)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
|
||||
if ifi == nil {
|
||||
t.Skipf("not available on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
for _, tt := range rawConnMulticastSocketOptionTests {
|
||||
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
r, err := ipv4.NewRawConn(c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
if tt.src == nil {
|
||||
testMulticastSocketOptions(t, r, ifi, tt.grp)
|
||||
} else {
|
||||
testSourceSpecificMulticastSocketOptions(t, r, ifi, tt.grp, tt.src)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type testIPv4MulticastConn interface {
|
||||
MulticastTTL() (int, error)
|
||||
SetMulticastTTL(ttl int) error
|
||||
MulticastLoopback() (bool, error)
|
||||
SetMulticastLoopback(bool) error
|
||||
JoinGroup(*net.Interface, net.Addr) error
|
||||
LeaveGroup(*net.Interface, net.Addr) error
|
||||
JoinSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
|
||||
LeaveSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
|
||||
ExcludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
|
||||
IncludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
|
||||
}
|
||||
|
||||
func testMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp net.Addr) {
|
||||
const ttl = 255
|
||||
if err := c.SetMulticastTTL(ttl); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if v, err := c.MulticastTTL(); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
} else if v != ttl {
|
||||
t.Errorf("got %v; want %v", v, ttl)
|
||||
return
|
||||
}
|
||||
|
||||
for _, toggle := range []bool{true, false} {
|
||||
if err := c.SetMulticastLoopback(toggle); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if v, err := c.MulticastLoopback(); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
} else if v != toggle {
|
||||
t.Errorf("got %v; want %v", v, toggle)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.JoinGroup(ifi, grp); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if err := c.LeaveGroup(ifi, grp); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func testSourceSpecificMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp, src net.Addr) {
|
||||
// MCAST_JOIN_GROUP -> MCAST_BLOCK_SOURCE -> MCAST_UNBLOCK_SOURCE -> MCAST_LEAVE_GROUP
|
||||
if err := c.JoinGroup(ifi, grp); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if err := c.ExcludeSourceSpecificGroup(ifi, grp, src); err != nil {
|
||||
switch runtime.GOOS {
|
||||
case "freebsd", "linux":
|
||||
default: // platforms that don't support IGMPv2/3 fail here
|
||||
t.Logf("not supported on %s", runtime.GOOS)
|
||||
return
|
||||
}
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if err := c.IncludeSourceSpecificGroup(ifi, grp, src); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if err := c.LeaveGroup(ifi, grp); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_SOURCE_GROUP
|
||||
if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if err := c.LeaveSourceSpecificGroup(ifi, grp, src); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_GROUP
|
||||
if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if err := c.LeaveGroup(ifi, grp); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
2
vendor/golang.org/x/net/ipv4/packet.go
generated
vendored
2
vendor/golang.org/x/net/ipv4/packet.go
generated
vendored
@@ -64,7 +64,7 @@ func slicePacket(b []byte) (h, p []byte, err error) {
|
||||
//
|
||||
// The IPv4 header h must contain appropriate fields that include:
|
||||
//
|
||||
// Version = ipv4.Version
|
||||
// Version = <must be specified>
|
||||
// Len = <must be specified>
|
||||
// TOS = <must be specified>
|
||||
// TotalLen = <must be specified>
|
||||
|
||||
174
vendor/golang.org/x/net/ipv4/readwrite_test.go
generated
vendored
Normal file
174
vendor/golang.org/x/net/ipv4/readwrite_test.go
generated
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv4_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/internal/nettest"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
func benchmarkUDPListener() (net.PacketConn, net.Addr, error) {
|
||||
c, err := net.ListenPacket("udp4", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String())
|
||||
if err != nil {
|
||||
c.Close()
|
||||
return nil, nil, err
|
||||
}
|
||||
return c, dst, nil
|
||||
}
|
||||
|
||||
func BenchmarkReadWriteNetUDP(b *testing.B) {
|
||||
c, dst, err := benchmarkUDPListener()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
benchmarkReadWriteNetUDP(b, c, wb, rb, dst)
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) {
|
||||
if _, err := c.WriteTo(wb, dst); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
if _, _, err := c.ReadFrom(rb); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkReadWriteIPv4UDP(b *testing.B) {
|
||||
c, dst, err := benchmarkUDPListener()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
p := ipv4.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
cf := ipv4.FlagTTL | ipv4.FlagInterface
|
||||
if err := p.SetControlMessage(cf, true); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
|
||||
|
||||
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
benchmarkReadWriteIPv4UDP(b, p, wb, rb, dst, ifi)
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkReadWriteIPv4UDP(b *testing.B, p *ipv4.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) {
|
||||
cm := ipv4.ControlMessage{TTL: 1}
|
||||
if ifi != nil {
|
||||
cm.IfIndex = ifi.Index
|
||||
}
|
||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
b.Fatal(err)
|
||||
} else if n != len(wb) {
|
||||
b.Fatalf("got %v; want %v", n, len(wb))
|
||||
}
|
||||
if _, _, _, err := p.ReadFrom(rb); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("udp4", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
p := ipv4.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
|
||||
dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
|
||||
cf := ipv4.FlagTTL | ipv4.FlagSrc | ipv4.FlagDst | ipv4.FlagInterface
|
||||
wb := []byte("HELLO-R-U-THERE")
|
||||
|
||||
if err := p.SetControlMessage(cf, true); err != nil { // probe before test
|
||||
if nettest.ProtocolNotSupported(err) {
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
reader := func() {
|
||||
defer wg.Done()
|
||||
rb := make([]byte, 128)
|
||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
} else if !bytes.Equal(rb[:n], wb) {
|
||||
t.Errorf("got %v; want %v", rb[:n], wb)
|
||||
return
|
||||
} else {
|
||||
s := cm.String()
|
||||
if strings.Contains(s, ",") {
|
||||
t.Errorf("should be space-separated values: %s", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
writer := func(toggle bool) {
|
||||
defer wg.Done()
|
||||
cm := ipv4.ControlMessage{
|
||||
Src: net.IPv4(127, 0, 0, 1),
|
||||
}
|
||||
if ifi != nil {
|
||||
cm.IfIndex = ifi.Index
|
||||
}
|
||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
} else if n != len(wb) {
|
||||
t.Errorf("short write: %v", n)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const N = 10
|
||||
wg.Add(N)
|
||||
for i := 0; i < N; i++ {
|
||||
go reader()
|
||||
}
|
||||
wg.Add(2 * N)
|
||||
for i := 0; i < 2*N; i++ {
|
||||
go writer(i%2 != 0)
|
||||
}
|
||||
wg.Add(N)
|
||||
for i := 0; i < N; i++ {
|
||||
go reader()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
57
vendor/golang.org/x/net/ipv4/sys_darwin.go
generated
vendored
57
vendor/golang.org/x/net/ipv4/sys_darwin.go
generated
vendored
@@ -6,6 +6,8 @@ package ipv4
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
@@ -36,41 +38,40 @@ var (
|
||||
func init() {
|
||||
// Seems like kern.osreldate is veiled on latest OS X. We use
|
||||
// kern.osrelease instead.
|
||||
osver, err := syscall.Sysctl("kern.osrelease")
|
||||
s, err := syscall.Sysctl("kern.osrelease")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var i int
|
||||
for i = range osver {
|
||||
if osver[i] == '.' {
|
||||
break
|
||||
}
|
||||
ss := strings.Split(s, ".")
|
||||
if len(ss) == 0 {
|
||||
return
|
||||
}
|
||||
// The IP_PKTINFO and protocol-independent multicast API were
|
||||
// introduced in OS X 10.7 (Darwin 11.0.0). But it looks like
|
||||
// those features require OS X 10.8 (Darwin 12.0.0) and above.
|
||||
// introduced in OS X 10.7 (Darwin 11). But it looks like
|
||||
// those features require OS X 10.8 (Darwin 12) or above.
|
||||
// See http://support.apple.com/kb/HT1633.
|
||||
if i > 2 || i == 2 && osver[0] >= '1' && osver[1] >= '2' {
|
||||
ctlOpts[ctlPacketInfo].name = sysIP_PKTINFO
|
||||
ctlOpts[ctlPacketInfo].length = sizeofInetPktinfo
|
||||
ctlOpts[ctlPacketInfo].marshal = marshalPacketInfo
|
||||
ctlOpts[ctlPacketInfo].parse = parsePacketInfo
|
||||
sockOpts[ssoPacketInfo].name = sysIP_RECVPKTINFO
|
||||
sockOpts[ssoPacketInfo].typ = ssoTypeInt
|
||||
sockOpts[ssoMulticastInterface].typ = ssoTypeIPMreqn
|
||||
sockOpts[ssoJoinGroup].name = sysMCAST_JOIN_GROUP
|
||||
sockOpts[ssoJoinGroup].typ = ssoTypeGroupReq
|
||||
sockOpts[ssoLeaveGroup].name = sysMCAST_LEAVE_GROUP
|
||||
sockOpts[ssoLeaveGroup].typ = ssoTypeGroupReq
|
||||
sockOpts[ssoJoinSourceGroup].name = sysMCAST_JOIN_SOURCE_GROUP
|
||||
sockOpts[ssoJoinSourceGroup].typ = ssoTypeGroupSourceReq
|
||||
sockOpts[ssoLeaveSourceGroup].name = sysMCAST_LEAVE_SOURCE_GROUP
|
||||
sockOpts[ssoLeaveSourceGroup].typ = ssoTypeGroupSourceReq
|
||||
sockOpts[ssoBlockSourceGroup].name = sysMCAST_BLOCK_SOURCE
|
||||
sockOpts[ssoBlockSourceGroup].typ = ssoTypeGroupSourceReq
|
||||
sockOpts[ssoUnblockSourceGroup].name = sysMCAST_UNBLOCK_SOURCE
|
||||
sockOpts[ssoUnblockSourceGroup].typ = ssoTypeGroupSourceReq
|
||||
if mjver, err := strconv.Atoi(ss[0]); err != nil || mjver < 12 {
|
||||
return
|
||||
}
|
||||
ctlOpts[ctlPacketInfo].name = sysIP_PKTINFO
|
||||
ctlOpts[ctlPacketInfo].length = sizeofInetPktinfo
|
||||
ctlOpts[ctlPacketInfo].marshal = marshalPacketInfo
|
||||
ctlOpts[ctlPacketInfo].parse = parsePacketInfo
|
||||
sockOpts[ssoPacketInfo].name = sysIP_RECVPKTINFO
|
||||
sockOpts[ssoPacketInfo].typ = ssoTypeInt
|
||||
sockOpts[ssoMulticastInterface].typ = ssoTypeIPMreqn
|
||||
sockOpts[ssoJoinGroup].name = sysMCAST_JOIN_GROUP
|
||||
sockOpts[ssoJoinGroup].typ = ssoTypeGroupReq
|
||||
sockOpts[ssoLeaveGroup].name = sysMCAST_LEAVE_GROUP
|
||||
sockOpts[ssoLeaveGroup].typ = ssoTypeGroupReq
|
||||
sockOpts[ssoJoinSourceGroup].name = sysMCAST_JOIN_SOURCE_GROUP
|
||||
sockOpts[ssoJoinSourceGroup].typ = ssoTypeGroupSourceReq
|
||||
sockOpts[ssoLeaveSourceGroup].name = sysMCAST_LEAVE_SOURCE_GROUP
|
||||
sockOpts[ssoLeaveSourceGroup].typ = ssoTypeGroupSourceReq
|
||||
sockOpts[ssoBlockSourceGroup].name = sysMCAST_BLOCK_SOURCE
|
||||
sockOpts[ssoBlockSourceGroup].typ = ssoTypeGroupSourceReq
|
||||
sockOpts[ssoUnblockSourceGroup].name = sysMCAST_UNBLOCK_SOURCE
|
||||
sockOpts[ssoUnblockSourceGroup].typ = ssoTypeGroupSourceReq
|
||||
}
|
||||
|
||||
func (pi *inetPktinfo) setIfindex(i int) {
|
||||
|
||||
250
vendor/golang.org/x/net/ipv4/unicast_test.go
generated
vendored
Normal file
250
vendor/golang.org/x/net/ipv4/unicast_test.go
generated
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv4_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/icmp"
|
||||
"golang.org/x/net/internal/iana"
|
||||
"golang.org/x/net/internal/nettest"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
|
||||
if ifi == nil {
|
||||
t.Skipf("not available on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("udp4", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
p := ipv4.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
|
||||
wb := []byte("HELLO-R-U-THERE")
|
||||
|
||||
for i, toggle := range []bool{true, false, true} {
|
||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
||||
if nettest.ProtocolNotSupported(err) {
|
||||
t.Logf("not supported on %s", runtime.GOOS)
|
||||
continue
|
||||
}
|
||||
t.Fatal(err)
|
||||
}
|
||||
p.SetTTL(i + 1)
|
||||
if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if n, err := p.WriteTo(wb, nil, dst); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if n != len(wb) {
|
||||
t.Fatalf("got %v; want %v", n, len(wb))
|
||||
}
|
||||
rb := make([]byte, 128)
|
||||
if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if n, _, _, err := p.ReadFrom(rb); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !bytes.Equal(rb[:n], wb) {
|
||||
t.Fatalf("got %v; want %v", rb[:n], wb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
||||
t.Skip(m)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
|
||||
if ifi == nil {
|
||||
t.Skipf("not available on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
dst, err := net.ResolveIPAddr("ip4", "127.0.0.1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
p := ipv4.NewPacketConn(c)
|
||||
defer p.Close()
|
||||
cf := ipv4.FlagDst | ipv4.FlagInterface
|
||||
if runtime.GOOS != "solaris" {
|
||||
// Solaris never allows to modify ICMP properties.
|
||||
cf |= ipv4.FlagTTL
|
||||
}
|
||||
|
||||
for i, toggle := range []bool{true, false, true} {
|
||||
wb, err := (&icmp.Message{
|
||||
Type: ipv4.ICMPTypeEcho, Code: 0,
|
||||
Body: &icmp.Echo{
|
||||
ID: os.Getpid() & 0xffff, Seq: i + 1,
|
||||
Data: []byte("HELLO-R-U-THERE"),
|
||||
},
|
||||
}).Marshal(nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
||||
if nettest.ProtocolNotSupported(err) {
|
||||
t.Logf("not supported on %s", runtime.GOOS)
|
||||
continue
|
||||
}
|
||||
t.Fatal(err)
|
||||
}
|
||||
p.SetTTL(i + 1)
|
||||
if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if n, err := p.WriteTo(wb, nil, dst); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if n != len(wb) {
|
||||
t.Fatalf("got %v; want %v", n, len(wb))
|
||||
}
|
||||
rb := make([]byte, 128)
|
||||
loop:
|
||||
if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if n, _, _, err := p.ReadFrom(rb); err != nil {
|
||||
switch runtime.GOOS {
|
||||
case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket
|
||||
t.Logf("not supported on %s", runtime.GOOS)
|
||||
continue
|
||||
}
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
m, err := icmp.ParseMessage(iana.ProtocolICMP, rb[:n])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho {
|
||||
// On Linux we must handle own sent packets.
|
||||
goto loop
|
||||
}
|
||||
if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 {
|
||||
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawConnReadWriteUnicastICMP(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
||||
t.Skip(m)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
|
||||
if ifi == nil {
|
||||
t.Skipf("not available on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
dst, err := net.ResolveIPAddr("ip4", "127.0.0.1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r, err := ipv4.NewRawConn(c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer r.Close()
|
||||
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
|
||||
|
||||
for i, toggle := range []bool{true, false, true} {
|
||||
wb, err := (&icmp.Message{
|
||||
Type: ipv4.ICMPTypeEcho, Code: 0,
|
||||
Body: &icmp.Echo{
|
||||
ID: os.Getpid() & 0xffff, Seq: i + 1,
|
||||
Data: []byte("HELLO-R-U-THERE"),
|
||||
},
|
||||
}).Marshal(nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
wh := &ipv4.Header{
|
||||
Version: ipv4.Version,
|
||||
Len: ipv4.HeaderLen,
|
||||
TOS: i + 1,
|
||||
TotalLen: ipv4.HeaderLen + len(wb),
|
||||
TTL: i + 1,
|
||||
Protocol: 1,
|
||||
Dst: dst.IP,
|
||||
}
|
||||
if err := r.SetControlMessage(cf, toggle); err != nil {
|
||||
if nettest.ProtocolNotSupported(err) {
|
||||
t.Logf("not supported on %s", runtime.GOOS)
|
||||
continue
|
||||
}
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := r.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := r.WriteTo(wh, wb, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rb := make([]byte, ipv4.HeaderLen+128)
|
||||
loop:
|
||||
if err := r.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, b, _, err := r.ReadFrom(rb); err != nil {
|
||||
switch runtime.GOOS {
|
||||
case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket
|
||||
t.Logf("not supported on %s", runtime.GOOS)
|
||||
continue
|
||||
}
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
m, err := icmp.ParseMessage(iana.ProtocolICMP, b)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho {
|
||||
// On Linux we must handle own sent packets.
|
||||
goto loop
|
||||
}
|
||||
if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 {
|
||||
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
148
vendor/golang.org/x/net/ipv4/unicastsockopt_test.go
generated
vendored
Normal file
148
vendor/golang.org/x/net/ipv4/unicastsockopt_test.go
generated
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ipv4_test
|
||||
|
||||
import (
|
||||
"net"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/internal/iana"
|
||||
"golang.org/x/net/internal/nettest"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
func TestConnUnicastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
|
||||
if ifi == nil {
|
||||
t.Skipf("not available on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
ln, err := net.Listen("tcp4", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer ln.Close()
|
||||
|
||||
errc := make(chan error, 1)
|
||||
go func() {
|
||||
c, err := ln.Accept()
|
||||
if err != nil {
|
||||
errc <- err
|
||||
return
|
||||
}
|
||||
errc <- c.Close()
|
||||
}()
|
||||
|
||||
c, err := net.Dial("tcp4", ln.Addr().String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
testUnicastSocketOptions(t, ipv4.NewConn(c))
|
||||
|
||||
if err := <-errc; err != nil {
|
||||
t.Errorf("server: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
var packetConnUnicastSocketOptionTests = []struct {
|
||||
net, proto, addr string
|
||||
}{
|
||||
{"udp4", "", "127.0.0.1:0"},
|
||||
{"ip4", ":icmp", "127.0.0.1"},
|
||||
}
|
||||
|
||||
func TestPacketConnUnicastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
|
||||
if ifi == nil {
|
||||
t.Skipf("not available on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
m, ok := nettest.SupportsRawIPSocket()
|
||||
for _, tt := range packetConnUnicastSocketOptionTests {
|
||||
if tt.net == "ip4" && !ok {
|
||||
t.Log(m)
|
||||
continue
|
||||
}
|
||||
c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
testUnicastSocketOptions(t, ipv4.NewPacketConn(c))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRawConnUnicastSocketOptions(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "nacl", "plan9", "windows":
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
||||
t.Skip(m)
|
||||
}
|
||||
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
|
||||
if ifi == nil {
|
||||
t.Skipf("not available on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
c, err := net.ListenPacket("ip4:icmp", "127.0.0.1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
r, err := ipv4.NewRawConn(c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testUnicastSocketOptions(t, r)
|
||||
}
|
||||
|
||||
type testIPv4UnicastConn interface {
|
||||
TOS() (int, error)
|
||||
SetTOS(int) error
|
||||
TTL() (int, error)
|
||||
SetTTL(int) error
|
||||
}
|
||||
|
||||
func testUnicastSocketOptions(t *testing.T, c testIPv4UnicastConn) {
|
||||
tos := iana.DiffServCS0 | iana.NotECNTransport
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
// IP_TOS option is supported on Windows 8 and beyond.
|
||||
t.Skipf("not supported on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
if err := c.SetTOS(tos); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if v, err := c.TOS(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if v != tos {
|
||||
t.Fatalf("got %v; want %v", v, tos)
|
||||
}
|
||||
const ttl = 255
|
||||
if err := c.SetTTL(ttl); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if v, err := c.TTL(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if v != ttl {
|
||||
t.Fatalf("got %v; want %v", v, ttl)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user