diff --git a/BTP.markdown b/BTP.markdown index 1a96bb0..b8c5184 100644 --- a/BTP.markdown +++ b/BTP.markdown @@ -9,31 +9,41 @@ The underlying transport is not required to provide any security properties. We Before two devices can communicate using BTP they must establish the following state: * A shared secret, *S* -* A timestamp called the epoch, *E* +* A timestamp, *T* * The maximum expected difference between the devices' clocks, *D* * The maximum expected latency of the transport, *L* +* A flag, *A*, which is true for one device and false for the other -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 *E* must be in the past according to both devices' clocks. +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. ### Crypto primitives BTP uses the following cryptographic primitives: -* A symmetric message authentication function, *MAC(k, m)* -* A symmetric authenticated cipher, *c = ENC(k, n, m)* and *m = DEC(k, n, c)*, where *n* is a nonce +* A pseudorandom function, *r = MAC(k, m)*, where *r* is *maclen* bytes +* An authenticated cipher, *c = ENC(k, n, m)* and *m = DEC(k, n, c)*, where *n* is a 24-byte nonce and *c* is *authlen* bytes longer than *m* -The output of *MAC* is *maclen* bytes. The output of *ENC(k, n, m)* is *authlen* bytes longer than *m*. All keys are *keylen* bytes and all nonces are 24 bytes. For simplicity we require that *maclen == keylen*. +All keys are *keylen* bytes. For simplicity we require that *maclen == keylen*. -We use || to denote concatenation, *int(b, x)* to denote *x* represented as a *b*-bit two's complement big-endian integer, *len(m)* to denote the length of *m* in bytes, and *pack(m)* as shorthand for *int(64, len(m))* || *m*. +We use *||* to denote concatenation, double quotes to denote a UTF-8 string, *int(b, x)* to denote *x* represented as a *b*-bit two's complement big-endian integer, *len(m)* to denote the length of *m* in bytes, and *pack(m)* as shorthand for *int(64, len(m)) || m*. ### Key derivation -BTP's key derivation function (KDF) is based on a message authentication function used as a pseudo-random function (PRF). This is similar to the "KDF in Counter Mode" from NIST SP 800-108. Since we require that *maclen* == *keylen*, the output of the MAC can be used directly as the output of the KDF, and we don't need to pass the output length or counter, both of which are fixed, to the MAC. +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 *keylen* bytes of output, so 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 is used to distinguish between different uses of the KDF. 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. -*KDF(k, p, a_1, ..., a_n) = MAC(k, pack(p)* || *pack(a_1)* || ... || *pack(a_n))* +*KDF(k, p, a_1, ..., a_n) = MAC(k, pack(p) || pack(a_1) || ... || pack(a_n))* + +Each device derives four initial keys from *S*: + +*alice_cipher = KDF(*S*, "ALICE_CIPHER")* +*bob_cipher = KDF(*S*, "BOB_CIPHER")* +*alice_tag = KDF(*S*, "ALICE_TAG")* +*bob_tag = KDF(*S*, "BOB_TAG")* + +Alice sets *out_cipher = alice_cipher*, *in_cipher = bob_cipher*, *out_tag = alice_tag*, *in_tag = bob_tag*. Bob sets *out_cipher = bob_cipher*, *in_cipher = alice_cipher*, *out_tag = bob_tag*, *in_tag = alice_tag*. ### Key rotation -BTP achieves forward secrecy by rotating keys periodically. The sender and recipient use the same deterministic function to rotate their keys, so they arrive at the same keys in each rotation period. \ No newline at end of file +BTP achieves forward secrecy by rotating keys periodically. The key rotation function is deterministic, so the devices have matching keys in each rotation period. \ No newline at end of file