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
tree: 6762b547162858e9ab36ba16d0976bc3d41d017d
  1. lib/
  2. profiles/
  3. runtimes/
  4. security/
  5. services/
  6. tools/