Re: [Openvpn-devel] OpenVPN protocol extensions update
On 07-01-15 01:08, James Yonan wrote: I've updated the OpenVPN protocol extension doc with additional details, now that more of these features have been implemented in OpenVPN 3. If you are implementing any of these features in OpenVPN 2.x, please review so we can ensure that OpenVPN 2.x and 3 are on the same page with respect to protocol extensions. Sorry for being this slow to publicly respond. There has been some discussion off-list, but I'd like to publicly mention my comments on the AEAD and NCP parts too. >AEAD Nonce: > > [ Packet ID ] [ HMAC keying material ] > [ 4 bytes ] [ 8 bytes ] > [ AEAD nonce total: 12 bytes ] > >TLS wire protocol: > > [ DATA_V2 opcode ] [ Packet ID ] [ AEAD Auth tag ] [ ciphertext ] > [ 4 bytes] [ 4 bytes ] [ 16 bytes ] > [ AEAD additional data (AD)] Agreed. I would have preferred to put the AEAD auth tag at the end of the packet (since that would put the additional data and ciphertext right next to each other), but this works for me too. >Static Key wire protocol: > > [ DATA_V2 opcode ] [ Packet ID ] [ Nonce tail (random) ] [ AEAD Auth tag ] [ ciphertext ] > [ AEAD nonce ] > [ 4 bytes] [ 8 bytes ] [ 4 bytes ] [ 16 bytes ] > [ AEAD additional data (AD)] I think we should not support GCM in static key mode. Reusing a nonce/key combination in GCM very bad, and guaranteeing that will never happen is tricky for static key mode. Particularly on constrained devices (where using static key mode makes sense), proper time for the packet ID might not be available, and random might be bad. Even if there is proper random, the birthday bound for the 32-bit nonce tail is only 2^16 (65536) packets. Iirc, we agreed to not support GCM is static key mode before off-list, but I wanted to publicly mention this. >When negotiating AEAD mode, the client indicates its support >of AES-128-GCM, AES-192-GCM, and AES-192-GCM by including: > > IV_NCP=2 > >in the peer info string (NCP stands for Negotiable Crypto >Parameters). > >When the IV_NCP value is 2 or higher, it indicates that >the server may push an AEAD "cipher" directive, e.g.: > > push "cipher AES-128-GCM" We can use this as an upgrade path to GCM, but I think we will need to come up with a more elaborate negotiation mechanism at some point. For now, some review comments about NCP=2: * Will there be a configuration option to enable/disable NCP? As a client or server, I might not want any dynamic behaviour, but instead be in full control. How about a '--ncp', which a user can set to the ncp version to use, or '0' to disable NCP. * How does a server choose the cipher? Here too, I think we need a configuration directive. We could merge it with the '--ncp' above, where any arguments after the version are interpreted based on the NCP version. E.g. '--ncp 2 AES-128-GCM' would result in the server pushing AES-128-GCM if the client indicates support for NCP=2. * This mechanism gives a client little to say about the cipher. It would be nice if a client could somehow enforce e.g. AES-256-GCM instead of AES-128-GCM. >In the future, the IV_NCP value (2 in the current >implementation) may be increased to indicate the >availability of additional negotiable ciphers. Next to the ability to add negotiable ciphers, we should think about how to restrict the offered ciphers in the future. -Steffan
Re: [Openvpn-devel] OpenVPN protocol extensions update
On 09/01/2015 02:41, Lev Stipakov wrote: Hi James, A few comments on peer-id part: * A disabled peer ID is denoted by 0xFF. * Server tells the client to use DATA_V2/peer_id by pushing the directive "peer-id ID" where ID is a decimal integer in the range [-1, 16777215]. Setting the peer ID to -1 transmits DATA_V2 packets with the peer ID field set to 0xFF. Setting the peer_id to -1 is the same as setting it to 16777215 (i.e. 0xFF). There is no such thing as "disabled peer-id" in current implementation, server does not send "-1" and client does not send 0xFF. I can surely do it, if needed. Could you maybe explain its meaning? I see DATA_V2 as playing multiple roles, e.g. aside from its intended use of client float, it also improves packet alignment. So conceivably, a connection might want to use DATA_V2 for alignment, but not need the peer-id/float capability. Another thing I've observed about protocol changes in the past, is that once a protocol change reaches maturity after many years, where almost every OpenVPN client/server universally supports it, you can safely deprecate the old protocol variant (case in point: CONTROL_HARD_RESET_(CLIENT|SERVER)_V1 which has been been completely supplanted by V2). So eventually we may want to deprecate DATA_V1, but we can't do that unless DATA_V2 is flexible enough to replace it. And being able to use DATA_V2 without peer-id/float would give it the flexibility to be used as a drop-in replacement for DATA_V1 in cases where peer-id/float is not wanted or needed. And just to make sure - if server gets DATA_V2 with peer-id -1, it should skip peer-id bytes and treat it as data_v1, correct? Right. There is no specific check for the max value of peer-id at the place where peer-id is issued. Logic relies on max_clients option. So in case if max_clients is set to 2^24 or above, peer-id will wrap. There is a check, however, that peer-id is between 0 and max_clients in the code which handles incoming data packets. It's an improbable corner case, but I would still check for wrap. My rationale for checking for improbable corner cases is that code is always evolving, and sometimes code changes can make previously forgotten-about rare corner cases much more probable. * Server never pushes a "peer-id" directive unless the client has indicated its support for DATA_V2 by including "IV_PROTO=2" in the peer info data. Server pushes peer-id if IV_PROTO>=2. Is it ok or should it be changed to =2 ? That's a good question. I think IV_PROTO>=2 is okay. If we made a future change to the protocol that wasn't backward compatible, then we would have to make a new IV symbol for it, but having IV_PROTO be versioned does make it easier to introduce changes that _are_ backward compatible. * ensure that the float doesn't clobber a pre-existing client (i.e. if the address floated to is already owned by another client) unless it can be verified that the pre-existing client is a previous instance of the floating client. Thanks to this mail, I've checked code again and found a bug - a lame duck client may float to an address taken by another client. I have submitted a fix: http://thread.gmane.org/gmane.network.openvpn.devel/9386 which is waiting for an ACK. Otherwise implementation is pretty much in line with your spec. Great, thanks. James -Lev 2015-01-07 2:08 GMT+02:00 James Yonan: I've updated the OpenVPN protocol extension doc with additional details, now that more of these features have been implemented in OpenVPN 3. If you are implementing any of these features in OpenVPN 2.x, please review so we can ensure that OpenVPN 2.x and 3 are on the same page with respect to protocol extensions. Changes: 1. Added specific details on DATA_V2/peer-id/float support. 2. For AEAD mode, emphasized that the leading 8 bytes (4 bytes for DATA_V2/peer-id and 4 for packet ID) is all included in the AD. 3. Added specific details on protocol negotiation where the client indicates protocol extension availability with IV_x parameters in the peer info string, and the server responds by pushing directives to the client to enable the feature. 4. Added "TCP nonlinear mode" section, a new protocol extension that is needed by multithreaded TCP servers. James -- Dive into the World of Parallel Programming! The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net ___ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel
Re: [Openvpn-devel] OpenVPN protocol extensions update
Hi James, A few comments on peer-id part: * A disabled peer ID is denoted by 0xFF. * Server tells the client to use DATA_V2/peer_id by pushing the directive "peer-id ID" where ID is a decimal integer in the range [-1, 16777215]. Setting the peer ID to -1 transmits DATA_V2 packets with the peer ID field set to 0xFF. Setting the peer_id to -1 is the same as setting it to 16777215 (i.e. 0xFF). There is no such thing as "disabled peer-id" in current implementation, server does not send "-1" and client does not send 0xFF. I can surely do it, if needed. Could you maybe explain its meaning? And just to make sure - if server gets DATA_V2 with peer-id -1, it should skip peer-id bytes and treat it as data_v1, correct? There is no specific check for the max value of peer-id at the place where peer-id is issued. Logic relies on max_clients option. So in case if max_clients is set to 2^24 or above, peer-id will wrap. There is a check, however, that peer-id is between 0 and max_clients in the code which handles incoming data packets. * Server never pushes a "peer-id" directive unless the client has indicated its support for DATA_V2 by including "IV_PROTO=2" in the peer info data. Server pushes peer-id if IV_PROTO>=2. Is it ok or should it be changed to =2 ? * ensure that the float doesn't clobber a pre-existing client (i.e. if the address floated to is already owned by another client) unless it can be verified that the pre-existing client is a previous instance of the floating client. Thanks to this mail, I've checked code again and found a bug - a lame duck client may float to an address taken by another client. I have submitted a fix: http://thread.gmane.org/gmane.network.openvpn.devel/9386 which is waiting for an ACK. Otherwise implementation is pretty much in line with your spec. -Lev 2015-01-07 2:08 GMT+02:00 James Yonan: > I've updated the OpenVPN protocol extension doc with additional details, now > that more of these features have been implemented in OpenVPN 3. > > If you are implementing any of these features in OpenVPN 2.x, please review > so we can ensure that OpenVPN 2.x and 3 are on the same page with respect to > protocol extensions. > > Changes: > > 1. Added specific details on DATA_V2/peer-id/float support. > > 2. For AEAD mode, emphasized that the leading 8 bytes (4 bytes for > DATA_V2/peer-id and 4 for packet ID) is all included in the AD. > > 3. Added specific details on protocol negotiation where the client indicates > protocol extension availability with IV_x parameters in the peer info > string, and the server responds by pushing directives to the client to > enable the feature. > > 4. Added "TCP nonlinear mode" section, a new protocol extension that is > needed by multithreaded TCP servers. > > James > > -- > Dive into the World of Parallel Programming! The Go Parallel Website, > sponsored by Intel and developed in partnership with Slashdot Media, is your > hub for all things parallel software development, from weekly thought > leadership blogs to news, videos, case studies, tutorials and more. Take a > look and join the conversation now. http://goparallel.sourceforge.net > ___ > Openvpn-devel mailing list > Openvpn-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/openvpn-devel > -- -Lev
[Openvpn-devel] OpenVPN protocol extensions update
I've updated the OpenVPN protocol extension doc with additional details, now that more of these features have been implemented in OpenVPN 3. If you are implementing any of these features in OpenVPN 2.x, please review so we can ensure that OpenVPN 2.x and 3 are on the same page with respect to protocol extensions. Changes: 1. Added specific details on DATA_V2/peer-id/float support. 2. For AEAD mode, emphasized that the leading 8 bytes (4 bytes for DATA_V2/peer-id and 4 for packet ID) is all included in the AD. 3. Added specific details on protocol negotiation where the client indicates protocol extension availability with IV_x parameters in the peer info string, and the server responds by pushing directives to the client to enable the feature. 4. Added "TCP nonlinear mode" section, a new protocol extension that is needed by multithreaded TCP servers. James OpenVPN Protocol extensions 2015-01-06 1. DATA_V2 opcode with 24-bit peer ID * The DATA_V2 opcode is 9. * The DATA_V2 opcode/key_id byte is followed by 3 additional (network endian) bytes indicating the peer ID. * If a 4-byte DATA_V2 header is passed through ntohl, the resulting high 8 bits will be the DATA_V2 opcode/key_id, and the lower 24 bits will be the peer ID. * A disabled peer ID is denoted by 0xFF. * Server tells the client to use DATA_V2/peer_id by pushing the directive "peer-id ID" where ID is a decimal integer in the range [-1, 16777215]. Setting the peer ID to -1 transmits DATA_V2 packets with the peer ID field set to 0xFF. Setting the peer_id to -1 is the same as setting it to 16777215 (i.e. 0xFF). * Client never transmits DATA_V2 packets unless the server has pushed a "peer-id" directive. * Server never pushes a "peer-id" directive unless the client has indicated its support for DATA_V2 by including "IV_PROTO=2" in the peer info data. * When DATA_V2 is used for "float" functionality, the server must perform the following checks before allowing a client to float, i.e. to assume a new source address. (a) verify integrity (HMAC or GCM auth tag, replay protection, etc.) of the DATA_V2 packet, and (b) ensure that the float doesn't clobber a pre-existing client (i.e. if the address floated to is already owned by another client) unless it can be verified that the pre-existing client is a previous instance of the floating client. 2. AEAD mode To support AEAD crypto modes such as AES-GCM, some protocol changes are in order. AES-GCM, for example, requires a 12 byte unique nonce for every packet. I would propose that 4 bytes be taken from the Packet ID which increments for every packet and therefore provides uniqueness. The remaining 8 bytes would be derived from the random key material that would normally be used to key the HMAC key. This is possible since AEAD modes use a combined key for encryption and integrity checking, therefore the random key material for HMAC is unused and can be repurposed as an AEAD nonce source. The 8 byte nonce component derived from the HMAC keying material would remain constant for a given Key State. Only the 4 byte Packet ID would increment for each packet. Because AEAD encryption can be compromised if the nonce ever repeats for a given key, the implementation MUST disable encryption for a key if the 32-bit packet ID wraps. In practical usage, renegotiation usually preempts wrapping, so the disable-encryption-on-wrap feature is a failsafe. AEAD Nonce: [ Packet ID ] [ HMAC keying material ] [ 4 bytes ] [ 8 bytes ] [ AEAD nonce total: 12 bytes ] TLS wire protocol: [ DATA_V2 opcode ] [ Packet ID ] [ AEAD Auth tag ] [ ciphertext ] [ 4 bytes] [ 4 bytes ] [ 16 bytes ] [ AEAD additional data (AD)] Static Key wire protocol: [ DATA_V2 opcode ] [ Packet ID ] [ Nonce tail (random) ] [ AEAD Auth tag ] [ ciphertext ] [ AEAD nonce ] [ 4 bytes] [ 8 bytes ] [ 4 bytes ] [ 16 bytes ] [ AEAD additional data (AD)] Note that the AEAD additional data (AD) includes all data preceding the AEAD Auth tag including the DATA_V2/peer_id opcode and packet ID. Also, note that because the HMAC keying material used to derive the last 8 bytes of the AEAD nonce is negotiated once per key as part of the control channel handshake, we can omit it from the data channel packets, thereby saving 8 bytes per packet. So only the 4-byte Packet ID component of the nonce must be transmitted with every packet. When negotiating AEAD mode, the client indicates its support of AES-128-GCM, AES-192-GCM, and AES-192-GCM by including: IV_NCP=2 in the peer info string (NCP stands for