Skip to content

Commit 0aa2e87

Browse files
committed
Handle remote DHKey confirmation before own DHKey
1 parent 7ecf299 commit 0aa2e87

File tree

3 files changed

+83
-4
lines changed

3 files changed

+83
-4
lines changed

src/utility/HCI.cpp

+72-2
Original file line numberDiff line numberDiff line change
@@ -1345,13 +1345,83 @@ void HCIClass::handleEventPkt(uint8_t /*plen*/, uint8_t pdata[])
13451345
#endif
13461346
encryption |= PEER_ENCRYPTION::DH_KEY_CALULATED;
13471347
ATT.setPeerEncryption(connectionHandle, encryption);
1348+
1349+
if((encryption & PEER_ENCRYPTION::RECEIVED_DH_CHECK) > 0){
1350+
#ifdef _BLE_TRACE_
1351+
Serial.println("Recieved DHKey check already so calculate f5, f6 now.");
1352+
#endif
1353+
1354+
uint8_t BD_ADDR_REMOTE[7];
1355+
ATT.getPeerAddrWithType(connectionHandle, BD_ADDR_REMOTE);
1356+
1357+
1358+
uint8_t MacKey[16];
1359+
uint8_t localAddress[7];
1360+
1361+
memcpy(&localAddress[1],HCI.localAddr,6);
1362+
localAddress[0] = 0; // IOT 33 uses a static address
1363+
1364+
btct.f5(HCI.DHKey,HCI.Na,HCI.Nb,BD_ADDR_REMOTE,localAddress,MacKey,HCI.LTK);
1365+
1366+
uint8_t Ea[16];
1367+
uint8_t Eb[16];
1368+
uint8_t R[16];
1369+
uint8_t MasterIOCap[3];
1370+
uint8_t SlaveIOCap[3] = {LOCAL_AUTHREQ, 0x0, LOCAL_IOCAP};
1371+
1372+
ATT.getPeerIOCap(connectionHandle, MasterIOCap);
1373+
for(int i=0; i<16; i++) R[i] = 0;
1374+
1375+
btct.f6(MacKey, HCI.Na,HCI.Nb,R, MasterIOCap, BD_ADDR_REMOTE, localAddress, Ea);
1376+
btct.f6(MacKey, HCI.Nb,HCI.Na,R, SlaveIOCap, localAddress, BD_ADDR_REMOTE, Eb);
1377+
1378+
13481379
#ifdef _BLE_TRACE_
1349-
if(encryption | PEER_ENCRYPTION::RECEIVED_DH_CHECK){
1350-
Serial.println("Recieved DHKey check already so calculate f5, f6.");
1380+
Serial.println("Calculate f5, f6:");
1381+
Serial.print("DH : ");
1382+
btct.printBytes(HCI.DHKey,32);
1383+
Serial.print("Na : ");
1384+
btct.printBytes(HCI.Na,16);
1385+
Serial.print("Nb : ");
1386+
btct.printBytes(HCI.Nb,16);
1387+
Serial.print("MAC : ");
1388+
btct.printBytes(MacKey,16);
1389+
// Serial.print("Expected MAC: ");
1390+
// printBytes(EXPECTED_MAC, 16);
1391+
Serial.print("LTK : ");
1392+
btct.printBytes(HCI.LTK,16);
1393+
// Serial.print("Expected LTK: ");
1394+
// printBytes(EXPECTED_LTK, 16);
1395+
Serial.print("Expected Ex : ");
1396+
btct.printBytes(HCI.remoteDHKeyCheckBuffer, 16);
1397+
Serial.print("Ea : ");
1398+
btct.printBytes(Ea, 16);
1399+
Serial.print("Eb : ");
1400+
btct.printBytes(Eb,16);
1401+
Serial.print("Local Addr : ");
1402+
btct.printBytes(localAddress, 7);
1403+
Serial.print("LocalIOCap : ");
1404+
btct.printBytes(SlaveIOCap, 3);
1405+
Serial.print("MasterAddr : ");
1406+
btct.printBytes(BD_ADDR_REMOTE, 7);
1407+
Serial.print("MasterIOCAP : ");
1408+
btct.printBytes(MasterIOCap, 3);
1409+
Serial.println("Send Eb Back.");
1410+
#endif
1411+
uint8_t ret[17];
1412+
ret[0] = 0x0d;
1413+
for(int i=0; i<sizeof(Eb); i++){
1414+
ret[sizeof(Eb)-i] = Eb[i];
1415+
}
1416+
HCI.sendAclPkt(connectionHandle, 0x06, sizeof(ret), ret );
1417+
ATT.setPeerEncryption(connectionHandle, encryption | PEER_ENCRYPTION::SENT_DH_CHECK);
13511418
}else{
1419+
#ifdef _BLE_TRACE_
13521420
Serial.println("Waiting on other DHKey check before calculating.");
1421+
#endif
13531422
}
13541423
}else{
1424+
#ifdef _BLE_TRACE_
13551425
Serial.print("Key generation error: 0x");
13561426
Serial.println(evtLeDHKeyComplete->status, HEX);
13571427
#endif

src/utility/HCI.h

+1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ class HCIClass {
111111
// TODO: Send command be private again & use ATT implementation within ATT.
112112
virtual int sendCommand(uint16_t opcode, uint8_t plen = 0, void* parameters = NULL);
113113
uint8_t remotePublicKeyBuffer[64];
114+
uint8_t remoteDHKeyCheckBuffer[16];
114115
uint8_t Na[16];
115116
uint8_t Nb[16];
116117
uint8_t DHKey[32];

src/utility/L2CAPSignaling.cpp

+10-2
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,14 @@ void L2CAPSignalingClass::handleSecurityData(uint16_t connectionHandle, uint8_t
290290

291291
HCI.readBdAddr();
292292
ATT.setPeerEncryption(connectionHandle, encryptionState);
293-
if((encryptionState & PEER_ENCRYPTION::DH_KEY_CALULATED) > 0){
293+
if((encryptionState & PEER_ENCRYPTION::DH_KEY_CALULATED) == 0){
294+
#ifdef _BLE_TRACE_
295+
Serial.println("DHKey not yet ready, will calculate f5, f6 later");
296+
#endif
297+
// store RemoteDHKeyCheck for later check
298+
memcpy(HCI.remoteDHKeyCheckBuffer,RemoteDHKeyCheck,16);
299+
300+
} else {
294301
// We've already calculated the DHKey so we can calculate our check and send it.
295302

296303
uint8_t MacKey[16];
@@ -312,7 +319,7 @@ void L2CAPSignalingClass::handleSecurityData(uint16_t connectionHandle, uint8_t
312319

313320
btct.f6(MacKey, HCI.Na,HCI.Nb,R, MasterIOCap, BD_ADDR_REMOTE, localAddress, Ea);
314321
btct.f6(MacKey, HCI.Nb,HCI.Na,R, SlaveIOCap, localAddress, BD_ADDR_REMOTE, Eb);
315-
322+
316323

317324
#ifdef _BLE_TRACE_
318325
Serial.println("Calculate f5, f6:");
@@ -353,6 +360,7 @@ void L2CAPSignalingClass::handleSecurityData(uint16_t connectionHandle, uint8_t
353360
ret[sizeof(Eb)-i] = Eb[i];
354361
}
355362
HCI.sendAclPkt(connectionHandle, 0x06, sizeof(ret), ret );
363+
ATT.setPeerEncryption(connectionHandle, encryptionState | PEER_ENCRYPTION::SENT_DH_CHECK);
356364
}
357365
}
358366
}

0 commit comments

Comments
 (0)