veyron/runtimes/google/ipc/stream: Implement control-channel encryption.
For VIFs, perform versioning, authentication, and encrypt the control
data (VC data is already encrypted).
In this implementation, authentication/encryption is initiated by the
client.
- The VIF starts off using the standard unencrypted protocol.
- The client calculates the expected IPC version by intersecting
its own supported version range with the server's range that
is published via the endpoint. If the version suports
encryption, the client immediately begins negotiating
with the server.
Negotiation is performed using Encrypt control messages to set up a
bidirectional flow between the client and server. This is like a VC,
but it is hop-by-hop, instead of end-to-end.
- Each party sends its acceptable verson ranges together with
public data for initiating encryption. There is only one
supported encryption scheme now, but the options should
eventually include data for each of the encryption protocols
the party is willing to support.
- Currently the only encryption protocol is based on
code.google.com/p/go.crypto/nacl/box,
which uses Curve25519, XSalsa20 and Poly1305 to encrypt and
authenticate messages. The parties exchange public keys
to create a box cipher.
- Perform the standard Veyron handshake using the cipher for
encryption.
- On success, use the cipher to encrypt the control data.
RULES:
- VIF message formats never change, except in compatible ways.
New developments can only change the VIF protocol by adding
more message types.
- The format of the public data header in the Encrypt
negotiation never changes for all time.
A VIF frame has two parts, a (Type + PayloadSize) header word, and
some payload. The Type+PayloadSize is encrypted with the cipher's
XORKeyStream. The rest of the control data is encrypted with the
cipher's Seal method. This means that none of the data is observable
by an adversary, but the type and length are subject to corruption
(the rest of the data is not). This doesn't matter -- if the Type
or PayloadSize is corrupted by an adversary, the payload will be
misread, and will fail to validate.
We could potentially pass the Type and PayloadSize in the clear,
but then the framing would be observable, a (probably minor)
information leak. There is no reason to do so, we encrypt everything.
TIMES:
$ veyron go test veyron.io/veyron/veyron/runtimes/google/ipc/stream/benchmark -bench=Flow -run=X
Before:
BenchmarkFlow_1VIF_1VC_1Flow 50000 45029 ns/op 1137.02 MB/s
BenchmarkFlow_1VIF_1VC_2Flow 50000 39475 ns/op 1296.99 MB/s
BenchmarkFlow_1VIF_1VC_8Flow 50000 42355 ns/op 1208.82 MB/s
BenchmarkFlow_1VIF_2VC_2Flow 50000 40518 ns/op 1263.62 MB/s
BenchmarkFlow_1VIF_2VC_8Flow 50000 42861 ns/op 1194.55 MB/s
BenchmarkFlow_2VIF_4VC_8Flow 50000 43486 ns/op 1177.38 MB/s
BenchmarkFlow_1VIF_1VC_1FlowTLS 5000 521504 ns/op 98.18 MB/s
BenchmarkFlow_1VIF_1VC_2FlowTLS 5000 503743 ns/op 101.64 MB/s
BenchmarkFlow_1VIF_1VC_8FlowTLS 5000 508953 ns/op 100.60 MB/s
BenchmarkFlow_1VIF_2VC_2FlowTLS 5000 503255 ns/op 101.74 MB/s
BenchmarkFlow_1VIF_2VC_8FlowTLS 5000 510379 ns/op 100.32 MB/s
BenchmarkFlow_2VIF_4VC_8FlowTLS 5000 511113 ns/op 100.17 MB/s
ok veyron.io/veyron/veyron/runtimes/google/ipc/stream/benchmark 32.253s
After:
BenchmarkFlow_1VIF_1VC_1Flow 50000 43946 ns/op 1165.05 MB/s
BenchmarkFlow_1VIF_1VC_2Flow 50000 39394 ns/op 1299.67 MB/s
BenchmarkFlow_1VIF_1VC_8Flow 50000 43537 ns/op 1175.98 MB/s
BenchmarkFlow_1VIF_2VC_2Flow 50000 39945 ns/op 1281.74 MB/s
BenchmarkFlow_1VIF_2VC_8Flow 50000 41531 ns/op 1232.80 MB/s
BenchmarkFlow_2VIF_4VC_8Flow 50000 43568 ns/op 1175.17 MB/s
BenchmarkFlow_1VIF_1VC_1FlowTLS 5000 538491 ns/op 95.08 MB/s
BenchmarkFlow_1VIF_1VC_2FlowTLS 5000 522869 ns/op 97.92 MB/s
BenchmarkFlow_1VIF_1VC_8FlowTLS 5000 526982 ns/op 97.16 MB/s
BenchmarkFlow_1VIF_2VC_2FlowTLS 5000 522381 ns/op 98.01 MB/s
BenchmarkFlow_1VIF_2VC_8FlowTLS 5000 528707 ns/op 96.84 MB/s
BenchmarkFlow_2VIF_4VC_8FlowTLS 5000 530732 ns/op 96.47 MB/s
ok veyron.io/veyron/veyron/runtimes/google/ipc/stream/benchmark 33.302s
Change-Id: I3fcb0346dd23f77d549744fe061695a2dd606215
22 files changed