akwizgran created page: BTP

akwizgran
2015-03-16 18:12:48 +00:00
parent c9037afe46
commit 76b788f1f0

@@ -11,9 +11,9 @@ We use *||* to denote concatenation, double quotes to denote a UTF-8 string, *in
BTP uses the following cryptographic primitives: BTP uses the following cryptographic primitives:
* A pseudorandom function, *r = MAC(k, m)*, where *r* is *mac_len* bytes long * A pseudorandom function, *r = MAC(k, m)*, where *r* is *mac_len* bytes long
* An authenticated cipher, *c = ENC(k, n, m)* and *m = DEC(k, n, c)*, where *n* is a 24-byte nonce and *c* is *auth_len* bytes longer than *m* * An authenticated cipher, *c = ENC(k, n, m)* and *m = DEC(k, n, c)*, where *n* is a nonce and *c* is *auth_len* bytes longer than *m*
All keys are *key_len* bytes long. For simplicity we require that *mac_len == keylen*. All keys are *key_len* bytes long and all nonces are *nonce_len* bytes long. For simplicity we require that *mac_len == key_len*.
### Initial state ### Initial state
@@ -23,13 +23,14 @@ Before two devices can communicate using BTP they must establish the following s
* A timestamp, *T* * A timestamp, *T*
* The maximum expected difference between the devices' clocks, *D* * The maximum expected difference between the devices' clocks, *D*
* The maximum expected latency of the transport, *L* * The maximum expected latency of the transport, *L*
* A flag that is true for one device and false for the other, *A*
How this state is established is outside the scope of BTP. The devices must establish a separate *S* for each transport over which they wish to communicate, and *T* must be in the past according to both devices' clocks. The device for which *A* is true is referred to as Alice, and the device for which *A* is false is referred to as Bob. How this state is established is outside the scope of BTP. The devices must establish a separate *S* for each transport over which they wish to communicate, and *T* must be in the past according to both devices' clocks.
The devices must also agree which of them will play the role of Alice and which will play the role of Bob. The roles are identical except for some key derivation constants.
### Key derivation ### Key derivation
BTP's key derivation function is based on a pseudorandom function, similar to the counter mode KDF from NIST SP 800-108. The KDF always produces *key_len* bytes of output, so we can omit the counter and output length arguments. BTP's key derivation function is based on a pseudorandom function. It is broadly similar to the counter mode KDF from NIST SP 800-108, but as it always produces *key_len* bytes of output, we can omit the counter and output length arguments.
The key derivation function takes an input key *k*, a label *p*, and zero or more additional arguments *a_1* to *a_n*, and returns an output key. The label describes the purpose of the output key, and the additional arguments vary according to the purpose. The key derivation function takes an input key *k*, a label *p*, and zero or more additional arguments *a_1* to *a_n*, and returns an output key. The label describes the purpose of the output key, and the additional arguments vary according to the purpose.
@@ -37,15 +38,24 @@ The key derivation function takes an input key *k*, a label *p*, and zero or mor
Each device derives four initial keys from *S*: Each device derives four initial keys from *S*:
*alice_cipher = KDF(*S*, "ALICE_CIPHER")* *ack = KDF(*S*, "ALICE_CIPHER_KEY")*
*bob_cipher = KDF(*S*, "BOB_CIPHER")* *bck = KDF(*S*, "BOB_CIPHER_KEY")*
*alice_tag = KDF(*S*, "ALICE_TAG")* *atk = KDF(*S*, "ALICE_TAG_KEY")*
*bob_tag = KDF(*S*, "BOB_TAG")* *btk = KDF(*S*, "BOB_TAG_KEY")*
Alice sets *out_cipher = alice_cipher*, *in_cipher = bob_cipher*, *out_tag = alice_tag*, and *in_tag = bob_tag*. Alice sets *ock = ack*, *ick = bck*, *otk = atk*, and *itk = btk*. Bob sets *ock = bck*, *ick = ack*, *otk = btk*, and *itk = atk*. Thus Alice's outgoing keys (*ock* and *otk*) are the same as Bob's incoming keys (*ick* and *itk*) and vice versa.
Bob sets *out_cipher = bob_cipher*, *in_cipher = alice_cipher*, *out_tag = bob_tag*, and *in_tag = alice_tag*.
### Key rotation ### Key rotation
BTP achieves forward secrecy by rotating keys periodically. The key rotation function is deterministic, so the devices always have matching keys. BTP achieves forward secrecy by rotating keys periodically. The key rotation function is deterministic, so devices that start from the same *S* will have matching keys in each rotation period.
The length of each rotation period is *R = D + L*. Rotation periods are aligned with the Unix epoch, *E*. The timestamp *T* falls in rotation period *P = floor((T - E) / R)*, where all times are measured in seconds.
If a sender starts sending a stream at time *t* according to the sender's clock, the recipient may start receiving it at any time between *t - D* and *t + D + L* according to the recipient's clock. Therefore each device must retain the incoming keys for the previous, current and next rotation periods, along with the outgoing keys for the current rotation period.
The four initial keys derived from *S* are the keys for period *P - 1*. The keys for each subsequent period *i* are derived from the previous period's keys as follows:
*next_ock = KDF(ock, "ROTATE", int(64, i))*
*next_ick = KDF(ick, "ROTATE", int(64, i))*
*next_otk = KDF(otk, "ROTATE", int(64, i))*
*next_itk = KDF(itk, "ROTATE", int(64, i))*