Skip to content
Snippets Groups Projects
BTP.md 20.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • akwizgran's avatar
    akwizgran committed
    # Bramble Transport Protocol, version 4
    
    akwizgran's avatar
    akwizgran committed
    
    
    ## 1 Introduction
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    Bramble Transport Protocol (BTP) is a transport layer security protocol suitable for delay-tolerant networks. It provides a secure channel between two peers, ensuring the confidentiality, integrity, authenticity and forward secrecy of their communication across a wide range of underlying transports.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    BTP's main components are a time-based key management protocol and a wire protocol for securely carrying streams of data.
    
    akwizgran's avatar
    akwizgran committed
    
    
    BTP can operate over any transport that can deliver a stream of bytes from one device to another on a best-effort basis, meaning that streams may be delayed, lost, reordered or duplicated. The underlying transport is not required to provide any security properties.
    
    akwizgran's avatar
    akwizgran committed
    
    The BTP wire protocol includes optional padding and does not use any timeouts, handshakes or plaintext headers. This makes BTP compatible with traffic analysis prevention techniques such as traffic morphing, with the goal of making it difficult to distinguish BTP from other protocols.
    
    
    akwizgran's avatar
    akwizgran committed
    BTP does not attempt to conceal the identities of the communicating parties or the fact that they are communicating - in other words, it does not provide anonymity, unlinkability or unobservability. If such properties are required, BTP can use an anonymity system such as Tor as the underlying transport.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    Forward secrecy is achieved by establishing an initial root key between two peers and using a one-way key derivation function to derive a series of temporary keys from the root key. Once both peers have deleted a given key, it cannot be re-derived if the peer devices are later compromised.
    
    akwizgran's avatar
    akwizgran committed
    
    
    ### 1.1 Motivation
    
    akwizgran's avatar
    akwizgran committed
     
    
    akwizgran's avatar
    akwizgran committed
    The primary motivation for BTP's design is to provide a versatile building block for censorship-resistant communication systems. BTP is therefore designed to be used across a diverse mixture of transports, both online and offline, with varying properties. The transports are not given access to unencrypted or unauthenticated data; nor are they required to ensure the confidentiality, integrity, authenticity or forward secrecy of the data they carry. BTP is responsible for providing those properties.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    BTP is unusual in that it provides forward secrecy even for transports where one of the peers can only send and the other can only receive. It can be used on transports with very high latency, such as disks sent through the mail.
    
    akwizgran's avatar
    akwizgran committed
    
    
    ### 1.2 Design Requirements
    
    akwizgran's avatar
    akwizgran committed
    
    
    -   **Flexibility**
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
        The protocol should be able to operate over a wide range of underlying transports with bandwidths varying from kilobits to gigabits per second, and with latencies varying from milliseconds to days.
    
    akwizgran's avatar
    akwizgran committed
    
    
    -   **Layering**
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
        The protocol should treat each underlying transport connection as a unidirectional or bidirectional sequence of bytes with a simple socket-like interface (open, read/write, close). Likewise, the protocol should provide a socket-like interface to higher protocol layers.
    
    akwizgran's avatar
    akwizgran committed
    
    
    -   **Concealability**
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
        The protocol should not reveal any plaintext fields that would make it easily distinguishable from other protocols. It should be compatible with techniques such as traffic morphing that are designed to resist traffic analysis and traffic classification.
    
    akwizgran's avatar
    akwizgran committed
    
    
    -   **Confidentiality**
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
        The adversary should not be able to learn what data is being carried by the protocol.
    
    akwizgran's avatar
    akwizgran committed
    
    
    -   **Integrity**
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
        The adversary should not be able to cause either peer to read data from the BTP layer that differs from the data written to the BTP layer by the other peer. If the adversary truncates the data, the receiving peer should be able to detect that this has happened.
    
    akwizgran's avatar
    akwizgran committed
    
    
    -   **Authenticity**
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
        The adversary should not be able to cause either peer to accept data from any third party as though it came from the other peer.
    
    akwizgran's avatar
    akwizgran committed
    
    
    -   **Forward Secrecy**
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
        The adversary should not be able to learn what data was carried by the protocol if, at some later time, the adversary compromises one or both of the peer devices.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    The protocol is not required to conceal the identities of the communicating parties or the fact that they are communicating.
    
    akwizgran's avatar
    akwizgran committed
    
    
    ### 1.3 Adversary Model
    
    akwizgran's avatar
    akwizgran committed
    
    BTP is intended to be used in systems that resist surveillance and censorship by powerful adversaries, such as governments. We must therefore assume:
    
    
    - The adversary can observe, block, delay, replay and modify traffic on all underlying transports.
    
    akwizgran's avatar
    akwizgran committed
    
    
    - The adversary can choose the data written to the BTP layer by higher protocol layers.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - The adversary has a limited ability to compromise peer devices. If a device is compromised, the adversary can access any information held in the device's volatile memory or persistent storage.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - The adversary cannot break standard cryptographic primitives such as ciphers and message authentication codes.
    
    akwizgran's avatar
    akwizgran committed
    
    
    ### 1.4 Underlying Transports
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    BTP can operate over any transport that can deliver a unidirectional or bidirectional sequence of bytes from one device to another on a best-effort basis. We refer to this sequence of bytes as a **connection**. If the connection is unidirectional then BTP uses it to carry an encrypted and authenticated sequence of bytes, which we refer to as a **stream**. If the connection is bidirectional then BTP uses it to carry two separate streams, one in each direction.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    Transports must ensure that the bytes within a given connection arrive in the correct order. If the bytes within a connection are reordered then none of BTP's security properties are lost, but it will reject the stream or streams carried by the connection.
    
    akwizgran's avatar
    akwizgran committed
    
    Transport connections themselves may be reordered. There is no requirement that all connections reach the intended recipient.
    
    
    akwizgran's avatar
    akwizgran committed
    If one endpoint of a connection starts writing to the transport at time T0 and the other endpoint starts reading from the transport at time T1, we call T1 - T0 the **latency** of the connection. For a bidirectional connection we define the latency of the connection to be the maximum latency in either direction.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    If a transport imposes a maximum connection length, such as the storage capacity of a disk, BTP passes this restriction on to higher protocol layers by limiting the stream length; it does not fragment a stream across multiple connections. BTP cannot use transport connections with less capacity than the minimum length of a stream. (*Note:* In the current version of the protocol, the minimum length of a stream is 134 bytes.)
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    Using BTP over a datagram-oriented transport such as UDP (which does not have a concept of connections) would require the use of an intermediate connection-oriented protocol such as UDT to provide an ordered sequence of bytes in each direction.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    ### 1.5 Prerequisites
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    Before two peers can communicate using BTP they must agree on the following properties:
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - **Roles of the peers**
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
        The peers must agree which of them will play the role of **Alice** and which the role of **Bob**. The roles are identical except for some key derivation constants. It does not matter which peer plays which role, as long as one is Alice and the other Bob.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - **Maximum clock difference**
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
        The peers must agree on the maximum expected difference between their clocks, **D**. This value may be hard-coded. The current version of BTP assumes D = 86,400 seconds (24 hours). This is to accommodate mobile devices, which often have inaccurate clocks.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - **Maximum latency**
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
        The peers must agree on the maximum expected latency, **L**, of each transport they wish to use. This value may be hard-coded. For any given transport we can choose some maximum latency that is unlikely to be exceeded under normal conditions. For example, we might choose one minute as the maximum latency for TCP, or two weeks as the maximum latency for disks sent through the mail. If a connection exceeds the maximum latency, none of BTP's security properties are lost but it may reject the stream or streams carried by the connection.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    ### 1.6 Notation
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - || denotes concatenation
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - Double quotes denote an ASCII string
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - len(x) denotes the length of x in bytes
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - int\_n(x) denotes x represented as an unsigned, big-endian, n-bit integer
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    ### 1.7 Cryptographic Primitives
    
    akwizgran's avatar
    akwizgran committed
    
    BTP uses three cryptographic primitives:
    
    
    1.  **A pseudo-random function**, PRF(k, m)
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
        The output of PRF(k, m) is PRF\_LEN bytes. (*Note:* The current version of BTP uses keyed BLAKE2b with a 32-byte output length as the pseudo-random function, giving PRF\_LEN = 32.)
    
    akwizgran's avatar
    akwizgran committed
    
    
    2.  **An authenticated cipher**, ENC(k, n, m) and DEC(k, n, m), where n is a nonce
    
    akwizgran's avatar
    akwizgran committed
    
    
        The output of ENC(k, n, m) is AUTH\_LEN bytes longer than m. All keys are KEY\_LEN bytes and all nonces are NONCE\_LEN bytes. For simplicity we require that PRF\_LEN = KEY\_LEN. (*Note:* The current version of BTP uses XSalsa20/Poly1305 for the authenticated cipher, giving KEY\_LEN = 32, NONCE\_LEN = 24, and AUTH\_LEN = 16.)
    
    akwizgran's avatar
    akwizgran committed
    
    
    3.  **A random number generator**, R(n), with an output length of n bytes
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
        R(n) must be either an unbiased true random number generator or a cryptographically secure pseudo-random number generator.
    
    akwizgran's avatar
    akwizgran committed
    
    
    ## 2 Key Management Protocol
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    BTP uses a time-based key management protocol to derive a series of **temporary keys** from an initial **root key**. The root key must be KEY\_LEN bytes long and contain KEY\_LEN * 8 bits of entropy.
    
    ### 2.1 Key Management Modes
    
    BTP has two key management modes, which are suitable for different purposes.
    
    
    akwizgran's avatar
    akwizgran committed
    **Rotation mode** provides forward secrecy for the data being carried, but requires the peers to delete the root key, and any information that could be used to re-derive it, before the temporary keys are used. As well as the root key, rotation mode requires the peers to agree on a timestamp, **T**, which must be in the past according to both peers' clocks.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    **Handshake mode** does not provide forward secrecy for the data being carried, but allows the peers to retain the root key or information that could be used to re-derive it. Handshake mode does not require a timestamp.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    These modes are intended to be complementary. Handshake mode can be used to bootstrap rotation mode by carrying the messages of a key agreement protocol that establishes a root key and timestamp for rotation mode.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    The establishment of root keys and timestamps is not handled by BTP itself. BTP is designed to be used with a separate key agreement protocol that securely establishes the initial state. A key agreement protocol for rotation mode must use ephemeral keys, or a combination of static and ephemeral keys, such that the root key cannot be re-derived from information retained by the peers. A key agreement protocol for handshake mode may use static keys, as it is not necessary to prevent the root key from being re-derived.
    
    akwizgran's avatar
    akwizgran committed
    
    ### 2.2 Key Derivation Function
    
    
    akwizgran's avatar
    akwizgran committed
    BTP uses a **key derivation function** to derive temporary keys from the root key. The key derivation function is based on PRF(k, m):
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - KDF(k, x\_1, ..., x\_n) = PRF(k, int\_32(len(x\_1)) || x\_1 || ... || int\_32(len(x\_n)) || x\_n)
    
    ### 2.3 Time Periods
    
    For each transport, BTP divides time into numbered periods, where period zero starts at the Unix epoch. A different set of temporary keys is used for each period.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    The length of each period is D + L seconds, where D is the maximum expected difference between the peers' clocks and L is the maximum expected latency of the transport.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    This ensures that if the sender starts sending a stream in period P0 according to the sender's clock, and if D and L are not exceeded, then the recipient will start receiving the stream in period P1 according to the recipient's clock, where abs(P1 - P0) <= 1. In other words, the recipient only needs to retain the temporary keys for the previous, current and next periods.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    ### 2.4 Key Derivation for Rotation Mode
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    In rotation mode, BTP achieves forward secrecy by periodically rotating and deleting the temporary keys. The key derivation function is deterministic, so peers that start from the same root key and timestamp will derive the same temporary keys for each time period. Forward secrecy relies on the one-way nature of the key derivation function: the keys of an earlier period cannot be re-derived from those of a later period.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    ##### Initial Keys
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    The peers derive temporary keys for each transport over which they want to communicate. Each transport is uniquely identified by an ASCII string known to both peers (for example, "org.briarproject.bramble.bluetooth" for Bluetooth).
    
    For each transport, each peer derives four initial keys from the root key. Alice derives her initial keys as follows:
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - outgoing\_tag\_key := KDF(root\_key, "org.briarproject.bramble.transport/ALICE\_TAG\_KEY", transport\_id)
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - outgoing\_header\_key := KDF(root\_key, "org.briarproject.bramble.transport/ALICE\_HEADER\_KEY", transport\_id)
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - incoming\_tag\_key := KDF(root\_key, "org.briarproject.bramble.transport/BOB\_TAG\_KEY", transport\_id)
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - incoming\_header\_key := KDF(root\_key, "org.briarproject.bramble.transport/BOB\_HEADER\_KEY", transport\_id)
    
    akwizgran's avatar
    akwizgran committed
    
    Bob derives his initial keys as follows:
    
    
    akwizgran's avatar
    akwizgran committed
    - outgoing\_tag\_key := KDF(root\_key, "org.briarproject.bramble.transport/BOB\_TAG\_KEY", transport\_id)
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - outgoing\_header\_key := KDF(root\_key, "org.briarproject.bramble.transport/BOB\_HEADER\_KEY", transport\_id)
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - incoming\_tag\_key := KDF(root\_key, "org.briarproject.bramble.transport/ALICE\_TAG\_KEY", transport\_id)
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - incoming\_header\_key := KDF(root\_key, "org.briarproject.bramble.transport/ALICE\_HEADER\_KEY", transport\_id)
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    Thus Alice's outgoing keys for each transport are the same as Bob's incoming keys, and vice versa.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    After deriving the initial keys, both peers must delete the root key.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    The initial keys are used as the temporary keys for period P - 1, where period P contains the timestamp T.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    The purpose of the timestamp is to save the cost of rotating keys from period zero to the current period. If it is not possible or convenient to agree a timestamp T along with the root key then T can be hard-coded to some value that is certain to be in the past according to both peers' clocks, at the cost of some extra key rotations.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    ##### Key Rotation
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    The temporary keys for each time period P are derived from the previous period's keys as follows:
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - outgoing\_tag\_key := KDF(outgoing\_tag\_key, "org.briarproject.bramble.transport/ROTATE", int\_64(P))
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - outgoing\_header\_key := KDF(outgoing\_header\_key, "org.briarproject.bramble.transport/ROTATE", int\_64(P))
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - incoming\_tag\_key := KDF(incoming\_tag\_key, "org.briarproject.bramble.transport/ROTATE", int\_64(P))
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - incoming\_header\_key := KDF(incoming\_header\_key, "org.briarproject.bramble.transport/ROTATE", int\_64(P))
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    To ensure forward secrecy, keys must be deleted when they are no longer needed. The outgoing keys for period P must be deleted at the end of period P, while the incoming keys for period P must be deleted at the end of period P + 1.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    ### 2.5 Key Derivation for Handshake Mode
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    In handshake mode, BTP does not provide forward secrecy. The temporary keys for any period can be derived from the root key, which is retained by the peers.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    Alice derives her temporary keys for each time period P as follows:
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - outgoing\_tag\_key := KDF(root\_key, "org.briarproject.bramble.transport/ALICE\_HANDSHAKE\_TAG\_KEY", transport\_id, int\_64(P))
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - outgoing\_header\_key := KDF(root\_key, "org.briarproject.bramble.transport/ALICE\_HANDSHAKE\_HEADER\_KEY", transport\_id, int\_64(P))
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - incoming\_tag\_key := KDF(root\_key, "org.briarproject.bramble.transport/BOB\_HANDSHAKE\_TAG\_KEY", transport\_id, int\_64(P))
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - incoming\_header\_key := KDF(root\_key, "org.briarproject.bramble.transport/BOB\_HANDSHAKE\_HEADER\_KEY", transport\_id, int\_64(P))
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    Bob derives his temporary keys as follows:
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - outgoing\_tag\_key := KDF(root\_key, "org.briarproject.bramble.transport/BOB\_HANDSHAKE\_TAG\_KEY", transport\_id, int\_64(P))
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - outgoing\_header\_key := KDF(root\_key, "org.briarproject.bramble.transport/BOB\_HANDSHAKE\_HEADER\_KEY", transport\_id, int\_64(P))
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - incoming\_tag\_key := KDF(root\_key, "org.briarproject.bramble.transport/ALICE\_HANDSHAKE\_TAG\_KEY", transport\_id, int\_64(P))
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - incoming\_header\_key := KDF(root\_key, "org.briarproject.bramble.transport/ALICE\_HANDSHAKE\_HEADER\_KEY", transport\_id, int\_64(P))
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    Thus Alice's outgoing keys for each transport are the same as Bob's incoming keys, and vice versa.
    
    akwizgran's avatar
    akwizgran committed
    The outgoing keys for period P can be deleted at the end of period P, and the incoming keys for period P can be deleted at the end of period P + 1, but this is not required for security.
    
    akwizgran's avatar
    akwizgran committed
    ## 3 Wire Protocol
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    A stream consists of three parts: a **pseudo-random tag**, a **stream header**, and one or more **frames**.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    ### 3.1 Tags
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    Each stream starts with a pseudo-random tag TAG\_LEN bytes long. (*Note:* In the current version of the protocol, TAG\_LEN = 16.) The recipient calculates the same tag in advance and uses it to recognise which sender the stream comes from and which incoming header key should be used for the stream.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    The tag for the i<sup>th</sup> stream from a given sender to a given recipient in a given time period is the first TAG\_LEN bytes of PRF(k, int\_16(protocol\_version) || int\_64(i)), where k is the sender's outgoing tag key (which is also the recipient's incoming tag key) and protocol\_version is 4 for the current version of BTP. Streams are counted from zero in each time period.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    ### 3.2 Stream Headers
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    The pseudo-random tag is followed by the stream header, which has the following format:
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - nonce = R(NONCE\_LEN)
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - stream\_header\_plaintext = int\_16(protocol\_version) || int\_64(stream\_number) || ephemeral\_cipher\_key
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - stream\_header = nonce || ENC(outgoing\_header\_key, nonce, stream\_header\_plaintext)
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    The stream header is NONCE\_LEN + 2 + 8 + KEY\_LEN + AUTH\_LEN = 82 bytes long. The header contains an **ephemeral cipher key** that is used for encrypting and authenticating the rest of the stream.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    The random nonce ensures that even if a stream number is accidentally reused, the combination of header key and nonce will be unique, which is a security requirement of many ciphers.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    ### 3.3 Frames
    
    akwizgran's avatar
    akwizgran committed
    
    
    The remainder of the stream consists of one or more frames. Each frame has a fixed-length **frame header** and a variable-length **frame body** that may contain data and/or padding. The total length of the data and padding must be no more than 988 bytes, giving a maximum length of 1,024 bytes for an encrypted frame, including the header.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    The frames in each stream are numbered from zero. A stream must not contain more than 2<sup>63</sup> frames.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    ##### Frame Header
    
    akwizgran's avatar
    akwizgran committed
    The plaintext frame header is four bytes long, with the following format (where bit zero is the most significant):
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - Bit 0: Final frame flag, set to one if this is the last frame in the stream
    
    - Bits 0 - 15: int\_16(len(data))
    
    - Bits 16 - 31: int\_16(len(padding))
    
    
    The final frame flag overlaps with the most significant bit of the data length, which is unused because the data must be no more than 988 bytes long.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    The final frame flag allows the recipient to detect the end of the stream without reading to EOF, which is not possible for all transports on all platforms.
    
    ##### Encryption and Authentication
    
    The header and body of each frame are encrypted and authenticated separately using the ephemeral cipher key and deterministic nonces. The nonces are not sent over the wire.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    Each nonce is NONCE\_LEN bytes long, with the following format (where bit zero is the most significant):
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    - Bit 0: Header flag, set to one for the frame header or zero for the frame body
    
    - Bits 0 - 63: int\_64(frame\_number)
    
    akwizgran's avatar
    akwizgran committed
    
    
    - Remaining bits: Zero
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    The header flag overlaps with the most significant bit of the frame number, which is unused because a stream must not contain more than 2<sup>63</sup> frames.
    
    
    The encrypted and authenticated frame header is 4 + AUTH\_LEN bytes long, while the encrypted and authenticated frame body is AUTH\_LEN bytes longer than the data and padding.
    
    akwizgran's avatar
    akwizgran committed
    
    
    ## 4 Reordering Windows
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    BTP uses **reordering windows** to allow peers to recognise streams that are received out of order due to reordering or loss of connections by the underlying transport. Each peer maintains reordering windows for the previous, current and next time periods. The windows are used to recognise incoming streams by their tags.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    Each window contains **W** tags, each of which is marked as *seen* or *unseen*. W is an implementation parameter. Maintaining larger windows makes it possible to tolerate more reordering or loss by the transport, at the cost of storing more tags. (*Note:* In the current implementation of the protocol, W = 32.)
    
    akwizgran's avatar
    akwizgran committed
    
    When a previously unseen tag is marked as seen, the window slides according to the following rules:
    
    
    1. Slide the window until all tags in the top half of the window are unseen.
    
    akwizgran's avatar
    akwizgran committed
    
    
    2. Slide the window until the lowest tag in the window is unseen.
    
    akwizgran's avatar
    akwizgran committed
    
    If the window slides past a tag that has not been seen, the recipient can no longer recognise the corresponding stream.
    
    
    akwizgran's avatar
    akwizgran committed
    To avoid reusing tags, which would allow the adversary to distinguish BTP traffic from other protocols, the sender must persistently store the number of streams sent to the recipient in the current time period.
    
    akwizgran's avatar
    akwizgran committed
    
    
    akwizgran's avatar
    akwizgran committed
    To avoid accepting replayed streams, the recipient must persistently store the reordering windows for the previous, current and next time periods.