|[ << ]||[ >> ]||[Top]||[Contents]||[Index]||[ ? ]|
6.1 The CIPE protocol Encrypted IP encapsulation used by CIPE. 6.2 The PKCIPE Protocol Public-key based setup and key exchange.
This chapter is copied verbatim from the earlier documentation texts.
The primary goal of this software is to provide a facility for secure (against eavesdropping, including traffic analsyis, and faked message injection) subnetwork interconnection across an insecure packet network such as the Internet.
This protocol was designed to be simple and efficient, and to work over existing communication facilities, especially by encapsulation in UDP packets. Compatibility with existing protocols such as the IPSEC RFCs were not a concern. The first test implementation was done entirely on the user level, while the now published one consists of a kernel module and a user level program.
The CIPE model assumes a fixed link between two peers which exchange datagrams (packetwise, not necessarily reliable). The most common way of implementing such a thing is sending UDP messages between them. (Another would be encapsulation in PPP, etc.)
Nothing that can be parameterized is inside the scope of this protocol and implementation. This is delegated to either prior arrangement or a yet-to-be-defined application level protocol. Most notably, this involves exchanging a shared secret key by now, and it involves choice of encryption algorithm.
The CIPE protocol consists of two parts: Encryption and checksumming of the data packets and dynamic key exchange.
2. Packet encryption
Each IP datagram is taken as a whole, including headers. It is padded at the end with zero to seven random octets so that the total length in octets is congruent three modulo eight. The padded packet is appended with one octet of the value P described below and the CRC-32 over the packet built up so far, up to and including P. (This makes the complete packet length a multiple of eight octets.)
This packet is then encrypted through a 64-bit block cipher in CBC mode with an IV as described below using either the static or the sending dynamic key of the outbound interface (for definition of keys see below). The default cipher algorithm is IDEA. The current implementation also supports Blowfish with 128 bit key.
The encrypted packet is prepended with the IV block. The highest order bit of the first octet of the IV is zero if the static key is used, one if the dynamic key is used. The remaining 63 bits are random, but the first 31 of them should not be all zeros (i.e. an IV/packet that starts with hex 0000 0000 or 8000 0000 is not allowed). Such packets are reserved for later protocol extensions.
The CRC is over the polynomial
The value P is given as follows: bits 6,5,4 indicate the length of the padding between the original packet end and P. Bits 2,1 are a type code, indicating which kind of packet this is. The remaining bits 7,3,0 are reserved and must be zero.
The type codes are: 00 - data 01 - key exchange 10 - reserved 11 - reserved
For decryption, first check the highest bit of the first octet and use it to select the key. Decrypt the packet, calculate the CRC over the packet minus the last four octets, compare that with the last four octets. If valid, strip off the last octet as value P, strip off the padding as given by bits 6,5,4 of P and process the packet as indicated by bits 2,1 of P.
3. Key exchange
Every interface is associated with a static key, a sending dynamic key and a receiving dynamic key. (An interface is an endpoint of a connection, which may use protocols like UDP for transport but for the purpose of CIPE are always point-to-point links.) On startup, only the static key is valid. Encryption uses the static key if and only if the sending dynamic key is invalid. The value 0 (all bits zero) for the static key is reserved for future extensions and should not be used.
The dynamic key is set by a dialogue procedure involving messages with type code bits 01. These are encrypted just like above. The packets consist of a type octet followed by protocol data followed by a random amount of padding random data, so that the packet is at least 64 octets long. A key consists of 16 octets, a key CRC is the CRC-32 over the key, transferred in network order.
The following messages exist:
NK_REQ: Type code 1, no data: Requests the peer to immediately start a key negotiation (send NK_IND). This should be sent when a packet is received encrypted with a dynamic key but no dynamic receive key is valid. (Which can happen when the receiving side of a connection is rebooted while the sending side remains running.)
NK_IND: Type code 2, data is new key followed by key CRC. Specifies a new sending dynamic key for this sender. Requests the peer to immediately answer with NK_ACK.
NK_ACK: Type code 3, data is CRC of the previously accepted key. Confirms receipt of NK_IND.
The key negotiation procedure normally runs as follows: The sender sends a NK_IND with the new key, then invalidates its own sending key. Upon receipt of NK_IND, the receiver starts using this key as its receiving key and sends a NK_ACK. When the sender receives NK_ACK, it starts using the new key as its sending key. If either of NK_IND or NK_ACK is lost in transmission, no new key will be used. The sender should send a new NK_IND (with new key) if no matching NK_ACK is received within a reasonable amount of time (current specification: 10 seconds).
If any of the checksums contained in the key negotiation data mismatches the contained or stored key, this packet is ignored and no further action taken.
A sending dynamic key should be invalidated after being used for a certain period of time or amount of data and a new NK_IND sent. The process is symmetric and both sides act independently for their own sending key. The dynamic key lifetime should not exceed 15 minutes and the amount of data sent using one dynamic key should not exceed 2^32 packets.
Optionally, the key exchange packets can be timestamped. The timestamp is a 32bit unsigned integer in network order representing the UNIX time of the sending host, placed in octets 56-59 (starting at zero) of the key exchange packets. The receiver may be configured to ignore the timestamp, or it may be configured to reject all key exchange packets whose timestamp differs from the current UNIX time of the receiving host by more than a defined amount. It is recommended that this timeout not exceeds 30 seconds.
4. Security considerations
The packets that actually get transmitted don't carry any usable information related to the original IP datagram other than its length, padded to a multiple of 8. This should effectively guard against most aspects of traffic analysis. The only information visible prior (attempt) to decrypting the packet is the bit that tells whether the static or dynamic key was used. Because the static key has a potentially long lifetime it is expected to be used as rarely as possible. It is normally used only in the short period of time during a key exchange. The dynamic key is changed often. These precautions are there because the application is prone to known and chosen plaintext attacks and the intention is to inhibit feeding of large amounts of data through one key.
Because the type code and padding length are encrypted with the packet, they can not be deduced from the ciphertext. Especially, it is not possible to determine whether the packet is a data or key exchange packet. (Usually, the last packet of a sequence of dynamic key packets followed by a sequence of static key packets is a NK_IND, but the NK_ACK and a possible second NK_IND can't be guessed this way, so there is no provision to tell whether the key exchange succeeded. However, this is a small but real weakness.)
The CRC serves as a check whether the encryption key was valid - i.e. some sort of signature for authenticity of the packet. Additionally, data packets should still have to form valid IP headers (with their own 16-bit checksum) and key exchange packets carry their own checksum as defined above.
IP packets carry some known or easily guessable plaintext in certain positions of their header. Potential exploitation of this fact should be mitigated by the limited key usage described above. The use of a random IV for each packet means at least that identical (retransmitted) packets encrypt to different ciphertexts.
The protocol gives only limited protection against replay attacks. A packet remains valid as long as the key it is encrypted with remains valid. However, active exploitation is unlikely as the packet carries no indication of its meaning. (Except for the note about sequences and NK_IND above. Replay of NK_IND could be dangerous. Possible remedy: store the last N accepted key CRCs [for large-ish N] and refuse to accept NK_INDs with the same CRC as an already stored one.)
If the timestamp of key exchange packets is used, it should guard against replay of key exchange packets. However, this requires that the clocks of both machines are in sync.
Denial of service attacks are possible e.g. by sending large amounts of bogus packets, which should affect performance only. A vulnerability against disruption of the key generation process exists if the sender is overrun with bogus packets so that it fails to process the NK_ACK, effectively being forced to use its static sending key for a prolonged period of time. A possible way out of this problem is to stop sending data completely after a long burst of static key sends, sending only NK_INDs and resuming only after a valid NK_ACK has been processed. Then this attack would become a simple denial-of-service.
5. Practical test, Conclusion
The mentioned prototype implementations, one on the user level and one as a kernel module, have been in use for several months now on a live network, where they provide a transparent connection between subnetworks through an insecure transit network based on UDP encapsulation. This does work flawlessly. However, it is too early to draw final conclusions about the feasibility of this approach.
It is planned to replace the simple secret key based key exchange process described above by a signed Diffie-Hellman scheme, which would eliminate the need for secret keys.
6. Appendix: New protocol for control messages in CIPE 1.3
CIPE 1.3 has added control messages. These are transmitted as key exchange messages with a type code of 0x70 or higher. They may, but don't need to carry a timestamp.
CT_DUMMY: Type code 0x70. Dummy/keepalive message, should be ignored by the receiver.
CT_DEBUG: Type code 0x71. Debug message. The data is a string which the receiver should log.
CT_PING: Type code 0x72. Echo request. Receiver should immediately answer with a CT_PONG.
CT_PONG: Type code 0x73. Echo reply. Data should be copied from the CT_PING message.
CT_KILL: Type code 0x74. Requests the peer to exit. Data is a string which should be logged, indicating the reason.
Strings sent in control packets should not exceed 254 octets in length. They should be terminated with a zero octet, after which random padding may follow. If the messages are timestamped, the string must not exceed a length of 54 octets, so a timestamp can be placed at octet 56.
CIPE 1.5 has added the following control messages. Because they are expected to be evaluated without even knowing if a matching key exists, they are sent as unencrypted control messages (see next section).
CT_CONFREQ: Type code 0x75. Tells the peer the fixed (compile-time) configuration parameters. The receiver should compare this to its own parameters, warn the user on any mismatch, and in any case immediately reply with a CT_CONF message.
The data in this packet is the following structure (shown here including the type code:)
|(Octet 0||the type code)|
|4-8||the ASCII letters "CIPE"|
|9||the protocol version, here 3 or 4|
|10||letter indicating the encryption algorithm ("b" or "i")|
|11-12||Major/minor number of the software release|
|13||1 if the implementation uses a correct key parser,|
|0 for the broken key interpretation of CIPE <1.4|
CT_CONF: Type code 0x76. Identical to CT_CONFREQ except that it does not solicit a response.
7. Appendix: New protocol for unencrypted control messages in CIPE 1.5
Starting with CIPE 1.5, control messages of certain kinds may be sent in the clear without any encryption at all. These are sent as a packet starting with an all-zeros IV (i.e. 8 zero bytes for IDEA and Blowfish), after which the actual message follows. The packet may carry a timestamp; the position of the timestamp is calculated starting with (i.e. including) the all-zeros IV.
Receivers must treat a packet starting with an IV with its first 32 bits zero as unencrypted control message. They must discard with a warning any unencrypted control message which would affect the proper operation of the daemon or the keying, especially CT_KILL and all KX_ messages.
A. Appendix: Errata
The IV specification originally said: "The remaining 63 bits are random, but the first 15 of them should not be all zeros (i.e. an IV/packet that starts with hex 0000 0000 or 8000 0000 is not allowed)." This is inconsistent. The hex numbers are correct and the right number of bits is 31. This has been corrected in the text above.
To be written.
|[ << ]||[ >> ]||[Top]||[Contents]||[Index]||[ ? ]|