@@ -278,19 +278,18 @@ void L2CAPSignalingClass::handleSecurityData(uint16_t connectionHandle, uint8_t
278278 else if (code == CONNECTION_PAIRING_DHKEY_CHECK)
279279 {
280280 uint8_t RemoteDHKeyCheck[16 ];
281- uint8_t BD_ADDR_REMOTE[7 ];
282- ATT.getPeerAddrWithType (connectionHandle, BD_ADDR_REMOTE);
283281 for (int i=0 ; i<16 ; i++) RemoteDHKeyCheck[15 -i] = l2capSignalingHdr->data [i];
284- uint8_t encryptionState = ATT.getPeerEncryption (connectionHandle) | PEER_ENCRYPTION::RECEIVED_DH_CHECK;
285-
282+
286283
287284#ifdef _BLE_TRACE_
288285 Serial.println (" [Info] DH Key check" );
289286 Serial.print (" Remote DHKey Check: " );
290287 btct.printBytes (RemoteDHKeyCheck, 16 );
291288#endif
292289
293- HCI.readBdAddr ();
290+
291+
292+ uint8_t encryptionState = ATT.getPeerEncryption (connectionHandle) | PEER_ENCRYPTION::RECEIVED_DH_CHECK;
294293 ATT.setPeerEncryption (connectionHandle, encryptionState);
295294 if ((encryptionState & PEER_ENCRYPTION::DH_KEY_CALULATED) == 0 ){
296295#ifdef _BLE_TRACE_
@@ -301,89 +300,80 @@ void L2CAPSignalingClass::handleSecurityData(uint16_t connectionHandle, uint8_t
301300
302301 } else {
303302 // We've already calculated the DHKey so we can calculate our check and send it.
303+ smCalculateLTKandConfirm (connectionHandle, RemoteDHKeyCheck);
304304
305- uint8_t MacKey[16 ];
306- uint8_t localAddress[7 ];
307-
308- memcpy (&localAddress[1 ],HCI.localAddr ,6 );
309- localAddress[0 ] = 0 ; // IOT 33 uses a static address
305+ }
306+ }
307+ }
310308
311- btct.f5 (HCI.DHKey ,HCI.Na ,HCI.Nb ,BD_ADDR_REMOTE,localAddress,MacKey,HCI.LTK );
312-
313- uint8_t Ea[16 ];
314- uint8_t Eb[16 ];
315- uint8_t R[16 ];
316- uint8_t MasterIOCap[3 ];
317- uint8_t SlaveIOCap[3 ] = {LOCAL_AUTHREQ, 0x0 , LOCAL_IOCAP};
318-
319- ATT.getPeerIOCap (connectionHandle, MasterIOCap);
320- for (int i=0 ; i<16 ; i++) R[i] = 0 ;
321-
322- btct.f6 (MacKey, HCI.Na ,HCI.Nb ,R, MasterIOCap, BD_ADDR_REMOTE, localAddress, Ea);
323- btct.f6 (MacKey, HCI.Nb ,HCI.Na ,R, SlaveIOCap, localAddress, BD_ADDR_REMOTE, Eb);
324-
309+ void L2CAPSignalingClass::smCalculateLTKandConfirm (uint16_t handle, uint8_t expectedEa[])
310+ { // Authentication stage 2: LTK Calculation
311+
312+ uint8_t localAddress[7 ];
313+ uint8_t remoteAddress[7 ];
314+ ATT.getPeerAddrWithType (handle, remoteAddress);
315+
316+ HCI.readBdAddr ();
317+ memcpy (&localAddress[1 ],HCI.localAddr ,6 );
318+ localAddress[0 ] = 0 ; // IOT 33 uses a static address // TODO: confirm for Nano BLE
319+
320+ // Compute the LTK and MacKey
321+ uint8_t MacKey[16 ];
322+ btct.f5 (HCI.DHKey , HCI.Na , HCI.Nb , remoteAddress, localAddress, MacKey, HCI.LTK );
323+
324+ // Compute Ea and Eb
325+ uint8_t Ea[16 ];
326+ uint8_t Eb[16 ];
327+ uint8_t R[16 ];
328+ uint8_t MasterIOCap[3 ];
329+ uint8_t SlaveIOCap[3 ] = {LOCAL_AUTHREQ, 0x0 , LOCAL_IOCAP};
330+
331+ ATT.getPeerIOCap (handle, MasterIOCap);
332+ for (int i=0 ; i<16 ; i++) R[i] = 0 ;
333+
334+ btct.f6 (MacKey, HCI.Na ,HCI.Nb ,R, MasterIOCap, remoteAddress, localAddress, Ea);
335+ btct.f6 (MacKey, HCI.Nb ,HCI.Na ,R, SlaveIOCap, localAddress, remoteAddress, Eb);
325336
326337#ifdef _BLE_TRACE_
327- Serial.println (" Calculate f5, f6:" );
328- Serial.print (" DH : " );
329- btct.printBytes (HCI.DHKey ,32 );
330- Serial.print (" Na : " );
331- btct.printBytes (HCI.Na ,16 );
332- Serial.print (" Nb : " );
333- btct.printBytes (HCI.Nb ,16 );
334- Serial.print (" MAC : " );
335- btct.printBytes (MacKey,16 );
336- // Serial.print("Expected MAC: ");
337- // printBytes(EXPECTED_MAC, 16);
338- Serial.print (" LTK : " );
339- btct.printBytes (HCI.LTK ,16 );
340- // Serial.print("Expected LTK: ");
341- // printBytes(EXPECTED_LTK, 16);
342- Serial.print (" Expected Ex : " );
343- btct.printBytes (RemoteDHKeyCheck, 16 );
344- Serial.print (" Ea : " );
345- btct.printBytes (Ea, 16 );
346- Serial.print (" Eb : " );
347- btct.printBytes (Eb,16 );
348- Serial.print (" Local Addr : " );
349- btct.printBytes (localAddress, 7 );
350- Serial.print (" LocalIOCap : " );
351- btct.printBytes (SlaveIOCap, 3 );
352- Serial.print (" MasterAddr : " );
353- btct.printBytes (BD_ADDR_REMOTE, 7 );
354- Serial.print (" MasterIOCAP : " );
355- btct.printBytes (MasterIOCap, 3 );
356- Serial.println (" Send Eb Back." );
338+ Serial.println (" Calculate and confirm LTK via f5, f6:" );
339+ Serial.print (" DHKey : " ); btct.printBytes (HCI.DHKey ,32 );
340+ Serial.print (" Na : " ); btct.printBytes (HCI.Na ,16 );
341+ Serial.print (" Nb : " ); btct.printBytes (HCI.Nb ,16 );
342+ Serial.print (" MacKey : " ); btct.printBytes (MacKey,16 );
343+ Serial.print (" LTK : " ); btct.printBytes (HCI.LTK ,16 );
344+ Serial.print (" Expected Ea: " ); btct.printBytes (expectedEa, 16 );
345+ Serial.print (" Ea : " ); btct.printBytes (Ea, 16 );
346+ Serial.print (" Eb : " ); btct.printBytes (Eb,16 );
347+ Serial.print (" Local Addr : " ); btct.printBytes (localAddress, 7 );
348+ Serial.print (" LocalIOCap : " ); btct.printBytes (SlaveIOCap, 3 );
349+ Serial.print (" MasterAddr : " ); btct.printBytes (remoteAddress, 7 );
350+ Serial.print (" MasterIOCAP: " ); btct.printBytes (MasterIOCap, 3 );
357351#endif
358352
359- // Check if RemoteDHKeyCheck = Ea
360- bool EaCheck = true ;
361- for (int i = 0 ; i < 16 ; i++){
362- if (Ea[i] != RemoteDHKeyCheck[i]){
363- EaCheck = false ;
364- }
365- }
366-
367- if (EaCheck){
368- // Send our confirmation value to complete authentication stage 2
369- uint8_t ret[17 ];
370- ret[0 ] = CONNECTION_PAIRING_DHKEY_CHECK;
371- for (int i=0 ; i<sizeof (Eb); i++){
372- ret[sizeof (Eb)-i] = Eb[i];
373- }
374- HCI.sendAclPkt (connectionHandle, SECURITY_CID, sizeof (ret), ret );
375- ATT.setPeerEncryption (connectionHandle, encryptionState | PEER_ENCRYPTION::SENT_DH_CHECK);
376-
377- } else {
378- // If check fails, abort
353+ // Check if Ea = expectedEa
354+ if (memcmp (Ea, expectedEa, 16 ) == 0 ){
355+ // Check ok
356+ // Send our confirmation value to complete authentication stage 2
357+ uint8_t ret[17 ];
358+ ret[0 ] = CONNECTION_PAIRING_DHKEY_CHECK;
359+ for (int i=0 ; i<sizeof (Eb); i++){
360+ ret[sizeof (Eb)-i] = Eb[i];
361+ }
362+ HCI.sendAclPkt (handle, SECURITY_CID, sizeof (ret), ret );
363+ uint8_t encryption = ATT.getPeerEncryption (handle) | PEER_ENCRYPTION::SENT_DH_CHECK;
364+ ATT.setPeerEncryption (handle, encryption);
379365#ifdef _BLE_TRACE_
380- Serial.println (" Error: DHKey check failed - Aborting" );
366+ Serial.println (" DHKey check ok - send Eb back" );
367+ #endif
368+
369+ } else {
370+ // Check failed, abort pairing
371+ uint8_t ret[2 ] = {CONNECTION_PAIRING_FAILED, 0x0B }; // 0x0B = DHKey Check Failed
372+ HCI.sendAclPkt (handle, SECURITY_CID, sizeof (ret), ret);
373+ ATT.setPeerEncryption (handle, NO_ENCRYPTION);
374+ #ifdef _BLE_TRACE_
375+ Serial.println (" Error: DHKey check failed - Aborting" );
381376#endif
382- uint8_t ret[2 ] = {CONNECTION_PAIRING_FAILED, 0x0B }; // DHKey Check Faile
383- HCI.sendAclPkt (connectionHandle, SECURITY_CID, sizeof (ret), ret);
384- ATT.setPeerEncryption (connectionHandle, NO_ENCRYPTION);
385- }
386- }
387377 }
388378}
389379
0 commit comments