Using shared secret as Out-Of-Band authentication data in Bluetooth pairing

According to the Bluetooth Specification, the pairing process starts with Slave sending a connectable advertising packet and then the Master initiates the connection. In LE Legacy OOB authentication a secret 128-bit Temporary Key (TK) is supposed to be shared via some other secure channel, e.g. NFC, to be used in a challenge-response authentication, which goes like this:

1. Master chooses random Mrand and calculates Mconfirm = AES(TK, AES(TK, Mrand XOR p1) XOR p2)
2. Slave chooses random Srand and calculates Sconfirm = AES(TK, AES(TK, Srand XOR p1) XOR p2)
3. Master sends Mconfirm
4. Slave sends Sconfirm
5. Master sends Mrand and Slave confirms
6. Slave sends Srand and Master confirms
7. Short Term Key is calculated as STK = AES(TK, Srand[65:128] || Mrand[65:128])
8. Further communication is encrypted with STK.

where p1 and p2 contains the addresses of Master and Slave along with some information about the pairing command, etc.

Now suppose Master and Slave share a secret key (SK) which is burned into them at factory. I intend to send a 128-bit random data (RD) in the advertising package so both sides can use it to calculate TK as TK = AES(SK, RD). I haven't seen this approach anywhere else and there is very little literature on the analysis of LE Legacy OOB authentication as far as I can see.

So, is this a valid approach? What are the problems with it?

Other related information and assumptions:

1. The payload of the connectable advertising packet is already encrypted and authenticated via CCM using another key along with replay protection via counter and/or timestamp.
2. There are many master and slaves where masters are at fixed locations and slaves are mobile. Each slave has a unique SK and masters can look it up from a secure database.
3. Bonding cannot be used because there should be no user interaction for authentication and the bonding keys cannot be shared between masters.
4. LE Secure Connections is supposed to be more secure but requires user interaction for authentication, which we cannot provide.
5. Connection will be made every 1-10 minutes for each slave.

This doesn't strike me as a very good authentication protocol. You can view $$(Mrand, \textsf{AES}_{TK}(\textsf{AES}_{TK}(Mrand \oplus p_1) \oplus p_2))$$ as an attempt of a randomized CBC-MAC of $$p_1\|p_2$$, with $$Mrand$$ being the initialization vector.

Unfortunately, randomized CBC-MAC is completely broken as a MAC. Suppose an adversary sees a valid MAC $$(R,T) = \bigl(R, \textsf{AES}_K(\textsf{AES}_K(R \oplus p_1) \oplus p_2)\bigr)$$ of a message $$p_1 \| p_2$$. Then it can produce $$(R \oplus \delta, T)$$ which is a valid MAC of message $$(p_1 \oplus \delta) \| p_2$$.

Apart from the poor attempt at a MAC, this protocol suffers from trivial replay attacks. Each party chooses a random value that affects only their own messages. To prevent replay, each party should bind their protocol messages to a random value chosen by the other party.

There is even a reflection attack. In this protocol if the master sends $$Mrand, Mconfirm$$ then the client can echo back $$Srand=Mrand$$ and $$Sconfirm=Mconfirm$$, which should verify correctly unless there is more to the protocol than you mention.

The result of these attacks is that one endpoint believes that it is successfully paired, despite the other endpoint not knowing the out-of-band key $$TK$$. The attacker cannot derive the session key, though.

• Thanks for the answer. I have checked again what p1 and p2 consists of. It turns out p1 only contains the connection parameters, which should be constant among all connections. So, we can ignore any connection attempt if p1 is different than expected. p2 includes both master and slave addresses. Is this enough to prevent randomized CBC-MAC issue? Jul 28, 2021 at 7:54
• TK changes for every session according to the random value provided by the slave in the advertisement package and a shared secret key which was provided at manufacturing time. I guess it prevents replay attacks? Jul 28, 2021 at 7:56
• I guess reflection attack can be prevented by checking $Sconfirm \neq Mconfirm$ or $Srand \neq Mrand$? I hope this is implemented by the stack provider. I can request a patch if it is not implemented. Jul 28, 2021 at 7:58