|
23 | 23 | #include "L2CAPSignaling.h"
|
24 | 24 | #include "btct.h"
|
25 | 25 | #include "HCI.h"
|
| 26 | +#include "bitDescriptions.h" |
| 27 | +// #define _BLE_TRACE_ |
26 | 28 |
|
27 | 29 | //#define _BLE_TRACE_
|
28 | 30 |
|
@@ -1141,50 +1143,63 @@ void HCIClass::handleEventPkt(uint8_t /*plen*/, uint8_t pdata[])
|
1141 | 1143 | // Load our LTK for this connection.
|
1142 | 1144 | uint8_t peerAddr[7];
|
1143 | 1145 | uint8_t resolvableAddr[6];
|
| 1146 | + uint8_t foundLTK; |
1144 | 1147 | ATT.getPeerAddrWithType(ltkRequest->connectionHandle, peerAddr);
|
1145 | 1148 |
|
1146 |
| - if(ATT.getPeerResolvedAddress(ltkRequest->connectionHandle, resolvableAddr) |
1147 |
| - && !((ATT.getPeerEncryption(ltkRequest->connectionHandle) & PEER_ENCRYPTION::PAIRING_REQUEST)>0)){ |
1148 |
| - _getLTK(resolvableAddr, HCI.LTK); |
| 1149 | + if((ATT.getPeerEncryption(ltkRequest->connectionHandle) & PEER_ENCRYPTION::PAIRING_REQUEST)>0){ |
| 1150 | + // Pairing request - LTK is one in buffer already |
| 1151 | + foundLTK = 1; |
1149 | 1152 | }else{
|
1150 |
| - _getLTK(&peerAddr[1], HCI.LTK); |
| 1153 | + if(ATT.getPeerResolvedAddress(ltkRequest->connectionHandle, resolvableAddr)){ |
| 1154 | + foundLTK = getLTK(resolvableAddr, HCI.LTK); |
| 1155 | + }else{ |
| 1156 | + foundLTK = getLTK(&peerAddr[1], HCI.LTK); |
| 1157 | + } |
1151 | 1158 | }
|
1152 |
| - // } |
| 1159 | + // } //2d |
1153 | 1160 | // Send our LTK back
|
1154 |
| - struct __attribute__ ((packed)) LTKReply |
1155 |
| - { |
1156 |
| - uint16_t connectionHandle; |
1157 |
| - uint8_t LTK[16]; |
1158 |
| - } ltkReply = {0,0}; |
1159 |
| - ltkReply.connectionHandle = ltkRequest->connectionHandle; |
1160 |
| - for(int i=0; i<16; i++) ltkReply.LTK[15-i] = HCI.LTK[i]; |
1161 |
| - int result = sendCommand(OGF_LE_CTL << 10 | LE_COMMAND::LONG_TERM_KEY_REPLY,sizeof(ltkReply), <kReply); |
1162 |
| - |
1163 |
| -#ifdef _BLE_TRACE_ |
1164 |
| - Serial.println("Sending LTK as: "); |
1165 |
| - btct.printBytes(ltkReply.LTK,16); |
1166 |
| -#endif |
1167 |
| - |
1168 |
| - if(result == 0){ |
1169 |
| - struct __attribute__ ((packed)) LTKReplyResult |
| 1161 | + if(foundLTK){ |
| 1162 | + struct __attribute__ ((packed)) LTKReply |
1170 | 1163 | {
|
1171 |
| - uint8_t status; |
1172 | 1164 | uint16_t connectionHandle;
|
1173 |
| - } ltkReplyResult = {0,0}; |
1174 |
| - memcpy(<kReplyResult, _cmdResponse, 3); |
1175 |
| - |
1176 |
| -#ifdef _BLE_TRACE_ |
1177 |
| - Serial.println("LTK send success"); |
1178 |
| - Serial.print("status : "); |
1179 |
| - btct.printBytes(<kReplyResult.status,1); |
1180 |
| - Serial.print("Conn Handle: "); |
1181 |
| - btct.printBytes((uint8_t*)<kReplyResult.connectionHandle,2); |
1182 |
| -#endif |
| 1165 | + uint8_t LTK[16]; |
| 1166 | + } ltkReply = {0,0}; |
| 1167 | + ltkReply.connectionHandle = ltkRequest->connectionHandle; |
| 1168 | + for(int i=0; i<16; i++) ltkReply.LTK[15-i] = HCI.LTK[i]; |
| 1169 | + int result = sendCommand(OGF_LE_CTL << 10 | LE_COMMAND::LONG_TERM_KEY_REPLY,sizeof(ltkReply), <kReply); |
| 1170 | + |
| 1171 | + #ifdef _BLE_TRACE_ |
| 1172 | + Serial.println("Sending LTK as: "); |
| 1173 | + btct.printBytes(ltkReply.LTK,16); |
| 1174 | + #endif |
| 1175 | + |
| 1176 | + if(result == 0){ |
| 1177 | + struct __attribute__ ((packed)) LTKReplyResult |
| 1178 | + { |
| 1179 | + uint8_t status; |
| 1180 | + uint16_t connectionHandle; |
| 1181 | + } ltkReplyResult = {0,0}; |
| 1182 | + memcpy(<kReplyResult, _cmdResponse, 3); |
| 1183 | + |
| 1184 | + #ifdef _BLE_TRACE_ |
| 1185 | + Serial.println("LTK send success"); |
| 1186 | + Serial.print("status : "); |
| 1187 | + btct.printBytes(<kReplyResult.status,1); |
| 1188 | + Serial.print("Conn Handle: "); |
| 1189 | + btct.printBytes((uint8_t*)<kReplyResult.connectionHandle,2); |
| 1190 | + #endif |
| 1191 | + }else{ |
| 1192 | + #ifdef _BLE_TRACE_ |
| 1193 | + Serial.print("Failed to send LTK...: "); |
| 1194 | + btct.printBytes((uint8_t*)&result,2); |
| 1195 | + #endif |
| 1196 | + } |
1183 | 1197 | }else{
|
| 1198 | + /// do LTK rejection |
1184 | 1199 | #ifdef _BLE_TRACE_
|
1185 |
| - Serial.print("Failed to send LTK...: "); |
1186 |
| - btct.printBytes((uint8_t*)&result,2); |
| 1200 | + Serial.println("LTK not found, rejecting"); |
1187 | 1201 | #endif
|
| 1202 | + sendCommand(OGF_LE_CTL << 10 | LE_COMMAND::LONG_TERM_KEY_NEGATIVE_REPLY,2, <kRequest->connectionHandle); |
1188 | 1203 | }
|
1189 | 1204 | break;
|
1190 | 1205 | }
|
@@ -1258,10 +1273,10 @@ void HCIClass::handleEventPkt(uint8_t /*plen*/, uint8_t pdata[])
|
1258 | 1273 |
|
1259 | 1274 |
|
1260 | 1275 | uint8_t Z = 0;
|
1261 |
| - for(int i=0; i<16; i++){ |
1262 |
| - /// TODO: Implement secure random |
1263 |
| - Nb[i] = rand(); //// Should use ESP or ECCx08 |
1264 |
| - } |
| 1276 | + |
| 1277 | + HCI.leRand(Nb); |
| 1278 | + HCI.leRand(&Nb[8]); |
| 1279 | + |
1265 | 1280 | #ifdef _BLE_TRACE_
|
1266 | 1281 | Serial.print("nb: ");
|
1267 | 1282 | btct.printBytes(Nb, 16);
|
@@ -1413,6 +1428,47 @@ int HCIClass::leEncrypt(uint8_t* key, uint8_t* plaintext, uint8_t* status, uint8
|
1413 | 1428 | #endif
|
1414 | 1429 | return res;
|
1415 | 1430 | }
|
| 1431 | +int HCIClass::leRand(uint8_t rand[]){ |
| 1432 | + int res = sendCommand(OGF_LE_CTL << 10 | LE_COMMAND::RANDOM); |
| 1433 | + if(res == 0){ |
| 1434 | + memcpy(rand,_cmdResponse, 8); /// backwards but it's a random number |
| 1435 | + } |
| 1436 | + return res; |
| 1437 | +} |
| 1438 | +int HCIClass::getLTK(uint8_t* address, uint8_t* LTK){ |
| 1439 | + if(_getLTK!=0){ |
| 1440 | + return _getLTK(address, LTK); |
| 1441 | + }else{ |
| 1442 | + return 0; |
| 1443 | + } |
| 1444 | +} |
| 1445 | +int HCIClass::storeIRK(uint8_t* address, uint8_t* IRK){ |
| 1446 | + if(_storeIRK!=0){ |
| 1447 | + return _storeIRK(address, IRK); |
| 1448 | + }else{ |
| 1449 | + return 0; |
| 1450 | + } |
| 1451 | +} |
| 1452 | +int HCIClass::storeLTK(uint8_t* address, uint8_t* LTK){ |
| 1453 | + if(_storeLTK!=0){ |
| 1454 | + return _storeLTK(address, LTK); |
| 1455 | + }else{ |
| 1456 | + return 0; |
| 1457 | + } |
| 1458 | +} |
| 1459 | + |
| 1460 | +/// Stub function to generate parameters for local authreq |
| 1461 | +AuthReq HCIClass::localAuthreq(){ |
| 1462 | + // If get, set, IRK, LTK all set then we can bond. |
| 1463 | + AuthReq local = AuthReq(); |
| 1464 | + if(_storeIRK!=0 && _storeLTK!=0 && _getLTK!=0 && _getIRKs!=0){ |
| 1465 | + local.setBonding(true); |
| 1466 | + } |
| 1467 | + local.setSC(true); |
| 1468 | + local.setMITM(true); |
| 1469 | + local.setCT2(true); |
| 1470 | + return LOCAL_AUTHREQ; |
| 1471 | +} |
1416 | 1472 |
|
1417 | 1473 | void HCIClass::dumpPkt(const char* prefix, uint8_t plen, uint8_t pdata[])
|
1418 | 1474 | {
|
|
0 commit comments