Skip to content

Commit c7c1458

Browse files
committed
nimble/ll: Add CS Security Start procedure
Implements LE CS Security Enable command.
1 parent e22e675 commit c7c1458

File tree

5 files changed

+155
-2
lines changed

5 files changed

+155
-2
lines changed

nimble/controller/include/controller/ble_ll_cs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ void ble_ll_cs_reset(void);
3333

3434
void ble_ll_cs_capabilities_pdu_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr);
3535
void ble_ll_cs_config_req_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr);
36+
void ble_ll_cs_security_req_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr);
3637

3738
int ble_ll_cs_rx_capabilities_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t *rspbuf);
3839
void ble_ll_cs_rx_capabilities_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr);
@@ -43,6 +44,9 @@ void ble_ll_cs_rx_fae_req_rejected(struct ble_ll_conn_sm *connsm, uint8_t ble_er
4344
int ble_ll_cs_rx_config_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t *rspbuf);
4445
void ble_ll_cs_rx_config_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr);
4546
void ble_ll_cs_rx_config_req_rejected(struct ble_ll_conn_sm *connsm, uint8_t ble_error);
47+
int ble_ll_cs_rx_security_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t *rspbuf);
48+
void ble_ll_cs_rx_security_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr);
49+
void ble_ll_cs_rx_security_req_rejected(struct ble_ll_conn_sm *connsm, uint8_t ble_error);
4650

4751
/* HCI handlers */
4852
int ble_ll_cs_hci_rd_loc_supp_cap(uint8_t *rspbuf, uint8_t *rsplen);

nimble/controller/include/controller/ble_ll_ctrl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ extern "C" {
4646
#define BLE_LL_CTRL_PROC_CS_CAP_XCHG (14)
4747
#define BLE_LL_CTRL_PROC_CS_FAE_REQ (15)
4848
#define BLE_LL_CTRL_PROC_CS_CONF (16)
49-
#define BLE_LL_CTRL_PROC_NUM (17)
49+
#define BLE_LL_CTRL_PROC_CS_SEC_START (17)
50+
#define BLE_LL_CTRL_PROC_NUM (18)
5051
#define BLE_LL_CTRL_PROC_IDLE (255)
5152

5253
/* Checks if a particular control procedure is running */

nimble/controller/src/ble_ll_cs.c

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,10 +360,136 @@ ble_ll_cs_hci_wr_cached_rem_supp_cap(const uint8_t *cmdbuf, uint8_t cmdlen,
360360
return BLE_ERR_SUCCESS;
361361
}
362362

363+
int
364+
ble_ll_cs_rx_security_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
365+
uint8_t *rspbuf)
366+
{
367+
uint8_t *iv = connsm->cssm->drbg_ctx.iv;
368+
uint8_t *in = connsm->cssm->drbg_ctx.in;
369+
uint8_t *pv = connsm->cssm->drbg_ctx.pv;
370+
371+
if (!connsm->flags.encrypted) {
372+
ble_ll_ctrl_rej_ext_ind_make(BLE_LL_CTRL_CS_SEC_REQ,
373+
BLE_ERR_INSUFFICIENT_SEC, rspbuf);
374+
return BLE_LL_CTRL_REJECT_IND_EXT;
375+
}
376+
377+
/* Vectors concatenation is done in the follwing manner:
378+
* CS_IV = CS_IV_P || CS_IV_C
379+
* The CS_IV_C is concatenated with the CS_IV_P. The least significant
380+
* octet of CS_IV_C becomes the least significant octet of CS_IV. The most
381+
* significant octet of CS_IV_P becomes the most significant octet of CS_IV.
382+
*/
383+
384+
/* Save Central's vector */
385+
memcpy(iv, dptr, 8);
386+
memcpy(in, dptr + 8, 4);
387+
memcpy(pv, dptr + 12, 8);
388+
389+
/* Generate Peripheral's vector */
390+
ble_ll_rand_data_get(iv + 8, 8);
391+
ble_ll_rand_data_get(in + 4, 4);
392+
ble_ll_rand_data_get(pv + 8, 8);
393+
394+
memcpy(rspbuf, iv + 8, 8);
395+
memcpy(rspbuf + 8, in + 4, 4);
396+
memcpy(rspbuf + 12, pv + 8, 8);
397+
398+
ble_ll_cs_drbg_init(&connsm->cssm->drbg_ctx);
399+
400+
return BLE_LL_CTRL_CS_SEC_RSP;
401+
}
402+
403+
static void
404+
ble_ll_cs_ev_sec_enable_complete(struct ble_ll_conn_sm *connsm, uint8_t status)
405+
{
406+
struct ble_hci_ev_le_subev_cs_sec_enable_complete *ev;
407+
struct ble_hci_ev *hci_ev;
408+
409+
if (ble_ll_hci_is_le_event_enabled(
410+
BLE_HCI_LE_SUBEV_CS_SEC_ENABLE_COMPLETE)) {
411+
hci_ev = ble_transport_alloc_evt(0);
412+
if (hci_ev) {
413+
hci_ev->opcode = BLE_HCI_EVCODE_LE_META;
414+
hci_ev->length = sizeof(*ev);
415+
ev = (void *) hci_ev->data;
416+
417+
ev->subev_code = BLE_HCI_LE_SUBEV_CS_SEC_ENABLE_COMPLETE;
418+
ev->status = status;
419+
ev->conn_handle = htole16(connsm->conn_handle);
420+
421+
ble_ll_hci_event_send(hci_ev);
422+
}
423+
}
424+
}
425+
426+
void
427+
ble_ll_cs_rx_security_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr)
428+
{
429+
int rc = 0;
430+
struct ble_ll_cs_drbg_ctx *drbg_ctx = &connsm->cssm->drbg_ctx;
431+
432+
if (!IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CS_SEC_START)) {
433+
/* Ignore */
434+
return;
435+
}
436+
437+
/* Save Peripheral's vector */
438+
memcpy(drbg_ctx->iv + 8, dptr, 8);
439+
memcpy(drbg_ctx->in + 4, dptr + 8, 4);
440+
memcpy(drbg_ctx->pv + 8, dptr + 12, 8);
441+
442+
rc = ble_ll_cs_drbg_init(drbg_ctx);
443+
444+
/* Stop the control procedure and send an event to the host */
445+
ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CS_SEC_START);
446+
ble_ll_cs_ev_sec_enable_complete(connsm, rc ? BLE_ERR_INV_LMP_LL_PARM :
447+
BLE_ERR_SUCCESS);
448+
}
449+
450+
void
451+
ble_ll_cs_rx_security_req_rejected(struct ble_ll_conn_sm *connsm, uint8_t ble_error)
452+
{
453+
/* Stop the control procedure and send an event to the host */
454+
ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CS_SEC_START);
455+
ble_ll_cs_ev_sec_enable_complete(connsm, ble_error);
456+
}
457+
458+
void
459+
ble_ll_cs_security_req_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr)
460+
{
461+
uint8_t *iv = connsm->cssm->drbg_ctx.iv;
462+
uint8_t *in = connsm->cssm->drbg_ctx.in;
463+
uint8_t *pv = connsm->cssm->drbg_ctx.pv;
464+
465+
/* Generate Central's vector */
466+
ble_ll_rand_data_get(iv, 8);
467+
ble_ll_rand_data_get(in, 4);
468+
ble_ll_rand_data_get(pv, 8);
469+
470+
memcpy(dptr, iv, 8);
471+
memcpy(dptr + 8, in, 4);
472+
memcpy(dptr + 12, pv, 8);
473+
}
474+
363475
int
364476
ble_ll_cs_hci_sec_enable(const uint8_t *cmdbuf, uint8_t cmdlen)
365477
{
366-
return BLE_ERR_UNSUPPORTED;
478+
const struct ble_hci_le_cs_sec_enable_cp *cmd = (const void *)cmdbuf;
479+
struct ble_ll_conn_sm *connsm;
480+
481+
connsm = ble_ll_conn_find_by_handle(le16toh(cmd->conn_handle));
482+
if (!connsm) {
483+
return BLE_ERR_UNK_CONN_ID;
484+
}
485+
486+
if (!connsm->flags.encrypted) {
487+
return BLE_ERR_INSUFFICIENT_SEC;
488+
}
489+
490+
ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_CS_SEC_START, NULL);
491+
492+
return BLE_ERR_SUCCESS;
367493
}
368494

369495
int

nimble/controller/src/ble_ll_cs_priv.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ struct ble_ll_cs_sm {
114114
uint8_t config_req_id;
115115
uint8_t config_req_action;
116116
struct ble_ll_cs_config tmp_config;
117+
118+
/* DRBG context, initialized onece per LE Connection */
119+
struct ble_ll_cs_drbg_ctx drbg_ctx;
117120
};
118121

119122
#ifdef __cplusplus

nimble/controller/src/ble_ll_ctrl.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2070,6 +2070,9 @@ ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
20702070
case BLE_LL_CTRL_PROC_CS_CONF:
20712071
ble_ll_cs_rx_config_req_rejected(connsm, ble_error);
20722072
break;
2073+
case BLE_LL_CTRL_PROC_CS_SEC_START:
2074+
ble_ll_cs_rx_security_req_rejected(connsm, ble_error);
2075+
break;
20732076
#endif
20742077

20752078
default:
@@ -2607,6 +2610,12 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc, void *data)
26072610
opcode = BLE_LL_CTRL_CS_CONFIG_REQ;
26082611
ble_ll_cs_config_req_make(connsm, ctrdata);
26092612
break;
2613+
#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL)
2614+
case BLE_LL_CTRL_PROC_CS_SEC_START:
2615+
opcode = BLE_LL_CTRL_CS_SEC_REQ;
2616+
ble_ll_cs_security_req_make(connsm, ctrdata);
2617+
break;
2618+
#endif
26102619
#endif
26112620
default:
26122621
BLE_LL_ASSERT(0);
@@ -3097,6 +3106,16 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
30973106
case BLE_LL_CTRL_CS_CONFIG_RSP:
30983107
ble_ll_cs_rx_config_rsp(connsm, dptr);
30993108
break;
3109+
#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
3110+
case BLE_LL_CTRL_CS_SEC_REQ:
3111+
rsp_opcode = ble_ll_cs_rx_security_req(connsm, dptr, rspdata);
3112+
break;
3113+
#endif
3114+
#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL)
3115+
case BLE_LL_CTRL_CS_SEC_RSP:
3116+
ble_ll_cs_rx_security_rsp(connsm, dptr);
3117+
break;
3118+
#endif
31003119
#endif
31013120
default:
31023121
/* Nothing to do here */

0 commit comments

Comments
 (0)