void smprActSendPairRandom(smpCcb_t *pCcb, smpMsg_t *pMsg) { uint8_t *pPkt; uint8_t *p; uint8_t encKeyLen; /* get max STK length */ encKeyLen = (pCcb->pairReq[SMP_MAXKEY_POS] < pCcb->pairRsp[SMP_MAXKEY_POS]) ? pCcb->pairReq[SMP_MAXKEY_POS] : pCcb->pairRsp[SMP_MAXKEY_POS]; /* store STK and adjust based on max key length */ memcpy(pCcb->pScr->buf.b3, pMsg->aes.pCiphertext, encKeyLen); memset((pCcb->pScr->buf.b3 + encKeyLen), 0, (SMP_KEY_LEN - encKeyLen)); /* start smp response timer */ smpStartRspTimer(pCcb); /* allocate packet buffer and send pairing random packet */ if ((pPkt = smpMsgAlloc(SMP_PAIR_RAND_LEN + L2C_PAYLOAD_START)) != NULL) { /* build packet */ p = pPkt + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, SMP_CMD_PAIR_RAND); memcpy(p, pCcb->pScr->buf.b4, SMP_RAND_LEN); /* send packet */ smpSendPkt(pCcb, pPkt); } }
void smpSendPairingFailed(smpCcb_t *pCcb, uint8_t reason) { uint8_t *pPacket; uint8_t *p; if ((pPacket = smpMsgAlloc(L2C_PAYLOAD_START + SMP_PAIR_FAIL_LEN)) != NULL) { p = pPacket + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, SMP_CMD_PAIR_FAIL); UINT8_TO_BSTREAM(p, reason); smpSendPkt(pCcb, pPacket); } }
void smprActSendPairRsp(smpCcb_t *pCcb, smpMsg_t *pMsg) { uint8_t *pPkt; uint8_t *p; uint8_t oob; uint8_t display; /* build packet to pairing response buffer in ccb */ p = pCcb->pairRsp; UINT8_TO_BSTREAM(p, SMP_CMD_PAIR_RSP); UINT8_TO_BSTREAM(p, pSmpCfg->ioCap); UINT8_TO_BSTREAM(p, pMsg->dm.pair.oob); UINT8_TO_BSTREAM(p, pMsg->dm.pair.auth); UINT8_TO_BSTREAM(p, pSmpCfg->maxKeyLen); UINT8_TO_BSTREAM(p, pMsg->dm.pair.iKeyDist); UINT8_TO_BSTREAM(p, pMsg->dm.pair.rKeyDist); /* process pairing request and response data */ if (smpCb.procPairing(pCcb, &oob, &display)) { /* set next expected packet */ if ((pCcb->pairReq[SMP_AUTHREQ_POS] & pMsg->dm.pair.auth & SMP_AUTH_SC_FLAG) == SMP_AUTH_SC_FLAG) { pCcb->nextCmdCode = SMP_CMD_PUBLIC_KEY; } else { pCcb->nextCmdCode = SMP_CMD_PAIR_CNF; } /* start smp response timer */ smpStartRspTimer(pCcb); /* send pairing response; allocate packet buffer */ if ((pPkt = smpMsgAlloc(SMP_PAIR_RSP_LEN + L2C_PAYLOAD_START)) != NULL) { /* build packet from pairing response buffer */ memcpy(pPkt + L2C_PAYLOAD_START, pCcb->pairRsp, SMP_PAIR_RSP_LEN); /* send packet */ smpSendPkt(pCcb, pPkt); } /* request authentication data */ smpCb.procAuthReq(pCcb, oob, display); } }
void smprActSendSecurityReq(smpCcb_t *pCcb, smpMsg_t *pMsg) { uint8_t *pPkt; uint8_t *p; /* start smp response timer */ smpStartRspTimer(pCcb); /* allocate packet buffer */ if ((pPkt = smpMsgAlloc(SMP_SECURITY_REQ_LEN + L2C_PAYLOAD_START)) != NULL) { /* build packet */ p = pPkt + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, SMP_CMD_SECURITY_REQ); UINT8_TO_BSTREAM(p, pMsg->dm.securityReq.auth); /* send packet */ smpSendPkt(pCcb, pPkt); } }
void smpActSendPairCnf(smpCcb_t *pCcb, smpMsg_t *pMsg) { uint8_t *pPkt; uint8_t *p; /* set next expected packet */ pCcb->nextCmdCode = (pCcb->initiator) ? SMP_CMD_PAIR_CNF : SMP_CMD_PAIR_RAND; /* start smp response timer */ smpStartRspTimer(pCcb); /* allocate packet buffer */ if ((pPkt = smpMsgAlloc(SMP_PAIR_CNF_LEN + L2C_PAYLOAD_START)) != NULL) { /* build packet */ p = pPkt + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, SMP_CMD_PAIR_CNF); memcpy(p, pMsg->aes.pCiphertext, SMP_CONFIRM_LEN); /* send packet */ smpSendPkt(pCcb, pPkt); } }
static void smpL2cCtrlCback(wsfMsgHdr_t *pMsg) { smpCcb_t *pCcb; uint8_t *pPkt; /* get connection control block */ pCcb = smpCcbByConnId((dmConnId_t) pMsg->param); /* verify connection is open */ if (pCcb->connId != DM_CONN_ID_NONE) { /* set flow */ pCcb->flowDisabled = (pMsg->event == L2C_CTRL_FLOW_DISABLE_IND); /* if data flow enabled */ if (!pCcb->flowDisabled) { /* if packet in qeueue */ if (pCcb->pQueued != NULL) { /* send queued packet */ pPkt = pCcb->pQueued; pCcb->pQueued = NULL; smpSendPkt(pCcb, pPkt); } /* if SMP state not idle */ if (!smpStateIdle(pCcb)) { /* trigger send of next key */ pMsg->event = SMP_MSG_INT_SEND_NEXT_KEY; smpSmExecute(pCcb, (smpMsg_t *) pMsg); } } } }
bool_t smpSendKey(smpCcb_t *pCcb, uint8_t keyDist) { uint8_t *pPkt; uint8_t *p; wsfMsgHdr_t *pHdr; if (smpCb.lescSupported && pCcb->pScCcb->lescEnabled && pCcb->lastSentKey == 0) { dmSecKeyIndEvt_t keyInd; /* pass LTK to app via DM */ if (DmConnRole(pCcb->connId) == DM_ROLE_MASTER) { keyInd.type = DM_KEY_PEER_LTK; } else { keyInd.type = DM_KEY_LOCAL_LTK; } keyInd.hdr.event = DM_SEC_KEY_IND; keyInd.hdr.param = pCcb->connId; keyInd.secLevel = smpGetScSecLevel(pCcb); keyInd.keyData.ltk.ediv = 0; memset(keyInd.keyData.ltk.rand, 0, SMP_RAND8_LEN); Calc128Cpy(keyInd.keyData.ltk.key, pCcb->pScCcb->pLtk->ltk_t); DmSmpCbackExec((dmEvt_t *)&keyInd); pCcb->lastSentKey = SMP_CMD_MASTER_ID; } /* check if we're done sending keys */ if ((keyDist == 0) || (keyDist == SMP_KEY_DIST_ENC && pCcb->lastSentKey == SMP_CMD_MASTER_ID) || (keyDist <= (SMP_KEY_DIST_ENC | SMP_KEY_DIST_ID) && pCcb->lastSentKey == SMP_CMD_ID_ADDR_INFO) || (pCcb->lastSentKey == SMP_CMD_SIGN_INFO)) { return TRUE; } /* if flow disabled return */ if (pCcb->flowDisabled) { return FALSE; } /* allocate packet buffer for largest packet size */ if ((pPkt = smpMsgAlloc(SMP_ENC_INFO_LEN + L2C_PAYLOAD_START)) != NULL) { p = pPkt + L2C_PAYLOAD_START; /* determine next key to send */ if (pCcb->lastSentKey == 0 && (keyDist & SMP_KEY_DIST_ENC)) { /* generate LTK, EDIV, and RAND */ smpGenerateLtk(pCcb); /* send first part of LTK */ UINT8_TO_BSTREAM(p, SMP_CMD_ENC_INFO); Calc128Cpy(p, pCcb->pScr->keyInd.keyData.ltk.key); } else if (pCcb->lastSentKey == SMP_CMD_ENC_INFO) { /* send second part of LTK */ UINT8_TO_BSTREAM(p, SMP_CMD_MASTER_ID); UINT16_TO_BSTREAM(p, pCcb->pScr->keyInd.keyData.ltk.ediv); memcpy(p, pCcb->pScr->keyInd.keyData.ltk.rand, SMP_RAND8_LEN); } else if ((keyDist & SMP_KEY_DIST_ID) && (pCcb->lastSentKey == 0 || pCcb->lastSentKey == SMP_CMD_MASTER_ID)) { /* send first part of IRK */ UINT8_TO_BSTREAM(p, SMP_CMD_ID_INFO); Calc128Cpy(p, DmSecGetLocalIrk()); } else if (pCcb->lastSentKey == SMP_CMD_ID_INFO) { /* send second part of IRK */ UINT8_TO_BSTREAM(p, SMP_CMD_ID_ADDR_INFO); UINT8_TO_BSTREAM(p, DM_ADDR_PUBLIC); BDA_TO_BSTREAM(p, HciGetBdAddr()); } else if ((keyDist & SMP_KEY_DIST_SIGN) && (pCcb->lastSentKey == 0 || pCcb->lastSentKey == SMP_CMD_ID_ADDR_INFO || pCcb->lastSentKey == SMP_CMD_MASTER_ID)) { /* send SRK */ UINT8_TO_BSTREAM(p, SMP_CMD_SIGN_INFO); Calc128Cpy(p, DmSecGetLocalCsrk()); } else { /* should never get here */ WsfMsgFree(pPkt); SMP_TRACE_WARN2("smpSendKey unexpected state keyDist:%d lastSentKey:%d", keyDist, pCcb->lastSentKey); return TRUE; } /* set last sent key to command code */ pCcb->lastSentKey = pPkt[L2C_PAYLOAD_START]; /* send command packet */ smpSendPkt(pCcb, pPkt); /* if flow not disabled set up to send next key */ if (!pCcb->flowDisabled) { if ((pHdr = WsfMsgAlloc(sizeof(wsfMsgHdr_t))) != NULL) { pHdr->event = SMP_MSG_INT_SEND_NEXT_KEY; pHdr->param = pCcb->connId; WsfMsgSend(smpCb.handlerId, pHdr); } } } return FALSE; }