diff options
| -rw-r--r-- | talpid-tunnel-config-client/proto/tunnel_config.proto | 91 |
1 files changed, 79 insertions, 12 deletions
diff --git a/talpid-tunnel-config-client/proto/tunnel_config.proto b/talpid-tunnel-config-client/proto/tunnel_config.proto index 9ce4232d0d..215aa941c8 100644 --- a/talpid-tunnel-config-client/proto/tunnel_config.proto +++ b/talpid-tunnel-config-client/proto/tunnel_config.proto @@ -1,15 +1,3 @@ -// -// If you need to (re)generate the gRPC code, see prerequisites -// -// https://grpc.io/docs/languages/go/quickstart/ -// -// and then run -// -// protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative tunnel_config.proto -// -// from this directory. -// - syntax = "proto3"; option go_package = "github.com/mullvad/wg-manager/server/tuncfg"; @@ -19,7 +7,71 @@ package tunnel_config; service PostQuantumSecure { // PskExchangeExperimentalV0 uses the common API defined by LibOQS. See: // https://github.com/open-quantum-safe/liboqs + // This endpoint is deprecated in favor for `PskExchangeExperimentalV1`. Please use that instead. rpc PskExchangeExperimentalV0(PskRequestExperimentalV0) returns (PskResponseExperimentalV0) {} + + // Allows deriving a preshared key (PSK) using one or multiple PQ-secure key-encapsulation + // mechanisms (KEM). The preshared key is added to WireGuard's preshared-key field in a new + // ephemeral peer (PQ-peer). This makes the tunnel resistant towards attacks using + // quantum computers. + // + // The VPN server associates the PQ-peer with the peer who performed the exchange. Any + // already existing PQ-peer for the normal peer is replaced. Each normal peer can have + // at most one PQ-peer. + // + // The PQ-peer is mutually exclusive to the normal peer. The server keeps both peers in memory, + // but only one of them is loaded into WireGuard at any point in time. A handshake from the + // normal peer unloads the corresponding PQ-peer from WireGuard and vice versa. + // + // A new peer is negotiated for PQ to avoid a premature break of the tunnel used for negotiation. + // A tunnel would break prematurely if the preshared key is applied before the normal peer + // received the server's contribution to the KEM exchange. This cannot occur now because + // the client decides when to switch to the PQ-secure tunnel. This design also allows + // the client to switch back to using a non-PQ-secure tunnel at any point. + // + // The negotiated PQ-peer is ephemeral. The server gives no guarantees how long it will be + // valid and working. The client should negotiate a new PQ-peer every time it establishes a new + // tunnel to the server. + // + // The full exchange requires just a single request-response round trip between the VPN client + // and the VPN server. + // + // # Request-response format + // + // The request from the VPN client contains: + // * `wg_pubkey` - The public key used by the current tunnel (that the request travels inside). + // * `wg_psk_pubkey` - A newly generated ephemeral WireGuard public key for the PQ-peer. + // The server will associate the derived PSK with this public key. + // * `kem_pubkeys` - A list describing the KEM algorithms. Must have at least one entry. + // The same KEM must not be listed more than once. Each list item contains: + // * `algorithm_name` - The name of the KEM, including which variant. Should be the same + // name/format that `liboqs` uses. + // * `key_data` - The client's public key for this KEM. Will be used by the server to + // encapsulate the shared secret for this KEM. + // + // The response from the VPN server contains: + // * `ciphertexts` - A list of the ciphertexts (the encapsulated shared secrets) for all + // public keys in `kem_pubkeys` in the request, in the same order as in the request. + // + // # Deriving the WireGuard PSK + // + // The PSK to be used in WireGuard's preshared-key field is computed by XORing the resulting + // shared secrets of all the KEM algorithms. All currently supported and planned to be + // supported algorithms output 32 bytes, so this is trivial. + // + // Since the PSK provided to WireGuard is directly fed into a HKDF, it is not important that + // the entropy in the PSK is uniformly distributed. The actual keys used for encrypting the + // data channel will have uniformly distributed entropy anyway, thanks to the HKDF. + // But even if that was not true, since both CME and Kyber run SHAKE256 as the last step + // of their internal key derivation, the output they produce are uniformly distributed. + // + // If we later want to support another type of KEM that produce longer or shorter output, + // we can hash that secret into a 32 byte hash before proceeding to the XOR step. + // + // Mixing with XOR (A = B ^ C) is fine since nothing about A is revealed even if one of B or C + // is known. Both B *and* C must be known to compute any bit in A. This means all involved + // KEM algorithms must be broken before the PSK can be computed by an attacker. + rpc PskExchangeExperimentalV1(PskRequestExperimentalV1) returns (PskResponseExperimentalV1) {} } message PskRequestExperimentalV0 { @@ -36,3 +88,18 @@ message KemPubkeyExperimentalV0 { message PskResponseExperimentalV0 { bytes ciphertext = 1; } + +message PskRequestExperimentalV1 { + bytes wg_pubkey = 1; + bytes wg_psk_pubkey = 2; + repeated KemPubkeyExperimentalV1 kem_pubkeys = 3; +} + +message KemPubkeyExperimentalV1 { + string algorithm_name = 1; + bytes key_data = 2; +} + +message PskResponseExperimentalV1 { + repeated bytes ciphertexts = 1; +} |
