You've already forked linux-packaging-mono
Imported Upstream version 4.8.0.309
Former-commit-id: 5f9c6ae75f295e057a7d2971f3a6df4656fa8850
This commit is contained in:
parent
ee1447783b
commit
94b2861243
78
external/boringssl/ssl/test/runner/alert.go
vendored
Normal file
78
external/boringssl/ssl/test/runner/alert.go
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
// 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 runner
|
||||
|
||||
import "strconv"
|
||||
|
||||
type alert uint8
|
||||
|
||||
const (
|
||||
// alert level
|
||||
alertLevelWarning = 1
|
||||
alertLevelError = 2
|
||||
)
|
||||
|
||||
const (
|
||||
alertCloseNotify alert = 0
|
||||
alertUnexpectedMessage alert = 10
|
||||
alertBadRecordMAC alert = 20
|
||||
alertDecryptionFailed alert = 21
|
||||
alertRecordOverflow alert = 22
|
||||
alertDecompressionFailure alert = 30
|
||||
alertHandshakeFailure alert = 40
|
||||
alertNoCertficate alert = 41
|
||||
alertBadCertificate alert = 42
|
||||
alertUnsupportedCertificate alert = 43
|
||||
alertCertificateRevoked alert = 44
|
||||
alertCertificateExpired alert = 45
|
||||
alertCertificateUnknown alert = 46
|
||||
alertIllegalParameter alert = 47
|
||||
alertUnknownCA alert = 48
|
||||
alertAccessDenied alert = 49
|
||||
alertDecodeError alert = 50
|
||||
alertDecryptError alert = 51
|
||||
alertProtocolVersion alert = 70
|
||||
alertInsufficientSecurity alert = 71
|
||||
alertInternalError alert = 80
|
||||
alertUserCanceled alert = 90
|
||||
alertNoRenegotiation alert = 100
|
||||
)
|
||||
|
||||
var alertText = map[alert]string{
|
||||
alertCloseNotify: "close notify",
|
||||
alertUnexpectedMessage: "unexpected message",
|
||||
alertBadRecordMAC: "bad record MAC",
|
||||
alertDecryptionFailed: "decryption failed",
|
||||
alertRecordOverflow: "record overflow",
|
||||
alertDecompressionFailure: "decompression failure",
|
||||
alertHandshakeFailure: "handshake failure",
|
||||
alertBadCertificate: "bad certificate",
|
||||
alertUnsupportedCertificate: "unsupported certificate",
|
||||
alertCertificateRevoked: "revoked certificate",
|
||||
alertCertificateExpired: "expired certificate",
|
||||
alertCertificateUnknown: "unknown certificate",
|
||||
alertIllegalParameter: "illegal parameter",
|
||||
alertUnknownCA: "unknown certificate authority",
|
||||
alertAccessDenied: "access denied",
|
||||
alertDecodeError: "error decoding message",
|
||||
alertDecryptError: "error decrypting message",
|
||||
alertProtocolVersion: "protocol version not supported",
|
||||
alertInsufficientSecurity: "insufficient security level",
|
||||
alertInternalError: "internal error",
|
||||
alertUserCanceled: "user canceled",
|
||||
alertNoRenegotiation: "no renegotiation",
|
||||
}
|
||||
|
||||
func (e alert) String() string {
|
||||
s, ok := alertText[e]
|
||||
if ok {
|
||||
return s
|
||||
}
|
||||
return "alert(" + strconv.Itoa(int(e)) + ")"
|
||||
}
|
||||
|
||||
func (e alert) Error() string {
|
||||
return e.String()
|
||||
}
|
15
external/boringssl/ssl/test/runner/cert.pem
vendored
Normal file
15
external/boringssl/ssl/test/runner/cert.pem
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
|
||||
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||
aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF
|
||||
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
|
||||
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
|
||||
gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci
|
||||
HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV
|
||||
W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV
|
||||
HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f
|
||||
Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht
|
||||
ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr
|
||||
T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f
|
||||
j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==
|
||||
-----END CERTIFICATE-----
|
235
external/boringssl/ssl/test/runner/chacha20_poly1305.go
vendored
Normal file
235
external/boringssl/ssl/test/runner/chacha20_poly1305.go
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
// Copyright (c) 2016, Google Inc.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
package runner
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"crypto/subtle"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
|
||||
"./poly1305"
|
||||
)
|
||||
|
||||
// See RFC 7539.
|
||||
|
||||
func leftRotate(a uint32, n uint) uint32 {
|
||||
return (a << n) | (a >> (32 - n))
|
||||
}
|
||||
|
||||
func chaChaQuarterRound(state *[16]uint32, a, b, c, d int) {
|
||||
state[a] += state[b]
|
||||
state[d] = leftRotate(state[d]^state[a], 16)
|
||||
|
||||
state[c] += state[d]
|
||||
state[b] = leftRotate(state[b]^state[c], 12)
|
||||
|
||||
state[a] += state[b]
|
||||
state[d] = leftRotate(state[d]^state[a], 8)
|
||||
|
||||
state[c] += state[d]
|
||||
state[b] = leftRotate(state[b]^state[c], 7)
|
||||
}
|
||||
|
||||
func chaCha20Block(state *[16]uint32, out []byte) {
|
||||
var workingState [16]uint32
|
||||
copy(workingState[:], state[:])
|
||||
for i := 0; i < 10; i++ {
|
||||
chaChaQuarterRound(&workingState, 0, 4, 8, 12)
|
||||
chaChaQuarterRound(&workingState, 1, 5, 9, 13)
|
||||
chaChaQuarterRound(&workingState, 2, 6, 10, 14)
|
||||
chaChaQuarterRound(&workingState, 3, 7, 11, 15)
|
||||
chaChaQuarterRound(&workingState, 0, 5, 10, 15)
|
||||
chaChaQuarterRound(&workingState, 1, 6, 11, 12)
|
||||
chaChaQuarterRound(&workingState, 2, 7, 8, 13)
|
||||
chaChaQuarterRound(&workingState, 3, 4, 9, 14)
|
||||
}
|
||||
for i := 0; i < 16; i++ {
|
||||
binary.LittleEndian.PutUint32(out[i*4:i*4+4], workingState[i]+state[i])
|
||||
}
|
||||
}
|
||||
|
||||
// sliceForAppend takes a slice and a requested number of bytes. It returns a
|
||||
// slice with the contents of the given slice followed by that many bytes and a
|
||||
// second slice that aliases into it and contains only the extra bytes. If the
|
||||
// original slice has sufficient capacity then no allocation is performed.
|
||||
func sliceForAppend(in []byte, n int) (head, tail []byte) {
|
||||
if total := len(in) + n; cap(in) >= total {
|
||||
head = in[:total]
|
||||
} else {
|
||||
head = make([]byte, total)
|
||||
copy(head, in)
|
||||
}
|
||||
tail = head[len(in):]
|
||||
return
|
||||
}
|
||||
|
||||
func chaCha20(out, in, key, nonce []byte, counter uint64) {
|
||||
var state [16]uint32
|
||||
state[0] = 0x61707865
|
||||
state[1] = 0x3320646e
|
||||
state[2] = 0x79622d32
|
||||
state[3] = 0x6b206574
|
||||
for i := 0; i < 8; i++ {
|
||||
state[4+i] = binary.LittleEndian.Uint32(key[i*4 : i*4+4])
|
||||
}
|
||||
|
||||
switch len(nonce) {
|
||||
case 8:
|
||||
state[14] = binary.LittleEndian.Uint32(nonce[0:4])
|
||||
state[15] = binary.LittleEndian.Uint32(nonce[4:8])
|
||||
case 12:
|
||||
state[13] = binary.LittleEndian.Uint32(nonce[0:4])
|
||||
state[14] = binary.LittleEndian.Uint32(nonce[4:8])
|
||||
state[15] = binary.LittleEndian.Uint32(nonce[8:12])
|
||||
default:
|
||||
panic("bad nonce length")
|
||||
}
|
||||
|
||||
for i := 0; i < len(in); i += 64 {
|
||||
state[12] = uint32(counter)
|
||||
|
||||
var tmp [64]byte
|
||||
chaCha20Block(&state, tmp[:])
|
||||
count := 64
|
||||
if len(in)-i < count {
|
||||
count = len(in) - i
|
||||
}
|
||||
for j := 0; j < count; j++ {
|
||||
out[i+j] = in[i+j] ^ tmp[j]
|
||||
}
|
||||
|
||||
counter++
|
||||
}
|
||||
}
|
||||
|
||||
// chaCha20Poly1305 implements the AEAD from
|
||||
// RFC 7539 and draft-agl-tls-chacha20poly1305-04.
|
||||
type chaCha20Poly1305 struct {
|
||||
key [32]byte
|
||||
// oldMode, if true, indicates that the draft spec should be
|
||||
// implemented rather than the final, RFC version.
|
||||
oldMode bool
|
||||
}
|
||||
|
||||
func newChaCha20Poly1305(key []byte) (cipher.AEAD, error) {
|
||||
if len(key) != 32 {
|
||||
return nil, errors.New("bad key length")
|
||||
}
|
||||
aead := new(chaCha20Poly1305)
|
||||
copy(aead.key[:], key)
|
||||
return aead, nil
|
||||
}
|
||||
|
||||
func newChaCha20Poly1305Old(key []byte) (cipher.AEAD, error) {
|
||||
if len(key) != 32 {
|
||||
return nil, errors.New("bad key length")
|
||||
}
|
||||
aead := &chaCha20Poly1305{
|
||||
oldMode: true,
|
||||
}
|
||||
copy(aead.key[:], key)
|
||||
return aead, nil
|
||||
}
|
||||
|
||||
func (c *chaCha20Poly1305) NonceSize() int {
|
||||
if c.oldMode {
|
||||
return 8
|
||||
} else {
|
||||
return 12
|
||||
}
|
||||
}
|
||||
|
||||
func (c *chaCha20Poly1305) Overhead() int { return 16 }
|
||||
|
||||
func (c *chaCha20Poly1305) poly1305(tag *[16]byte, nonce, ciphertext, additionalData []byte) {
|
||||
input := make([]byte, 0, len(additionalData)+15+len(ciphertext)+15+8+8)
|
||||
input = append(input, additionalData...)
|
||||
var zeros [15]byte
|
||||
if pad := len(input) % 16; pad != 0 {
|
||||
input = append(input, zeros[:16-pad]...)
|
||||
}
|
||||
input = append(input, ciphertext...)
|
||||
if pad := len(input) % 16; pad != 0 {
|
||||
input = append(input, zeros[:16-pad]...)
|
||||
}
|
||||
input, out := sliceForAppend(input, 8)
|
||||
binary.LittleEndian.PutUint64(out, uint64(len(additionalData)))
|
||||
input, out = sliceForAppend(input, 8)
|
||||
binary.LittleEndian.PutUint64(out, uint64(len(ciphertext)))
|
||||
|
||||
var poly1305Key [32]byte
|
||||
chaCha20(poly1305Key[:], poly1305Key[:], c.key[:], nonce, 0)
|
||||
|
||||
poly1305.Sum(tag, input, &poly1305Key)
|
||||
}
|
||||
|
||||
func (c *chaCha20Poly1305) poly1305Old(tag *[16]byte, nonce, ciphertext, additionalData []byte) {
|
||||
input := make([]byte, 0, len(additionalData)+8+len(ciphertext)+8)
|
||||
input = append(input, additionalData...)
|
||||
input, out := sliceForAppend(input, 8)
|
||||
binary.LittleEndian.PutUint64(out, uint64(len(additionalData)))
|
||||
input = append(input, ciphertext...)
|
||||
input, out = sliceForAppend(input, 8)
|
||||
binary.LittleEndian.PutUint64(out, uint64(len(ciphertext)))
|
||||
|
||||
var poly1305Key [32]byte
|
||||
chaCha20(poly1305Key[:], poly1305Key[:], c.key[:], nonce, 0)
|
||||
|
||||
poly1305.Sum(tag, input, &poly1305Key)
|
||||
}
|
||||
|
||||
func (c *chaCha20Poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
|
||||
if len(nonce) != c.NonceSize() {
|
||||
panic("Bad nonce length")
|
||||
}
|
||||
|
||||
ret, out := sliceForAppend(dst, len(plaintext)+16)
|
||||
chaCha20(out[:len(plaintext)], plaintext, c.key[:], nonce, 1)
|
||||
|
||||
var tag [16]byte
|
||||
if c.oldMode {
|
||||
c.poly1305Old(&tag, nonce, out[:len(plaintext)], additionalData)
|
||||
} else {
|
||||
c.poly1305(&tag, nonce, out[:len(plaintext)], additionalData)
|
||||
}
|
||||
copy(out[len(plaintext):], tag[:])
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (c *chaCha20Poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
|
||||
if len(nonce) != c.NonceSize() {
|
||||
panic("Bad nonce length")
|
||||
}
|
||||
if len(ciphertext) < 16 {
|
||||
return nil, errors.New("chacha20: message authentication failed")
|
||||
}
|
||||
plaintextLen := len(ciphertext) - 16
|
||||
|
||||
var tag [16]byte
|
||||
if c.oldMode {
|
||||
c.poly1305Old(&tag, nonce, ciphertext[:plaintextLen], additionalData)
|
||||
} else {
|
||||
c.poly1305(&tag, nonce, ciphertext[:plaintextLen], additionalData)
|
||||
}
|
||||
if subtle.ConstantTimeCompare(tag[:], ciphertext[plaintextLen:]) != 1 {
|
||||
return nil, errors.New("chacha20: message authentication failed")
|
||||
}
|
||||
|
||||
ret, out := sliceForAppend(dst, plaintextLen)
|
||||
chaCha20(out, ciphertext[:plaintextLen], c.key[:], nonce, 1)
|
||||
return ret, nil
|
||||
}
|
176
external/boringssl/ssl/test/runner/chacha20_poly1305_test.go
vendored
Normal file
176
external/boringssl/ssl/test/runner/chacha20_poly1305_test.go
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
// Copyright (c) 2016, Google Inc.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
package runner
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// See RFC 7539, section 2.1.1.
|
||||
func TestChaChaQuarterRound(t *testing.T) {
|
||||
state := [16]uint32{0x11111111, 0x01020304, 0x9b8d6f43, 0x01234567}
|
||||
chaChaQuarterRound(&state, 0, 1, 2, 3)
|
||||
|
||||
a, b, c, d := state[0], state[1], state[2], state[3]
|
||||
if a != 0xea2a92f4 || b != 0xcb1cf8ce || c != 0x4581472e || d != 0x5881c4bb {
|
||||
t.Errorf("Incorrect results: %x", state)
|
||||
}
|
||||
}
|
||||
|
||||
// See RFC 7539, section 2.2.1.
|
||||
func TestChaChaQuarterRoundState(t *testing.T) {
|
||||
state := [16]uint32{
|
||||
0x879531e0, 0xc5ecf37d, 0x516461b1, 0xc9a62f8a,
|
||||
0x44c20ef3, 0x3390af7f, 0xd9fc690b, 0x2a5f714c,
|
||||
0x53372767, 0xb00a5631, 0x974c541a, 0x359e9963,
|
||||
0x5c971061, 0x3d631689, 0x2098d9d6, 0x91dbd320,
|
||||
}
|
||||
chaChaQuarterRound(&state, 2, 7, 8, 13)
|
||||
|
||||
expected := [16]uint32{
|
||||
0x879531e0, 0xc5ecf37d, 0xbdb886dc, 0xc9a62f8a,
|
||||
0x44c20ef3, 0x3390af7f, 0xd9fc690b, 0xcfacafd2,
|
||||
0xe46bea80, 0xb00a5631, 0x974c541a, 0x359e9963,
|
||||
0x5c971061, 0xccc07c79, 0x2098d9d6, 0x91dbd320,
|
||||
}
|
||||
for i := range state {
|
||||
if state[i] != expected[i] {
|
||||
t.Errorf("Mismatch at %d: %x vs %x", i, state, expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See RFC 7539, section 2.3.2.
|
||||
func TestChaCha20Block(t *testing.T) {
|
||||
state := [16]uint32{
|
||||
0x61707865, 0x3320646e, 0x79622d32, 0x6b206574,
|
||||
0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
|
||||
0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c,
|
||||
0x00000001, 0x09000000, 0x4a000000, 0x00000000,
|
||||
}
|
||||
out := make([]byte, 64)
|
||||
chaCha20Block(&state, out)
|
||||
|
||||
expected := []byte{
|
||||
0x10, 0xf1, 0xe7, 0xe4, 0xd1, 0x3b, 0x59, 0x15,
|
||||
0x50, 0x0f, 0xdd, 0x1f, 0xa3, 0x20, 0x71, 0xc4,
|
||||
0xc7, 0xd1, 0xf4, 0xc7, 0x33, 0xc0, 0x68, 0x03,
|
||||
0x04, 0x22, 0xaa, 0x9a, 0xc3, 0xd4, 0x6c, 0x4e,
|
||||
0xd2, 0x82, 0x64, 0x46, 0x07, 0x9f, 0xaa, 0x09,
|
||||
0x14, 0xc2, 0xd7, 0x05, 0xd9, 0x8b, 0x02, 0xa2,
|
||||
0xb5, 0x12, 0x9c, 0xd1, 0xde, 0x16, 0x4e, 0xb9,
|
||||
0xcb, 0xd0, 0x83, 0xe8, 0xa2, 0x50, 0x3c, 0x4e,
|
||||
}
|
||||
if !bytes.Equal(out, expected) {
|
||||
t.Errorf("Got %x, wanted %x", out, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func decodeHexOrPanic(in string) []byte {
|
||||
out, err := hex.DecodeString(in)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// See draft-agl-tls-chacha20poly1305-04, section 7.
|
||||
func TestChaCha20Poly1305Old(t *testing.T) {
|
||||
key := decodeHexOrPanic("4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007")
|
||||
input := decodeHexOrPanic("86d09974840bded2a5ca")
|
||||
nonce := decodeHexOrPanic("cd7cf67be39c794a")
|
||||
ad := decodeHexOrPanic("87e229d4500845a079c0")
|
||||
output := decodeHexOrPanic("e3e446f7ede9a19b62a4677dabf4e3d24b876bb284753896e1d6")
|
||||
|
||||
aead, err := newChaCha20Poly1305Old(key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
out, err := aead.Open(nil, nonce, output, ad)
|
||||
if err != nil {
|
||||
t.Errorf("Open failed: %s", err)
|
||||
} else if !bytes.Equal(out, input) {
|
||||
t.Errorf("Open gave %x, wanted %x", out, input)
|
||||
}
|
||||
|
||||
out = aead.Seal(nil, nonce, input, ad)
|
||||
if !bytes.Equal(out, output) {
|
||||
t.Errorf("Open gave %x, wanted %x", out, output)
|
||||
}
|
||||
|
||||
out[0]++
|
||||
_, err = aead.Open(nil, nonce, out, ad)
|
||||
if err == nil {
|
||||
t.Errorf("Open on malformed data unexpectedly succeeded")
|
||||
}
|
||||
}
|
||||
|
||||
var chaCha20Poly1305TestVectors = []struct {
|
||||
key, input, nonce, ad, output string
|
||||
}{
|
||||
{
|
||||
// See RFC 7539, section 2.8.2.
|
||||
key: "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
|
||||
input: "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e",
|
||||
nonce: "070000004041424344454647",
|
||||
ad: "50515253c0c1c2c3c4c5c6c7",
|
||||
output: "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691",
|
||||
},
|
||||
{
|
||||
// See RFC 7539, section A.5.
|
||||
key: "1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0",
|
||||
input: "496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d",
|
||||
nonce: "000000000102030405060708",
|
||||
ad: "f33388860000000000004e91",
|
||||
output: "64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709beead9d67890cbb22392336fea1851f38",
|
||||
},
|
||||
}
|
||||
|
||||
// See draft-agl-tls-chacha20poly1305-04, section 7.
|
||||
func TestChaCha20Poly1305(t *testing.T) {
|
||||
for i, tt := range chaCha20Poly1305TestVectors {
|
||||
key := decodeHexOrPanic(tt.key)
|
||||
input := decodeHexOrPanic(tt.input)
|
||||
nonce := decodeHexOrPanic(tt.nonce)
|
||||
ad := decodeHexOrPanic(tt.ad)
|
||||
output := decodeHexOrPanic(tt.output)
|
||||
|
||||
aead, err := newChaCha20Poly1305(key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
out, err := aead.Open(nil, nonce, output, ad)
|
||||
if err != nil {
|
||||
t.Errorf("%d. Open failed: %s", i, err)
|
||||
} else if !bytes.Equal(out, input) {
|
||||
t.Errorf("%d. Open gave %x, wanted %x", i, out, input)
|
||||
}
|
||||
|
||||
out = aead.Seal(nil, nonce, input, ad)
|
||||
if !bytes.Equal(out, output) {
|
||||
t.Errorf("%d. Open gave %x, wanted %x", i, out, output)
|
||||
}
|
||||
|
||||
out[0]++
|
||||
_, err = aead.Open(nil, nonce, out, ad)
|
||||
if err == nil {
|
||||
t.Errorf("%d. Open on malformed data unexpectedly succeeded", i)
|
||||
}
|
||||
}
|
||||
}
|
5
external/boringssl/ssl/test/runner/channel_id_key.pem
vendored
Normal file
5
external/boringssl/ssl/test/runner/channel_id_key.pem
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIPwxu50c7LEhVNRYJFRWBUnoaz7JSos96T5hBp4rjyptoAoGCCqGSM49
|
||||
AwEHoUQDQgAEzFSVTE5guxJRQ0VbZ8dicPs5e/DT7xpW7Yc9hq0VOchv7cbXuI/T
|
||||
CwadDjGWX/oaz0ftFqrVmfkwZu+C58ioWg==
|
||||
-----END EC PRIVATE KEY-----
|
508
external/boringssl/ssl/test/runner/cipher_suites.go
vendored
Normal file
508
external/boringssl/ssl/test/runner/cipher_suites.go
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1200
external/boringssl/ssl/test/runner/common.go
vendored
Normal file
1200
external/boringssl/ssl/test/runner/common.go
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1451
external/boringssl/ssl/test/runner/conn.go
vendored
Normal file
1451
external/boringssl/ssl/test/runner/conn.go
vendored
Normal file
File diff suppressed because it is too large
Load Diff
20
external/boringssl/ssl/test/runner/curve25519/const_amd64.s
vendored
Normal file
20
external/boringssl/ssl/test/runner/curve25519/const_amd64.s
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// 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.
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
DATA ·REDMASK51(SB)/8, $0x0007FFFFFFFFFFFF
|
||||
GLOBL ·REDMASK51(SB), 8, $8
|
||||
|
||||
DATA ·_121666_213(SB)/8, $996687872
|
||||
GLOBL ·_121666_213(SB), 8, $8
|
||||
|
||||
DATA ·_2P0(SB)/8, $0xFFFFFFFFFFFDA
|
||||
GLOBL ·_2P0(SB), 8, $8
|
||||
|
||||
DATA ·_2P1234(SB)/8, $0xFFFFFFFFFFFFE
|
||||
GLOBL ·_2P1234(SB), 8, $8
|
88
external/boringssl/ssl/test/runner/curve25519/cswap_amd64.s
vendored
Normal file
88
external/boringssl/ssl/test/runner/curve25519/cswap_amd64.s
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
// 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.
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
// func cswap(inout *[5]uint64, v uint64)
|
||||
TEXT ·cswap(SB),7,$0
|
||||
MOVQ inout+0(FP),DI
|
||||
MOVQ v+8(FP),SI
|
||||
|
||||
CMPQ SI,$1
|
||||
MOVQ 0(DI),SI
|
||||
MOVQ 80(DI),DX
|
||||
MOVQ 8(DI),CX
|
||||
MOVQ 88(DI),R8
|
||||
MOVQ SI,R9
|
||||
CMOVQEQ DX,SI
|
||||
CMOVQEQ R9,DX
|
||||
MOVQ CX,R9
|
||||
CMOVQEQ R8,CX
|
||||
CMOVQEQ R9,R8
|
||||
MOVQ SI,0(DI)
|
||||
MOVQ DX,80(DI)
|
||||
MOVQ CX,8(DI)
|
||||
MOVQ R8,88(DI)
|
||||
MOVQ 16(DI),SI
|
||||
MOVQ 96(DI),DX
|
||||
MOVQ 24(DI),CX
|
||||
MOVQ 104(DI),R8
|
||||
MOVQ SI,R9
|
||||
CMOVQEQ DX,SI
|
||||
CMOVQEQ R9,DX
|
||||
MOVQ CX,R9
|
||||
CMOVQEQ R8,CX
|
||||
CMOVQEQ R9,R8
|
||||
MOVQ SI,16(DI)
|
||||
MOVQ DX,96(DI)
|
||||
MOVQ CX,24(DI)
|
||||
MOVQ R8,104(DI)
|
||||
MOVQ 32(DI),SI
|
||||
MOVQ 112(DI),DX
|
||||
MOVQ 40(DI),CX
|
||||
MOVQ 120(DI),R8
|
||||
MOVQ SI,R9
|
||||
CMOVQEQ DX,SI
|
||||
CMOVQEQ R9,DX
|
||||
MOVQ CX,R9
|
||||
CMOVQEQ R8,CX
|
||||
CMOVQEQ R9,R8
|
||||
MOVQ SI,32(DI)
|
||||
MOVQ DX,112(DI)
|
||||
MOVQ CX,40(DI)
|
||||
MOVQ R8,120(DI)
|
||||
MOVQ 48(DI),SI
|
||||
MOVQ 128(DI),DX
|
||||
MOVQ 56(DI),CX
|
||||
MOVQ 136(DI),R8
|
||||
MOVQ SI,R9
|
||||
CMOVQEQ DX,SI
|
||||
CMOVQEQ R9,DX
|
||||
MOVQ CX,R9
|
||||
CMOVQEQ R8,CX
|
||||
CMOVQEQ R9,R8
|
||||
MOVQ SI,48(DI)
|
||||
MOVQ DX,128(DI)
|
||||
MOVQ CX,56(DI)
|
||||
MOVQ R8,136(DI)
|
||||
MOVQ 64(DI),SI
|
||||
MOVQ 144(DI),DX
|
||||
MOVQ 72(DI),CX
|
||||
MOVQ 152(DI),R8
|
||||
MOVQ SI,R9
|
||||
CMOVQEQ DX,SI
|
||||
CMOVQEQ R9,DX
|
||||
MOVQ CX,R9
|
||||
CMOVQEQ R8,CX
|
||||
CMOVQEQ R9,R8
|
||||
MOVQ SI,64(DI)
|
||||
MOVQ DX,144(DI)
|
||||
MOVQ CX,72(DI)
|
||||
MOVQ R8,152(DI)
|
||||
MOVQ DI,AX
|
||||
MOVQ SI,DX
|
||||
RET
|
841
external/boringssl/ssl/test/runner/curve25519/curve25519.go
vendored
Normal file
841
external/boringssl/ssl/test/runner/curve25519/curve25519.go
vendored
Normal file
File diff suppressed because it is too large
Load Diff
29
external/boringssl/ssl/test/runner/curve25519/curve25519_test.go
vendored
Normal file
29
external/boringssl/ssl/test/runner/curve25519/curve25519_test.go
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// 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 curve25519
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const expectedHex = "89161fde887b2b53de549af483940106ecc114d6982daa98256de23bdf77661a"
|
||||
|
||||
func TestBaseScalarMult(t *testing.T) {
|
||||
var a, b [32]byte
|
||||
in := &a
|
||||
out := &b
|
||||
a[0] = 1
|
||||
|
||||
for i := 0; i < 200; i++ {
|
||||
ScalarBaseMult(out, in)
|
||||
in, out = out, in
|
||||
}
|
||||
|
||||
result := fmt.Sprintf("%x", in[:])
|
||||
if result != expectedHex {
|
||||
t.Errorf("incorrect result: got %s, want %s", result, expectedHex)
|
||||
}
|
||||
}
|
23
external/boringssl/ssl/test/runner/curve25519/doc.go
vendored
Normal file
23
external/boringssl/ssl/test/runner/curve25519/doc.go
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.
|
||||
|
||||
// Package curve25519 provides an implementation of scalar multiplication on
|
||||
// the elliptic curve known as curve25519. See http://cr.yp.to/ecdh.html
|
||||
package curve25519 // import "golang.org/x/crypto/curve25519"
|
||||
|
||||
// basePoint is the x coordinate of the generator of the curve.
|
||||
var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
// ScalarMult sets dst to the product in*base where dst and base are the x
|
||||
// coordinates of group points and all values are in little-endian form.
|
||||
func ScalarMult(dst, in, base *[32]byte) {
|
||||
scalarMult(dst, in, base)
|
||||
}
|
||||
|
||||
// ScalarBaseMult sets dst to the product in*base where dst and base are the x
|
||||
// coordinates of group points, base is the standard generator and all values
|
||||
// are in little-endian form.
|
||||
func ScalarBaseMult(dst, in *[32]byte) {
|
||||
ScalarMult(dst, in, &basePoint)
|
||||
}
|
94
external/boringssl/ssl/test/runner/curve25519/freeze_amd64.s
vendored
Normal file
94
external/boringssl/ssl/test/runner/curve25519/freeze_amd64.s
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
// 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.
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
// func freeze(inout *[5]uint64)
|
||||
TEXT ·freeze(SB),7,$96-8
|
||||
MOVQ inout+0(FP), DI
|
||||
|
||||
MOVQ SP,R11
|
||||
MOVQ $31,CX
|
||||
NOTQ CX
|
||||
ANDQ CX,SP
|
||||
ADDQ $32,SP
|
||||
|
||||
MOVQ R11,0(SP)
|
||||
MOVQ R12,8(SP)
|
||||
MOVQ R13,16(SP)
|
||||
MOVQ R14,24(SP)
|
||||
MOVQ R15,32(SP)
|
||||
MOVQ BX,40(SP)
|
||||
MOVQ BP,48(SP)
|
||||
MOVQ 0(DI),SI
|
||||
MOVQ 8(DI),DX
|
||||
MOVQ 16(DI),CX
|
||||
MOVQ 24(DI),R8
|
||||
MOVQ 32(DI),R9
|
||||
MOVQ ·REDMASK51(SB),AX
|
||||
MOVQ AX,R10
|
||||
SUBQ $18,R10
|
||||
MOVQ $3,R11
|
||||
REDUCELOOP:
|
||||
MOVQ SI,R12
|
||||
SHRQ $51,R12
|
||||
ANDQ AX,SI
|
||||
ADDQ R12,DX
|
||||
MOVQ DX,R12
|
||||
SHRQ $51,R12
|
||||
ANDQ AX,DX
|
||||
ADDQ R12,CX
|
||||
MOVQ CX,R12
|
||||
SHRQ $51,R12
|
||||
ANDQ AX,CX
|
||||
ADDQ R12,R8
|
||||
MOVQ R8,R12
|
||||
SHRQ $51,R12
|
||||
ANDQ AX,R8
|
||||
ADDQ R12,R9
|
||||
MOVQ R9,R12
|
||||
SHRQ $51,R12
|
||||
ANDQ AX,R9
|
||||
IMUL3Q $19,R12,R12
|
||||
ADDQ R12,SI
|
||||
SUBQ $1,R11
|
||||
JA REDUCELOOP
|
||||
MOVQ $1,R12
|
||||
CMPQ R10,SI
|
||||
CMOVQLT R11,R12
|
||||
CMPQ AX,DX
|
||||
CMOVQNE R11,R12
|
||||
CMPQ AX,CX
|
||||
CMOVQNE R11,R12
|
||||
CMPQ AX,R8
|
||||
CMOVQNE R11,R12
|
||||
CMPQ AX,R9
|
||||
CMOVQNE R11,R12
|
||||
NEGQ R12
|
||||
ANDQ R12,AX
|
||||
ANDQ R12,R10
|
||||
SUBQ R10,SI
|
||||
SUBQ AX,DX
|
||||
SUBQ AX,CX
|
||||
SUBQ AX,R8
|
||||
SUBQ AX,R9
|
||||
MOVQ SI,0(DI)
|
||||
MOVQ DX,8(DI)
|
||||
MOVQ CX,16(DI)
|
||||
MOVQ R8,24(DI)
|
||||
MOVQ R9,32(DI)
|
||||
MOVQ 0(SP),R11
|
||||
MOVQ 8(SP),R12
|
||||
MOVQ 16(SP),R13
|
||||
MOVQ 24(SP),R14
|
||||
MOVQ 32(SP),R15
|
||||
MOVQ 40(SP),BX
|
||||
MOVQ 48(SP),BP
|
||||
MOVQ R11,SP
|
||||
MOVQ DI,AX
|
||||
MOVQ SI,DX
|
||||
RET
|
1398
external/boringssl/ssl/test/runner/curve25519/ladderstep_amd64.s
vendored
Normal file
1398
external/boringssl/ssl/test/runner/curve25519/ladderstep_amd64.s
vendored
Normal file
File diff suppressed because it is too large
Load Diff
240
external/boringssl/ssl/test/runner/curve25519/mont25519_amd64.go
vendored
Normal file
240
external/boringssl/ssl/test/runner/curve25519/mont25519_amd64.go
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
// 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,!gccgo,!appengine
|
||||
|
||||
package curve25519
|
||||
|
||||
// These functions are implemented in the .s files. The names of the functions
|
||||
// in the rest of the file are also taken from the SUPERCOP sources to help
|
||||
// people following along.
|
||||
|
||||
//go:noescape
|
||||
|
||||
func cswap(inout *[5]uint64, v uint64)
|
||||
|
||||
//go:noescape
|
||||
|
||||
func ladderstep(inout *[5][5]uint64)
|
||||
|
||||
//go:noescape
|
||||
|
||||
func freeze(inout *[5]uint64)
|
||||
|
||||
//go:noescape
|
||||
|
||||
func mul(dest, a, b *[5]uint64)
|
||||
|
||||
//go:noescape
|
||||
|
||||
func square(out, in *[5]uint64)
|
||||
|
||||
// mladder uses a Montgomery ladder to calculate (xr/zr) *= s.
|
||||
func mladder(xr, zr *[5]uint64, s *[32]byte) {
|
||||
var work [5][5]uint64
|
||||
|
||||
work[0] = *xr
|
||||
setint(&work[1], 1)
|
||||
setint(&work[2], 0)
|
||||
work[3] = *xr
|
||||
setint(&work[4], 1)
|
||||
|
||||
j := uint(6)
|
||||
var prevbit byte
|
||||
|
||||
for i := 31; i >= 0; i-- {
|
||||
for j < 8 {
|
||||
bit := ((*s)[i] >> j) & 1
|
||||
swap := bit ^ prevbit
|
||||
prevbit = bit
|
||||
cswap(&work[1], uint64(swap))
|
||||
ladderstep(&work)
|
||||
j--
|
||||
}
|
||||
j = 7
|
||||
}
|
||||
|
||||
*xr = work[1]
|
||||
*zr = work[2]
|
||||
}
|
||||
|
||||
func scalarMult(out, in, base *[32]byte) {
|
||||
var e [32]byte
|
||||
copy(e[:], (*in)[:])
|
||||
e[0] &= 248
|
||||
e[31] &= 127
|
||||
e[31] |= 64
|
||||
|
||||
var t, z [5]uint64
|
||||
unpack(&t, base)
|
||||
mladder(&t, &z, &e)
|
||||
invert(&z, &z)
|
||||
mul(&t, &t, &z)
|
||||
pack(out, &t)
|
||||
}
|
||||
|
||||
func setint(r *[5]uint64, v uint64) {
|
||||
r[0] = v
|
||||
r[1] = 0
|
||||
r[2] = 0
|
||||
r[3] = 0
|
||||
r[4] = 0
|
||||
}
|
||||
|
||||
// unpack sets r = x where r consists of 5, 51-bit limbs in little-endian
|
||||
// order.
|
||||
func unpack(r *[5]uint64, x *[32]byte) {
|
||||
r[0] = uint64(x[0]) |
|
||||
uint64(x[1])<<8 |
|
||||
uint64(x[2])<<16 |
|
||||
uint64(x[3])<<24 |
|
||||
uint64(x[4])<<32 |
|
||||
uint64(x[5])<<40 |
|
||||
uint64(x[6]&7)<<48
|
||||
|
||||
r[1] = uint64(x[6])>>3 |
|
||||
uint64(x[7])<<5 |
|
||||
uint64(x[8])<<13 |
|
||||
uint64(x[9])<<21 |
|
||||
uint64(x[10])<<29 |
|
||||
uint64(x[11])<<37 |
|
||||
uint64(x[12]&63)<<45
|
||||
|
||||
r[2] = uint64(x[12])>>6 |
|
||||
uint64(x[13])<<2 |
|
||||
uint64(x[14])<<10 |
|
||||
uint64(x[15])<<18 |
|
||||
uint64(x[16])<<26 |
|
||||
uint64(x[17])<<34 |
|
||||
uint64(x[18])<<42 |
|
||||
uint64(x[19]&1)<<50
|
||||
|
||||
r[3] = uint64(x[19])>>1 |
|
||||
uint64(x[20])<<7 |
|
||||
uint64(x[21])<<15 |
|
||||
uint64(x[22])<<23 |
|
||||
uint64(x[23])<<31 |
|
||||
uint64(x[24])<<39 |
|
||||
uint64(x[25]&15)<<47
|
||||
|
||||
r[4] = uint64(x[25])>>4 |
|
||||
uint64(x[26])<<4 |
|
||||
uint64(x[27])<<12 |
|
||||
uint64(x[28])<<20 |
|
||||
uint64(x[29])<<28 |
|
||||
uint64(x[30])<<36 |
|
||||
uint64(x[31]&127)<<44
|
||||
}
|
||||
|
||||
// pack sets out = x where out is the usual, little-endian form of the 5,
|
||||
// 51-bit limbs in x.
|
||||
func pack(out *[32]byte, x *[5]uint64) {
|
||||
t := *x
|
||||
freeze(&t)
|
||||
|
||||
out[0] = byte(t[0])
|
||||
out[1] = byte(t[0] >> 8)
|
||||
out[2] = byte(t[0] >> 16)
|
||||
out[3] = byte(t[0] >> 24)
|
||||
out[4] = byte(t[0] >> 32)
|
||||
out[5] = byte(t[0] >> 40)
|
||||
out[6] = byte(t[0] >> 48)
|
||||
|
||||
out[6] ^= byte(t[1]<<3) & 0xf8
|
||||
out[7] = byte(t[1] >> 5)
|
||||
out[8] = byte(t[1] >> 13)
|
||||
out[9] = byte(t[1] >> 21)
|
||||
out[10] = byte(t[1] >> 29)
|
||||
out[11] = byte(t[1] >> 37)
|
||||
out[12] = byte(t[1] >> 45)
|
||||
|
||||
out[12] ^= byte(t[2]<<6) & 0xc0
|
||||
out[13] = byte(t[2] >> 2)
|
||||
out[14] = byte(t[2] >> 10)
|
||||
out[15] = byte(t[2] >> 18)
|
||||
out[16] = byte(t[2] >> 26)
|
||||
out[17] = byte(t[2] >> 34)
|
||||
out[18] = byte(t[2] >> 42)
|
||||
out[19] = byte(t[2] >> 50)
|
||||
|
||||
out[19] ^= byte(t[3]<<1) & 0xfe
|
||||
out[20] = byte(t[3] >> 7)
|
||||
out[21] = byte(t[3] >> 15)
|
||||
out[22] = byte(t[3] >> 23)
|
||||
out[23] = byte(t[3] >> 31)
|
||||
out[24] = byte(t[3] >> 39)
|
||||
out[25] = byte(t[3] >> 47)
|
||||
|
||||
out[25] ^= byte(t[4]<<4) & 0xf0
|
||||
out[26] = byte(t[4] >> 4)
|
||||
out[27] = byte(t[4] >> 12)
|
||||
out[28] = byte(t[4] >> 20)
|
||||
out[29] = byte(t[4] >> 28)
|
||||
out[30] = byte(t[4] >> 36)
|
||||
out[31] = byte(t[4] >> 44)
|
||||
}
|
||||
|
||||
// invert calculates r = x^-1 mod p using Fermat's little theorem.
|
||||
func invert(r *[5]uint64, x *[5]uint64) {
|
||||
var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t [5]uint64
|
||||
|
||||
square(&z2, x) /* 2 */
|
||||
square(&t, &z2) /* 4 */
|
||||
square(&t, &t) /* 8 */
|
||||
mul(&z9, &t, x) /* 9 */
|
||||
mul(&z11, &z9, &z2) /* 11 */
|
||||
square(&t, &z11) /* 22 */
|
||||
mul(&z2_5_0, &t, &z9) /* 2^5 - 2^0 = 31 */
|
||||
|
||||
square(&t, &z2_5_0) /* 2^6 - 2^1 */
|
||||
for i := 1; i < 5; i++ { /* 2^20 - 2^10 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&z2_10_0, &t, &z2_5_0) /* 2^10 - 2^0 */
|
||||
|
||||
square(&t, &z2_10_0) /* 2^11 - 2^1 */
|
||||
for i := 1; i < 10; i++ { /* 2^20 - 2^10 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&z2_20_0, &t, &z2_10_0) /* 2^20 - 2^0 */
|
||||
|
||||
square(&t, &z2_20_0) /* 2^21 - 2^1 */
|
||||
for i := 1; i < 20; i++ { /* 2^40 - 2^20 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&t, &t, &z2_20_0) /* 2^40 - 2^0 */
|
||||
|
||||
square(&t, &t) /* 2^41 - 2^1 */
|
||||
for i := 1; i < 10; i++ { /* 2^50 - 2^10 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&z2_50_0, &t, &z2_10_0) /* 2^50 - 2^0 */
|
||||
|
||||
square(&t, &z2_50_0) /* 2^51 - 2^1 */
|
||||
for i := 1; i < 50; i++ { /* 2^100 - 2^50 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&z2_100_0, &t, &z2_50_0) /* 2^100 - 2^0 */
|
||||
|
||||
square(&t, &z2_100_0) /* 2^101 - 2^1 */
|
||||
for i := 1; i < 100; i++ { /* 2^200 - 2^100 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&t, &t, &z2_100_0) /* 2^200 - 2^0 */
|
||||
|
||||
square(&t, &t) /* 2^201 - 2^1 */
|
||||
for i := 1; i < 50; i++ { /* 2^250 - 2^50 */
|
||||
square(&t, &t)
|
||||
}
|
||||
mul(&t, &t, &z2_50_0) /* 2^250 - 2^0 */
|
||||
|
||||
square(&t, &t) /* 2^251 - 2^1 */
|
||||
square(&t, &t) /* 2^252 - 2^2 */
|
||||
square(&t, &t) /* 2^253 - 2^3 */
|
||||
|
||||
square(&t, &t) /* 2^254 - 2^4 */
|
||||
|
||||
square(&t, &t) /* 2^255 - 2^5 */
|
||||
mul(r, &t, &z11) /* 2^255 - 21 */
|
||||
}
|
191
external/boringssl/ssl/test/runner/curve25519/mul_amd64.s
vendored
Normal file
191
external/boringssl/ssl/test/runner/curve25519/mul_amd64.s
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
// 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.
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
// func mul(dest, a, b *[5]uint64)
|
||||
TEXT ·mul(SB),0,$128-24
|
||||
MOVQ dest+0(FP), DI
|
||||
MOVQ a+8(FP), SI
|
||||
MOVQ b+16(FP), DX
|
||||
|
||||
MOVQ SP,R11
|
||||
MOVQ $31,CX
|
||||
NOTQ CX
|
||||
ANDQ CX,SP
|
||||
ADDQ $32,SP
|
||||
|
||||
MOVQ R11,0(SP)
|
||||
MOVQ R12,8(SP)
|
||||
MOVQ R13,16(SP)
|
||||
MOVQ R14,24(SP)
|
||||
MOVQ R15,32(SP)
|
||||
MOVQ BX,40(SP)
|
||||
MOVQ BP,48(SP)
|
||||
MOVQ DI,56(SP)
|
||||
MOVQ DX,CX
|
||||
MOVQ 24(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MOVQ AX,64(SP)
|
||||
MULQ 16(CX)
|
||||
MOVQ AX,R8
|
||||
MOVQ DX,R9
|
||||
MOVQ 32(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MOVQ AX,72(SP)
|
||||
MULQ 8(CX)
|
||||
ADDQ AX,R8
|
||||
ADCQ DX,R9
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 0(CX)
|
||||
ADDQ AX,R8
|
||||
ADCQ DX,R9
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 8(CX)
|
||||
MOVQ AX,R10
|
||||
MOVQ DX,R11
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 16(CX)
|
||||
MOVQ AX,R12
|
||||
MOVQ DX,R13
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 24(CX)
|
||||
MOVQ AX,R14
|
||||
MOVQ DX,R15
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 32(CX)
|
||||
MOVQ AX,BX
|
||||
MOVQ DX,BP
|
||||
MOVQ 8(SI),AX
|
||||
MULQ 0(CX)
|
||||
ADDQ AX,R10
|
||||
ADCQ DX,R11
|
||||
MOVQ 8(SI),AX
|
||||
MULQ 8(CX)
|
||||
ADDQ AX,R12
|
||||
ADCQ DX,R13
|
||||
MOVQ 8(SI),AX
|
||||
MULQ 16(CX)
|
||||
ADDQ AX,R14
|
||||
ADCQ DX,R15
|
||||
MOVQ 8(SI),AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX,BX
|
||||
ADCQ DX,BP
|
||||
MOVQ 8(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX,R8
|
||||
ADCQ DX,R9
|
||||
MOVQ 16(SI),AX
|
||||
MULQ 0(CX)
|
||||
ADDQ AX,R12
|
||||
ADCQ DX,R13
|
||||
MOVQ 16(SI),AX
|
||||
MULQ 8(CX)
|
||||
ADDQ AX,R14
|
||||
ADCQ DX,R15
|
||||
MOVQ 16(SI),AX
|
||||
MULQ 16(CX)
|
||||
ADDQ AX,BX
|
||||
ADCQ DX,BP
|
||||
MOVQ 16(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX,R8
|
||||
ADCQ DX,R9
|
||||
MOVQ 16(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX,R10
|
||||
ADCQ DX,R11
|
||||
MOVQ 24(SI),AX
|
||||
MULQ 0(CX)
|
||||
ADDQ AX,R14
|
||||
ADCQ DX,R15
|
||||
MOVQ 24(SI),AX
|
||||
MULQ 8(CX)
|
||||
ADDQ AX,BX
|
||||
ADCQ DX,BP
|
||||
MOVQ 64(SP),AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX,R10
|
||||
ADCQ DX,R11
|
||||
MOVQ 64(SP),AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX,R12
|
||||
ADCQ DX,R13
|
||||
MOVQ 32(SI),AX
|
||||
MULQ 0(CX)
|
||||
ADDQ AX,BX
|
||||
ADCQ DX,BP
|
||||
MOVQ 72(SP),AX
|
||||
MULQ 16(CX)
|
||||
ADDQ AX,R10
|
||||
ADCQ DX,R11
|
||||
MOVQ 72(SP),AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX,R12
|
||||
ADCQ DX,R13
|
||||
MOVQ 72(SP),AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX,R14
|
||||
ADCQ DX,R15
|
||||
MOVQ ·REDMASK51(SB),SI
|
||||
SHLQ $13,R9:R8
|
||||
ANDQ SI,R8
|
||||
SHLQ $13,R11:R10
|
||||
ANDQ SI,R10
|
||||
ADDQ R9,R10
|
||||
SHLQ $13,R13:R12
|
||||
ANDQ SI,R12
|
||||
ADDQ R11,R12
|
||||
SHLQ $13,R15:R14
|
||||
ANDQ SI,R14
|
||||
ADDQ R13,R14
|
||||
SHLQ $13,BP:BX
|
||||
ANDQ SI,BX
|
||||
ADDQ R15,BX
|
||||
IMUL3Q $19,BP,DX
|
||||
ADDQ DX,R8
|
||||
MOVQ R8,DX
|
||||
SHRQ $51,DX
|
||||
ADDQ R10,DX
|
||||
MOVQ DX,CX
|
||||
SHRQ $51,DX
|
||||
ANDQ SI,R8
|
||||
ADDQ R12,DX
|
||||
MOVQ DX,R9
|
||||
SHRQ $51,DX
|
||||
ANDQ SI,CX
|
||||
ADDQ R14,DX
|
||||
MOVQ DX,AX
|
||||
SHRQ $51,DX
|
||||
ANDQ SI,R9
|
||||
ADDQ BX,DX
|
||||
MOVQ DX,R10
|
||||
SHRQ $51,DX
|
||||
ANDQ SI,AX
|
||||
IMUL3Q $19,DX,DX
|
||||
ADDQ DX,R8
|
||||
ANDQ SI,R10
|
||||
MOVQ R8,0(DI)
|
||||
MOVQ CX,8(DI)
|
||||
MOVQ R9,16(DI)
|
||||
MOVQ AX,24(DI)
|
||||
MOVQ R10,32(DI)
|
||||
MOVQ 0(SP),R11
|
||||
MOVQ 8(SP),R12
|
||||
MOVQ 16(SP),R13
|
||||
MOVQ 24(SP),R14
|
||||
MOVQ 32(SP),R15
|
||||
MOVQ 40(SP),BX
|
||||
MOVQ 48(SP),BP
|
||||
MOVQ R11,SP
|
||||
MOVQ DI,AX
|
||||
MOVQ SI,DX
|
||||
RET
|
153
external/boringssl/ssl/test/runner/curve25519/square_amd64.s
vendored
Normal file
153
external/boringssl/ssl/test/runner/curve25519/square_amd64.s
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
// 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.
|
||||
|
||||
// This code was translated into a form compatible with 6a from the public
|
||||
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
// func square(out, in *[5]uint64)
|
||||
TEXT ·square(SB),7,$96-16
|
||||
MOVQ out+0(FP), DI
|
||||
MOVQ in+8(FP), SI
|
||||
|
||||
MOVQ SP,R11
|
||||
MOVQ $31,CX
|
||||
NOTQ CX
|
||||
ANDQ CX,SP
|
||||
ADDQ $32, SP
|
||||
|
||||
MOVQ R11,0(SP)
|
||||
MOVQ R12,8(SP)
|
||||
MOVQ R13,16(SP)
|
||||
MOVQ R14,24(SP)
|
||||
MOVQ R15,32(SP)
|
||||
MOVQ BX,40(SP)
|
||||
MOVQ BP,48(SP)
|
||||
MOVQ 0(SI),AX
|
||||
MULQ 0(SI)
|
||||
MOVQ AX,CX
|
||||
MOVQ DX,R8
|
||||
MOVQ 0(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 8(SI)
|
||||
MOVQ AX,R9
|
||||
MOVQ DX,R10
|
||||
MOVQ 0(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 16(SI)
|
||||
MOVQ AX,R11
|
||||
MOVQ DX,R12
|
||||
MOVQ 0(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 24(SI)
|
||||
MOVQ AX,R13
|
||||
MOVQ DX,R14
|
||||
MOVQ 0(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 32(SI)
|
||||
MOVQ AX,R15
|
||||
MOVQ DX,BX
|
||||
MOVQ 8(SI),AX
|
||||
MULQ 8(SI)
|
||||
ADDQ AX,R11
|
||||
ADCQ DX,R12
|
||||
MOVQ 8(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 16(SI)
|
||||
ADDQ AX,R13
|
||||
ADCQ DX,R14
|
||||
MOVQ 8(SI),AX
|
||||
SHLQ $1,AX
|
||||
MULQ 24(SI)
|
||||
ADDQ AX,R15
|
||||
ADCQ DX,BX
|
||||
MOVQ 8(SI),DX
|
||||
IMUL3Q $38,DX,AX
|
||||
MULQ 32(SI)
|
||||
ADDQ AX,CX
|
||||
ADCQ DX,R8
|
||||
MOVQ 16(SI),AX
|
||||
MULQ 16(SI)
|
||||
ADDQ AX,R15
|
||||
ADCQ DX,BX
|
||||
MOVQ 16(SI),DX
|
||||
IMUL3Q $38,DX,AX
|
||||
MULQ 24(SI)
|
||||
ADDQ AX,CX
|
||||
ADCQ DX,R8
|
||||
MOVQ 16(SI),DX
|
||||
IMUL3Q $38,DX,AX
|
||||
MULQ 32(SI)
|
||||
ADDQ AX,R9
|
||||
ADCQ DX,R10
|
||||
MOVQ 24(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MULQ 24(SI)
|
||||
ADDQ AX,R9
|
||||
ADCQ DX,R10
|
||||
MOVQ 24(SI),DX
|
||||
IMUL3Q $38,DX,AX
|
||||
MULQ 32(SI)
|
||||
ADDQ AX,R11
|
||||
ADCQ DX,R12
|
||||
MOVQ 32(SI),DX
|
||||
IMUL3Q $19,DX,AX
|
||||
MULQ 32(SI)
|
||||
ADDQ AX,R13
|
||||
ADCQ DX,R14
|
||||
MOVQ ·REDMASK51(SB),SI
|
||||
SHLQ $13,R8:CX
|
||||
ANDQ SI,CX
|
||||
SHLQ $13,R10:R9
|
||||
ANDQ SI,R9
|
||||
ADDQ R8,R9
|
||||
SHLQ $13,R12:R11
|
||||
ANDQ SI,R11
|
||||
ADDQ R10,R11
|
||||
SHLQ $13,R14:R13
|
||||
ANDQ SI,R13
|
||||
ADDQ R12,R13
|
||||
SHLQ $13,BX:R15
|
||||
ANDQ SI,R15
|
||||
ADDQ R14,R15
|
||||
IMUL3Q $19,BX,DX
|
||||
ADDQ DX,CX
|
||||
MOVQ CX,DX
|
||||
SHRQ $51,DX
|
||||
ADDQ R9,DX
|
||||
ANDQ SI,CX
|
||||
MOVQ DX,R8
|
||||
SHRQ $51,DX
|
||||
ADDQ R11,DX
|
||||
ANDQ SI,R8
|
||||
MOVQ DX,R9
|
||||
SHRQ $51,DX
|
||||
ADDQ R13,DX
|
||||
ANDQ SI,R9
|
||||
MOVQ DX,AX
|
||||
SHRQ $51,DX
|
||||
ADDQ R15,DX
|
||||
ANDQ SI,AX
|
||||
MOVQ DX,R10
|
||||
SHRQ $51,DX
|
||||
IMUL3Q $19,DX,DX
|
||||
ADDQ DX,CX
|
||||
ANDQ SI,R10
|
||||
MOVQ CX,0(DI)
|
||||
MOVQ R8,8(DI)
|
||||
MOVQ R9,16(DI)
|
||||
MOVQ AX,24(DI)
|
||||
MOVQ R10,32(DI)
|
||||
MOVQ 0(SP),R11
|
||||
MOVQ 8(SP),R12
|
||||
MOVQ 16(SP),R13
|
||||
MOVQ 24(SP),R14
|
||||
MOVQ 32(SP),R15
|
||||
MOVQ 40(SP),BX
|
||||
MOVQ 48(SP),BP
|
||||
MOVQ R11,SP
|
||||
MOVQ DI,AX
|
||||
MOVQ SI,DX
|
||||
RET
|
37
external/boringssl/ssl/test/runner/deterministic.go
vendored
Normal file
37
external/boringssl/ssl/test/runner/deterministic.go
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2016, Google Inc.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
package runner
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// Use a different key from crypto/rand/deterministic.c.
|
||||
var deterministicRandKey = []byte("runner deterministic key 0123456")
|
||||
|
||||
type deterministicRand struct {
|
||||
numCalls uint64
|
||||
}
|
||||
|
||||
func (d *deterministicRand) Read(buf []byte) (int, error) {
|
||||
for i := range buf {
|
||||
buf[i] = 0
|
||||
}
|
||||
var nonce [12]byte
|
||||
binary.LittleEndian.PutUint64(nonce[:8], d.numCalls)
|
||||
chaCha20(buf, buf, deterministicRandKey, nonce[:], 0)
|
||||
d.numCalls++
|
||||
return len(buf), nil
|
||||
}
|
446
external/boringssl/ssl/test/runner/dtls.go
vendored
Normal file
446
external/boringssl/ssl/test/runner/dtls.go
vendored
Normal file
@@ -0,0 +1,446 @@
|
||||
// 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.
|
||||
|
||||
// DTLS implementation.
|
||||
//
|
||||
// NOTE: This is a not even a remotely production-quality DTLS
|
||||
// implementation. It is the bare minimum necessary to be able to
|
||||
// achieve coverage on BoringSSL's implementation. Of note is that
|
||||
// this implementation assumes the underlying net.PacketConn is not
|
||||
// only reliable but also ordered. BoringSSL will be expected to deal
|
||||
// with simulated loss, but there is no point in forcing the test
|
||||
// driver to.
|
||||
|
||||
package runner
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"net"
|
||||
)
|
||||
|
||||
func versionToWire(vers uint16, isDTLS bool) uint16 {
|
||||
if isDTLS {
|
||||
return ^(vers - 0x0201)
|
||||
}
|
||||
return vers
|
||||
}
|
||||
|
||||
func wireToVersion(vers uint16, isDTLS bool) uint16 {
|
||||
if isDTLS {
|
||||
return ^vers + 0x0201
|
||||
}
|
||||
return vers
|
||||
}
|
||||
|
||||
func (c *Conn) dtlsDoReadRecord(want recordType) (recordType, *block, error) {
|
||||
recordHeaderLen := dtlsRecordHeaderLen
|
||||
|
||||
if c.rawInput == nil {
|
||||
c.rawInput = c.in.newBlock()
|
||||
}
|
||||
b := c.rawInput
|
||||
|
||||
// Read a new packet only if the current one is empty.
|
||||
var newPacket bool
|
||||
if len(b.data) == 0 {
|
||||
// Pick some absurdly large buffer size.
|
||||
b.resize(maxCiphertext + recordHeaderLen)
|
||||
n, err := c.conn.Read(c.rawInput.data)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
if c.config.Bugs.MaxPacketLength != 0 && n > c.config.Bugs.MaxPacketLength {
|
||||
return 0, nil, fmt.Errorf("dtls: exceeded maximum packet length")
|
||||
}
|
||||
c.rawInput.resize(n)
|
||||
newPacket = true
|
||||
}
|
||||
|
||||
// Read out one record.
|
||||
//
|
||||
// A real DTLS implementation should be tolerant of errors,
|
||||
// but this is test code. We should not be tolerant of our
|
||||
// peer sending garbage.
|
||||
if len(b.data) < recordHeaderLen {
|
||||
return 0, nil, errors.New("dtls: failed to read record header")
|
||||
}
|
||||
typ := recordType(b.data[0])
|
||||
vers := wireToVersion(uint16(b.data[1])<<8|uint16(b.data[2]), c.isDTLS)
|
||||
if c.haveVers {
|
||||
if vers != c.vers {
|
||||
c.sendAlert(alertProtocolVersion)
|
||||
return 0, nil, c.in.setErrorLocked(fmt.Errorf("dtls: received record with version %x when expecting version %x", vers, c.vers))
|
||||
}
|
||||
} else {
|
||||
if expect := c.config.Bugs.ExpectInitialRecordVersion; expect != 0 && vers != expect {
|
||||
c.sendAlert(alertProtocolVersion)
|
||||
return 0, nil, c.in.setErrorLocked(fmt.Errorf("dtls: received record with version %x when expecting version %x", vers, expect))
|
||||
}
|
||||
}
|
||||
epoch := b.data[3:5]
|
||||
seq := b.data[5:11]
|
||||
// For test purposes, require the sequence number be monotonically
|
||||
// increasing, so c.in includes the minimum next sequence number. Gaps
|
||||
// may occur if packets failed to be sent out. A real implementation
|
||||
// would maintain a replay window and such.
|
||||
if !bytes.Equal(epoch, c.in.seq[:2]) {
|
||||
c.sendAlert(alertIllegalParameter)
|
||||
return 0, nil, c.in.setErrorLocked(fmt.Errorf("dtls: bad epoch"))
|
||||
}
|
||||
if bytes.Compare(seq, c.in.seq[2:]) < 0 {
|
||||
c.sendAlert(alertIllegalParameter)
|
||||
return 0, nil, c.in.setErrorLocked(fmt.Errorf("dtls: bad sequence number"))
|
||||
}
|
||||
copy(c.in.seq[2:], seq)
|
||||
n := int(b.data[11])<<8 | int(b.data[12])
|
||||
if n > maxCiphertext || len(b.data) < recordHeaderLen+n {
|
||||
c.sendAlert(alertRecordOverflow)
|
||||
return 0, nil, c.in.setErrorLocked(fmt.Errorf("dtls: oversized record received with length %d", n))
|
||||
}
|
||||
|
||||
// Process message.
|
||||
b, c.rawInput = c.in.splitBlock(b, recordHeaderLen+n)
|
||||
ok, off, err := c.in.decrypt(b)
|
||||
if !ok {
|
||||
c.in.setErrorLocked(c.sendAlert(err))
|
||||
}
|
||||
b.off = off
|
||||
|
||||
// Require that ChangeCipherSpec always share a packet with either the
|
||||
// previous or next handshake message.
|
||||
if newPacket && typ == recordTypeChangeCipherSpec && c.rawInput == nil {
|
||||
return 0, nil, c.in.setErrorLocked(fmt.Errorf("dtls: ChangeCipherSpec not packed together with Finished"))
|
||||
}
|
||||
|
||||
return typ, b, nil
|
||||
}
|
||||
|
||||
func (c *Conn) makeFragment(header, data []byte, fragOffset, fragLen int) []byte {
|
||||
fragment := make([]byte, 0, 12+fragLen)
|
||||
fragment = append(fragment, header...)
|
||||
fragment = append(fragment, byte(c.sendHandshakeSeq>>8), byte(c.sendHandshakeSeq))
|
||||
fragment = append(fragment, byte(fragOffset>>16), byte(fragOffset>>8), byte(fragOffset))
|
||||
fragment = append(fragment, byte(fragLen>>16), byte(fragLen>>8), byte(fragLen))
|
||||
fragment = append(fragment, data[fragOffset:fragOffset+fragLen]...)
|
||||
return fragment
|
||||
}
|
||||
|
||||
func (c *Conn) dtlsWriteRecord(typ recordType, data []byte) (n int, err error) {
|
||||
if typ != recordTypeHandshake {
|
||||
// Only handshake messages are fragmented.
|
||||
return c.dtlsWriteRawRecord(typ, data)
|
||||
}
|
||||
|
||||
maxLen := c.config.Bugs.MaxHandshakeRecordLength
|
||||
if maxLen <= 0 {
|
||||
maxLen = 1024
|
||||
}
|
||||
|
||||
// Handshake messages have to be modified to include fragment
|
||||
// offset and length and with the header replicated. Save the
|
||||
// TLS header here.
|
||||
//
|
||||
// TODO(davidben): This assumes that data contains exactly one
|
||||
// handshake message. This is incompatible with
|
||||
// FragmentAcrossChangeCipherSpec. (Which is unfortunate
|
||||
// because OpenSSL's DTLS implementation will probably accept
|
||||
// such fragmentation and could do with a fix + tests.)
|
||||
header := data[:4]
|
||||
data = data[4:]
|
||||
|
||||
isFinished := header[0] == typeFinished
|
||||
|
||||
if c.config.Bugs.SendEmptyFragments {
|
||||
fragment := c.makeFragment(header, data, 0, 0)
|
||||
c.pendingFragments = append(c.pendingFragments, fragment)
|
||||
}
|
||||
|
||||
firstRun := true
|
||||
fragOffset := 0
|
||||
for firstRun || fragOffset < len(data) {
|
||||
firstRun = false
|
||||
fragLen := len(data) - fragOffset
|
||||
if fragLen > maxLen {
|
||||
fragLen = maxLen
|
||||
}
|
||||
|
||||
fragment := c.makeFragment(header, data, fragOffset, fragLen)
|
||||
if c.config.Bugs.FragmentMessageTypeMismatch && fragOffset > 0 {
|
||||
fragment[0]++
|
||||
}
|
||||
if c.config.Bugs.FragmentMessageLengthMismatch && fragOffset > 0 {
|
||||
fragment[3]++
|
||||
}
|
||||
|
||||
// Buffer the fragment for later. They will be sent (and
|
||||
// reordered) on flush.
|
||||
c.pendingFragments = append(c.pendingFragments, fragment)
|
||||
if c.config.Bugs.ReorderHandshakeFragments {
|
||||
// Don't duplicate Finished to avoid the peer
|
||||
// interpreting it as a retransmit request.
|
||||
if !isFinished {
|
||||
c.pendingFragments = append(c.pendingFragments, fragment)
|
||||
}
|
||||
|
||||
if fragLen > (maxLen+1)/2 {
|
||||
// Overlap each fragment by half.
|
||||
fragLen = (maxLen + 1) / 2
|
||||
}
|
||||
}
|
||||
fragOffset += fragLen
|
||||
n += fragLen
|
||||
}
|
||||
if !isFinished && c.config.Bugs.MixCompleteMessageWithFragments {
|
||||
fragment := c.makeFragment(header, data, 0, len(data))
|
||||
c.pendingFragments = append(c.pendingFragments, fragment)
|
||||
}
|
||||
|
||||
// Increment the handshake sequence number for the next
|
||||
// handshake message.
|
||||
c.sendHandshakeSeq++
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Conn) dtlsFlushHandshake() error {
|
||||
if !c.isDTLS {
|
||||
return nil
|
||||
}
|
||||
|
||||
// This is a test-only DTLS implementation, so there is no need to
|
||||
// retain |c.pendingFragments| for a future retransmit.
|
||||
var fragments [][]byte
|
||||
fragments, c.pendingFragments = c.pendingFragments, fragments
|
||||
|
||||
if c.config.Bugs.ReorderHandshakeFragments {
|
||||
perm := rand.New(rand.NewSource(0)).Perm(len(fragments))
|
||||
tmp := make([][]byte, len(fragments))
|
||||
for i := range tmp {
|
||||
tmp[i] = fragments[perm[i]]
|
||||
}
|
||||
fragments = tmp
|
||||
}
|
||||
|
||||
maxRecordLen := c.config.Bugs.PackHandshakeFragments
|
||||
maxPacketLen := c.config.Bugs.PackHandshakeRecords
|
||||
|
||||
// Pack handshake fragments into records.
|
||||
var records [][]byte
|
||||
for _, fragment := range fragments {
|
||||
if n := c.config.Bugs.SplitFragments; n > 0 {
|
||||
if len(fragment) > n {
|
||||
records = append(records, fragment[:n])
|
||||
records = append(records, fragment[n:])
|
||||
} else {
|
||||
records = append(records, fragment)
|
||||
}
|
||||
} else if i := len(records) - 1; len(records) > 0 && len(records[i])+len(fragment) <= maxRecordLen {
|
||||
records[i] = append(records[i], fragment...)
|
||||
} else {
|
||||
// The fragment will be appended to, so copy it.
|
||||
records = append(records, append([]byte{}, fragment...))
|
||||
}
|
||||
}
|
||||
|
||||
// Format them into packets.
|
||||
var packets [][]byte
|
||||
for _, record := range records {
|
||||
b, err := c.dtlsSealRecord(recordTypeHandshake, record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if i := len(packets) - 1; len(packets) > 0 && len(packets[i])+len(b.data) <= maxPacketLen {
|
||||
packets[i] = append(packets[i], b.data...)
|
||||
} else {
|
||||
// The sealed record will be appended to and reused by
|
||||
// |c.out|, so copy it.
|
||||
packets = append(packets, append([]byte{}, b.data...))
|
||||
}
|
||||
c.out.freeBlock(b)
|
||||
}
|
||||
|
||||
// Send all the packets.
|
||||
for _, packet := range packets {
|
||||
if _, err := c.conn.Write(packet); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// dtlsSealRecord seals a record into a block from |c.out|'s pool.
|
||||
func (c *Conn) dtlsSealRecord(typ recordType, data []byte) (b *block, err error) {
|
||||
recordHeaderLen := dtlsRecordHeaderLen
|
||||
maxLen := c.config.Bugs.MaxHandshakeRecordLength
|
||||
if maxLen <= 0 {
|
||||
maxLen = 1024
|
||||
}
|
||||
|
||||
b = c.out.newBlock()
|
||||
|
||||
explicitIVLen := 0
|
||||
explicitIVIsSeq := false
|
||||
|
||||
if cbc, ok := c.out.cipher.(cbcMode); ok {
|
||||
// Block cipher modes have an explicit IV.
|
||||
explicitIVLen = cbc.BlockSize()
|
||||
} else if aead, ok := c.out.cipher.(*tlsAead); ok {
|
||||
if aead.explicitNonce {
|
||||
explicitIVLen = 8
|
||||
// The AES-GCM construction in TLS has an explicit nonce so that
|
||||
// the nonce can be random. However, the nonce is only 8 bytes
|
||||
// which is too small for a secure, random nonce. Therefore we
|
||||
// use the sequence number as the nonce.
|
||||
explicitIVIsSeq = true
|
||||
}
|
||||
} else if c.out.cipher != nil {
|
||||
panic("Unknown cipher")
|
||||
}
|
||||
b.resize(recordHeaderLen + explicitIVLen + len(data))
|
||||
b.data[0] = byte(typ)
|
||||
vers := c.vers
|
||||
if vers == 0 {
|
||||
// Some TLS servers fail if the record version is greater than
|
||||
// TLS 1.0 for the initial ClientHello.
|
||||
vers = VersionTLS10
|
||||
}
|
||||
vers = versionToWire(vers, c.isDTLS)
|
||||
b.data[1] = byte(vers >> 8)
|
||||
b.data[2] = byte(vers)
|
||||
// DTLS records include an explicit sequence number.
|
||||
copy(b.data[3:11], c.out.outSeq[0:])
|
||||
b.data[11] = byte(len(data) >> 8)
|
||||
b.data[12] = byte(len(data))
|
||||
if explicitIVLen > 0 {
|
||||
explicitIV := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
|
||||
if explicitIVIsSeq {
|
||||
copy(explicitIV, c.out.outSeq[:])
|
||||
} else {
|
||||
if _, err = io.ReadFull(c.config.rand(), explicitIV); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
copy(b.data[recordHeaderLen+explicitIVLen:], data)
|
||||
c.out.encrypt(b, explicitIVLen)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Conn) dtlsWriteRawRecord(typ recordType, data []byte) (n int, err error) {
|
||||
b, err := c.dtlsSealRecord(typ, data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = c.conn.Write(b.data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
n = len(data)
|
||||
|
||||
c.out.freeBlock(b)
|
||||
|
||||
if typ == recordTypeChangeCipherSpec {
|
||||
err = c.out.changeCipherSpec(c.config)
|
||||
if err != nil {
|
||||
// Cannot call sendAlert directly,
|
||||
// because we already hold c.out.Mutex.
|
||||
c.tmp[0] = alertLevelError
|
||||
c.tmp[1] = byte(err.(alert))
|
||||
c.writeRecord(recordTypeAlert, c.tmp[0:2])
|
||||
return n, c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Conn) dtlsDoReadHandshake() ([]byte, error) {
|
||||
// Assemble a full handshake message. For test purposes, this
|
||||
// implementation assumes fragments arrive in order. It may
|
||||
// need to be cleverer if we ever test BoringSSL's retransmit
|
||||
// behavior.
|
||||
for len(c.handMsg) < 4+c.handMsgLen {
|
||||
// Get a new handshake record if the previous has been
|
||||
// exhausted.
|
||||
if c.hand.Len() == 0 {
|
||||
if err := c.in.err; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.readRecord(recordTypeHandshake); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Read the next fragment. It must fit entirely within
|
||||
// the record.
|
||||
if c.hand.Len() < 12 {
|
||||
return nil, errors.New("dtls: bad handshake record")
|
||||
}
|
||||
header := c.hand.Next(12)
|
||||
fragN := int(header[1])<<16 | int(header[2])<<8 | int(header[3])
|
||||
fragSeq := uint16(header[4])<<8 | uint16(header[5])
|
||||
fragOff := int(header[6])<<16 | int(header[7])<<8 | int(header[8])
|
||||
fragLen := int(header[9])<<16 | int(header[10])<<8 | int(header[11])
|
||||
|
||||
if c.hand.Len() < fragLen {
|
||||
return nil, errors.New("dtls: fragment length too long")
|
||||
}
|
||||
fragment := c.hand.Next(fragLen)
|
||||
|
||||
// Check it's a fragment for the right message.
|
||||
if fragSeq != c.recvHandshakeSeq {
|
||||
return nil, errors.New("dtls: bad handshake sequence number")
|
||||
}
|
||||
|
||||
// Check that the length is consistent.
|
||||
if c.handMsg == nil {
|
||||
c.handMsgLen = fragN
|
||||
if c.handMsgLen > maxHandshake {
|
||||
return nil, c.in.setErrorLocked(c.sendAlert(alertInternalError))
|
||||
}
|
||||
// Start with the TLS handshake header,
|
||||
// without the DTLS bits.
|
||||
c.handMsg = append([]byte{}, header[:4]...)
|
||||
} else if fragN != c.handMsgLen {
|
||||
return nil, errors.New("dtls: bad handshake length")
|
||||
}
|
||||
|
||||
// Add the fragment to the pending message.
|
||||
if 4+fragOff != len(c.handMsg) {
|
||||
return nil, errors.New("dtls: bad fragment offset")
|
||||
}
|
||||
if fragOff+fragLen > c.handMsgLen {
|
||||
return nil, errors.New("dtls: bad fragment length")
|
||||
}
|
||||
c.handMsg = append(c.handMsg, fragment...)
|
||||
}
|
||||
c.recvHandshakeSeq++
|
||||
ret := c.handMsg
|
||||
c.handMsg, c.handMsgLen = nil, 0
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// DTLSServer returns a new DTLS server side connection
|
||||
// using conn as the underlying transport.
|
||||
// The configuration config must be non-nil and must have
|
||||
// at least one certificate.
|
||||
func DTLSServer(conn net.Conn, config *Config) *Conn {
|
||||
c := &Conn{config: config, isDTLS: true, conn: conn}
|
||||
c.init()
|
||||
return c
|
||||
}
|
||||
|
||||
// DTLSClient returns a new DTLS client side connection
|
||||
// using conn as the underlying transport.
|
||||
// The config cannot be nil: users must set either ServerHostname or
|
||||
// InsecureSkipVerify in the config.
|
||||
func DTLSClient(conn net.Conn, config *Config) *Conn {
|
||||
c := &Conn{config: config, isClient: true, isDTLS: true, conn: conn}
|
||||
c.init()
|
||||
return c
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user