@@ -278,19 +278,18 @@ void L2CAPSignalingClass::handleSecurityData(uint16_t connectionHandle, uint8_t
278
278
else if (code == CONNECTION_PAIRING_DHKEY_CHECK)
279
279
{
280
280
uint8_t RemoteDHKeyCheck[16 ];
281
- uint8_t BD_ADDR_REMOTE[7 ];
282
- ATT.getPeerAddrWithType (connectionHandle, BD_ADDR_REMOTE);
283
281
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
+
286
283
287
284
#ifdef _BLE_TRACE_
288
285
Serial.println (" [Info] DH Key check" );
289
286
Serial.print (" Remote DHKey Check: " );
290
287
btct.printBytes (RemoteDHKeyCheck, 16 );
291
288
#endif
292
289
293
- HCI.readBdAddr ();
290
+
291
+
292
+ uint8_t encryptionState = ATT.getPeerEncryption (connectionHandle) | PEER_ENCRYPTION::RECEIVED_DH_CHECK;
294
293
ATT.setPeerEncryption (connectionHandle, encryptionState);
295
294
if ((encryptionState & PEER_ENCRYPTION::DH_KEY_CALULATED) == 0 ){
296
295
#ifdef _BLE_TRACE_
@@ -301,89 +300,80 @@ void L2CAPSignalingClass::handleSecurityData(uint16_t connectionHandle, uint8_t
301
300
302
301
} else {
303
302
// We've already calculated the DHKey so we can calculate our check and send it.
303
+ smCalculateLTKandConfirm (connectionHandle, RemoteDHKeyCheck);
304
304
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
+ }
310
308
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);
325
336
326
337
#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 );
357
351
#endif
358
352
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);
379
365
#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" );
381
376
#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
- }
387
377
}
388
378
}
389
379
0 commit comments