... | ... | @@ -2,7 +2,7 @@ BQP is a key agreement protocol that establishes an ephemeral secure channel bet |
|
|
|
|
|
Each device displays a QR code containing a commitment to an ephemeral public key and information about how to connect to the device over various short-range transports. The devices scan each other's codes and use the connection information to establish an insecure duplex channel. The devices exchange public keys matching their commitments over the insecure channel. Each device derives the shared secret from its own private key and the received public key, and keys derived from the shared secret are used to secure the channel. Further information, such as long-term public keys, may then be exchanged over the secure channel.
|
|
|
|
|
|
The initial exchange of QR codes is assumed to be secure against man-in-the-middle attacks because the users can see which devices they are scanning. Man-in-the-middle attacks against the subsequent exchange of public keys over the insecure channel can be detected by comparing the keys to the commitments contained in the QR codes. We assume the adversary can read, modify, delete and insert traffic on the short-range transports at will.
|
|
|
The initial exchange of QR codes is assumed to be secure against man-in-the-middle attacks because the users can see which devices they are scanning. Man-in-the-middle attacks against the subsequent exchange of public keys over the insecure channel can be detected by comparing the keys to the commitments contained in the QR codes. We assume the adversary can read, modify, delete and insert traffic on the transports at will.
|
|
|
|
|
|
### Notation
|
|
|
|
... | ... | @@ -15,46 +15,115 @@ BQP uses the following cryptographic primitives: |
|
|
* A cryptographic hash function, H(m)
|
|
|
* A key agreement function, DH(pri, pub), where pri is one party's private key and pub is the other party's public key
|
|
|
* A message authentication code, MAC(k, m)
|
|
|
* An authenticated cipher, ENC(k, n, m) and DEC(k, n, m), where n is a nonce
|
|
|
|
|
|
All hashes are HASH_LEN bytes, all symmetric keys are KEY_LEN bytes and all nonces are NONCE_LEN bytes. The output of MAC(k, m) is MAC_LEN bytes, and the output of ENC(k, n, m) is AUTH_LEN bytes longer than m. For simplicity we require that MAC_LEN == KEY_LEN.
|
|
|
We use H(m) to define a multi-argument hash function:
|
|
|
|
|
|
> Implementation note: We propose to use BLAKE2s as the hash function, Curve25519 as the key agreement function, keyed BLAKE2s as the message authentication code, and XSalsa20/Poly1305 as the authenticated cipher. This gives HASH_LEN = 32, KEY_LEN = 32, MAC_LEN = 32, NONCE_LEN = 24, and AUTH_LEN = 16.
|
|
|
* `HASH(x_1, ..., x_n) == H(len(x_1) || x_1 || ... || len(x_n) || x_n)`
|
|
|
|
|
|
We use MAC(k, m) to define a key derivation function:
|
|
|
|
|
|
* `KDF(k, x_1, ..., x_n) == MAC(k, len(x_1) || x_1 || ... || len(x_n) || x_n)`
|
|
|
|
|
|
All hashes are HASH_LEN bytes, all symmetric keys are KEY_LEN bytes, and the output of MAC(k, m) is MAC_LEN bytes. For simplicity we require that HASH_LEN == KEY_LEN == MAC_LEN.
|
|
|
|
|
|
> Implementation note: We propose to use BLAKE2s as the hash function, Curve25519 as the key agreement function, and keyed BLAKE2s as the message authentication code. This gives HASH_LEN = KEY_LEN = MAC_LEN = 32.
|
|
|
|
|
|
### Key generation
|
|
|
|
|
|
Each device starts by generating a fresh ephemeral key pair (pri, pub). The commitment to the public key is H(pub).
|
|
|
Each device starts by generating a fresh ephemeral key pair (pri, pub). The commitment to the public key is HASH("COMMIT", pub).
|
|
|
|
|
|
### QR codes
|
|
|
|
|
|
Each device creates a QR code containing a binary payload. The payload is encoded using Base32, as defined in [RFC 4648](https://tools.ietf.org/html/rfc4648), which allows the QR code to use alphanumeric mode. The first byte of the payload is the protocol version, which is 1 for the current version of BQP. The next HASH_LEN bytes of the payload are the commitment to the ephemeral public key. The remainder of the payload consists of zero or more transport records, as defined in the next section.
|
|
|
Each device creates a QR code with a binary payload. The payload is encoded using Base32, as defined in [RFC 4648](https://tools.ietf.org/html/rfc4648), and the QR code uses alphanumeric mode. The first byte of the binary payload is the protocol version, which is 1 for the current version of BQP. The next HASH_LEN bytes of the payload are the public key commitment. The remainder of the payload consists of zero or more transport descriptors.
|
|
|
|
|
|
### Transport records
|
|
|
### Transport descriptors
|
|
|
|
|
|
A transport record describes how to connect to a device over a short-range transport. Each record starts with a two-byte header. The first byte identifies the transport and the second byte gives the number of chunks in the record body. The chunks contain transport-dependent data. Each chunk is preceded by a byte giving the length of the chunk in bytes.
|
|
|
A transport descriptor describes how to connect to a device over a short-range transport. Each descriptor starts with a two-byte header. The first byte identifies the transport, the second gives the number of fields in the descriptor. Each field consists of a single byte giving the length of the value in bytes, followed by the value.
|
|
|
|
|
|
The following transports have been defined so far:
|
|
|
The following transports have been defined:
|
|
|
|
|
|
**0: Bluetooth** - The device registers a Bluetooth service to accept RFCOMM connections. The service UUID is generated by converting the first 16 bytes of the public key commitment into a UUID as specified in section 4.4 of [RFC 4122](https://tools.ietf.org/html/rfc4122). The record body contains one chunk:
|
|
|
**0: Bluetooth** - The device registers a Bluetooth service to accept RFCOMM connections. The service UUID is generated by converting the first 16 bytes of the device's public key commitment into a UUID as specified in section 4.4 of [RFC 4122](https://tools.ietf.org/html/rfc4122). The descriptor contains one field:
|
|
|
|
|
|
* The device's Bluetooth MAC address (6 bytes)
|
|
|
|
|
|
**1: LAN** - The device connects to a local area network and opens a port to accept TCP connections. The record body contains two chunks:
|
|
|
**1: LAN** - The device connects to a local area network and opens a port to accept TCP connections. The descriptor contains two fields:
|
|
|
|
|
|
* The device's link-local or site-local IPv4 or IPv6 address (4 or 16 bytes)
|
|
|
* The port number as a 16-bit integer (2 bytes)
|
|
|
|
|
|
**2: Wi-Fi** - The device connects to a Wi-Fi network and opens a port to accept TCP connections. The record body contains three chunks:
|
|
|
**2: Wi-Fi** - The device connects to a Wi-Fi network and opens a port to accept TCP connections. The descriptor contains three fields:
|
|
|
|
|
|
* The device's link-local or site-local IPv4 or IPv6 address (4 or 16 bytes)
|
|
|
* The port number as a 16-bit integer (2 bytes)
|
|
|
* The SSID of the Wi-Fi network (variable length)
|
|
|
* The SSID of the network (variable length)
|
|
|
|
|
|
**3: Wi-Fi Direct** - The device creates a Wi-Fi Direct legacy mode access point and opens a port to accept TCP connections. The record body contains four chunks:
|
|
|
**3: Wi-Fi Direct** - The device creates a Wi-Fi Direct legacy mode access point and opens a port to accept TCP connections. The descriptor contains four fields:
|
|
|
|
|
|
* The device's link-local or site-local IPv4 or IPv6 address (4 or 16 bytes)
|
|
|
* The port number as a 16-bit integer (2 bytes)
|
|
|
* The SSID of the access point (variable length)
|
|
|
* The password of the access point (variable length)
|
|
|
|
|
|
New transports may be defined in future without incrementing the protocol version; devices must ignore any transports they do not recognise. |
|
|
New transports may be defined in future without incrementing the protocol version. Devices must ignore any transports they do not recognise.
|
|
|
|
|
|
### Connection establishment
|
|
|
|
|
|
When a device has scanned a QR code it may immediately connect to the other device over any transports supported by both devices, simultaneously or in any order. This may result in one or more transport connections being established.
|
|
|
|
|
|
If no connections can be established within CONNECTION_TIMEOUT seconds of scanning the QR code, the device aborts the protocol.
|
|
|
|
|
|
The devices are assigned roles according to the lexicographic order of their public key commitments: the device with the earlier commitment takes the role of Alice, while the device with the later commitment takes the role of Bob. If multiple transport connections are established, Alice decides which connection to use and closes any other connections.
|
|
|
|
|
|
> Implementation note: We propose to use CONNECTION_TIMEOUT = 20 seconds.
|
|
|
|
|
|
### Records
|
|
|
|
|
|
Alice and Bob exchange a series of records over the connection chosen by Alice. Each record starts with a four-byte header with the following format:
|
|
|
|
|
|
* Bits 0-7: Protocol version
|
|
|
* Bits 8-15: Record type
|
|
|
* Bits 16-31: Length of the payload in bytes as a 16-bit integer
|
|
|
|
|
|
The current version of the protocol is 1, which has three record types:
|
|
|
|
|
|
**0: KEY** - The payload consists of the sender's ephemeral public key.
|
|
|
|
|
|
**1: CONFIRM** - The payload consists of a message authentication code.
|
|
|
|
|
|
**2: ABORT** - The payload is empty. When a device receives an ABORT record it responds with an ABORT record (unless it has already sent one) and aborts the protocol.
|
|
|
|
|
|
### Key exchange
|
|
|
|
|
|
Alice begins by sending a KEY record containing her ephemeral public key, pub_a. Bob compares HASH("COMMIT", pub_a) to the commitment in Alice's QR code. If the key does not match the commitment, Bob sends an ABORT record and aborts the protocol.
|
|
|
|
|
|
Bob sends a KEY record containing his ephemeral public key, pub_b. Alice compares HASH("COMMIT", pub_b) to the commitment in Bob's QR code. If the key does not match the commitment, Alice sends an ABORT record and aborts the protocol.
|
|
|
|
|
|
Alice and Bob calculate the shared secret as follows:
|
|
|
|
|
|
* Alice calculates `s = HASH("SECRET", DH(pri_a, pub_b), pub_a, pub_b)`
|
|
|
* Bob calculates `s = HASH("SECRET", DH(pri_b, pub_a), pub_a, pub_b)`
|
|
|
|
|
|
If the adversary has not modified the KEY records, both devices should calculate the same shared secret.
|
|
|
|
|
|
### Confirmation
|
|
|
|
|
|
Each device knows it has calculated the correct shared secret because it has compared the received public key to the commitment in the QR code. However, each device also needs to know that the other device has calculated the correct shared secret. To confirm this, both devices derive a confirmation key from the shared secret and use it to calculate two message authentication codes over the payloads of the QR codes, q_a and q_b, and the public keys, pub_a and pub_b:
|
|
|
|
|
|
* k_c = KDF(s, "CONFIRMATION_KEY")
|
|
|
* sent_a = len(q_a) || q_a || len(pub_a) || pub_a
|
|
|
* sent_b = len(q_b) || q_b || len(pub_b) || pub_b
|
|
|
* mac_a = MAC(k_c, sent_a || sent_b)
|
|
|
* mac_b = MAC(k_c, sent_b || sent_a)
|
|
|
|
|
|
Alice sends a CONFIRM record containing mac_a. Bob compares the received mac_a to the mac_a he calculated. If the codes do not match, Bob sends an ABORT record and aborts the protocol.
|
|
|
|
|
|
Bob sends a CONFIRM record containing mac_b. Alice compares the received mac_b to the mac_b she calculated. If the codes do not match, Alice sends an ABORT record and aborts the protocol.
|
|
|
|
|
|
### Securing the channel
|
|
|
|
|
|
Finally, the devices upgrade the insecure channel to a secure channel by deriving two keys from the shared secret:
|
|
|
|
|
|
* k_a = KDF(s, "ALICE_STREAM_KEY")
|
|
|
* k_b = KDF(s, "BOB_STREAM_KEY")
|
|
|
|
|
|
Alice uses k_a to encrypt and authenticate a [BTP] stream to Bob over one side of the transport connection, and Bob uses k_b to encrypt and authenticate a BTP stream to Alice over the other side of the connection. The streams do not have pseudo-random tags or stream headers: each stream just consists of one or more BTP frames. |