@@ -279,10 +279,136 @@ ble_ll_cs_hci_wr_cached_rem_supp_cap(const uint8_t *cmdbuf, uint8_t cmdlen,
279
279
return BLE_ERR_SUCCESS ;
280
280
}
281
281
282
+ static void
283
+ rej_ext_ind_make (uint8_t rej_opcode , uint8_t err , uint8_t * ctrdata )
284
+ {
285
+ ctrdata [0 ] = rej_opcode ;
286
+ ctrdata [1 ] = err ;
287
+ }
288
+
289
+ int
290
+ ble_ll_cs_rx_security_req (struct ble_ll_conn_sm * connsm , uint8_t * dptr ,
291
+ uint8_t * rspbuf )
292
+ {
293
+ uint8_t * iv = connsm -> cssm -> drbg_ctx .iv ;
294
+ uint8_t * in = connsm -> cssm -> drbg_ctx .in ;
295
+ uint8_t * pv = connsm -> cssm -> drbg_ctx .pv ;
296
+
297
+ if (!connsm -> flags .encrypted ) {
298
+ rej_ext_ind_make (BLE_LL_CTRL_CS_SEC_REQ , BLE_ERR_INSUFFICIENT_SEC ,
299
+ rspbuf );
300
+
301
+ return BLE_LL_CTRL_REJECT_IND_EXT ;
302
+ }
303
+
304
+ /* Vectors concatenation is done in the follwing manner:
305
+ * CS_IV = CS_IV_P || CS_IV_C
306
+ * The CS_IV_C is concatenated with the CS_IV_P. The least significant
307
+ * octet of CS_IV_C becomes the least significant octet of CS_IV. The most
308
+ * significant octet of CS_IV_P becomes the most significant octet of CS_IV.
309
+ */
310
+
311
+ /* Save Central's vector */
312
+ memcpy (iv , dptr , 8 );
313
+ memcpy (in , dptr + 8 , 4 );
314
+ memcpy (pv , dptr + 12 , 8 );
315
+
316
+ /* Generate Peripheral's vector */
317
+ ble_ll_rand_data_get (iv + 8 , 8 );
318
+ ble_ll_rand_data_get (in + 4 , 4 );
319
+ ble_ll_rand_data_get (pv + 8 , 8 );
320
+
321
+ memcpy (rspbuf , iv + 8 , 8 );
322
+ memcpy (rspbuf + 8 , in + 4 , 4 );
323
+ memcpy (rspbuf + 12 , pv + 8 , 8 );
324
+
325
+ ble_ll_cs_drbg_init (& connsm -> cssm -> drbg_ctx );
326
+
327
+ return BLE_LL_CTRL_CS_SEC_RSP ;
328
+ }
329
+
330
+ static void
331
+ ble_ll_cs_ev_sec_enable_complete (struct ble_ll_conn_sm * connsm , uint8_t status )
332
+ {
333
+ struct ble_hci_ev_le_subev_cs_sec_enable_complete * ev ;
334
+ struct ble_hci_ev * hci_ev ;
335
+
336
+ if (ble_ll_hci_is_le_event_enabled (
337
+ BLE_HCI_LE_SUBEV_CS_SEC_ENABLE_COMPLETE )) {
338
+ hci_ev = ble_transport_alloc_evt (0 );
339
+ if (hci_ev ) {
340
+ hci_ev -> opcode = BLE_HCI_EVCODE_LE_META ;
341
+ hci_ev -> length = sizeof (* ev );
342
+ ev = (void * ) hci_ev -> data ;
343
+
344
+ ev -> subev_code = BLE_HCI_LE_SUBEV_CS_SEC_ENABLE_COMPLETE ;
345
+ ev -> status = status ;
346
+ ev -> conn_handle = htole16 (connsm -> conn_handle );
347
+
348
+ ble_ll_hci_event_send (hci_ev );
349
+ }
350
+ }
351
+ }
352
+
353
+ void
354
+ ble_ll_cs_rx_security_rsp (struct ble_ll_conn_sm * connsm , uint8_t * dptr )
355
+ {
356
+ int rc = 0 ;
357
+ struct ble_ll_cs_drbg_ctx * drbg_ctx = & connsm -> cssm -> drbg_ctx ;
358
+
359
+ if (!IS_PENDING_CTRL_PROC (connsm , BLE_LL_CTRL_PROC_CS_SEC_START )) {
360
+ /* Should never happen */
361
+ return ;
362
+ }
363
+
364
+ /* Save Peripheral's vector */
365
+ memcpy (drbg_ctx -> iv + 8 , dptr , 8 );
366
+ memcpy (drbg_ctx -> in + 4 , dptr + 8 , 4 );
367
+ memcpy (drbg_ctx -> pv + 8 , dptr + 12 , 8 );
368
+
369
+ rc = ble_ll_cs_drbg_init (drbg_ctx );
370
+
371
+ /* Stop the control procedure and send an event to the host */
372
+ ble_ll_ctrl_proc_stop (connsm , BLE_LL_CTRL_PROC_CS_SEC_START );
373
+ ble_ll_cs_ev_sec_enable_complete (connsm , rc ? BLE_ERR_INV_LMP_LL_PARM :
374
+ BLE_ERR_SUCCESS );
375
+ }
376
+
377
+ void
378
+ ble_ll_cs_security_req_make (struct ble_ll_conn_sm * connsm , uint8_t * dptr )
379
+ {
380
+ uint8_t * iv = connsm -> cssm -> drbg_ctx .iv ;
381
+ uint8_t * in = connsm -> cssm -> drbg_ctx .in ;
382
+ uint8_t * pv = connsm -> cssm -> drbg_ctx .pv ;
383
+
384
+ /* Generate Central's vector */
385
+ ble_ll_rand_data_get (iv , 8 );
386
+ ble_ll_rand_data_get (in , 4 );
387
+ ble_ll_rand_data_get (pv , 8 );
388
+
389
+ memcpy (dptr , iv , 8 );
390
+ memcpy (dptr + 8 , in , 4 );
391
+ memcpy (dptr + 12 , pv , 8 );
392
+ }
393
+
282
394
int
283
395
ble_ll_cs_hci_sec_enable (const uint8_t * cmdbuf , uint8_t cmdlen )
284
396
{
285
- return BLE_ERR_UNSUPPORTED ;
397
+ const struct ble_hci_le_cs_sec_enable_cp * cmd = (const void * )cmdbuf ;
398
+ struct ble_ll_conn_sm * connsm ;
399
+
400
+ connsm = ble_ll_conn_find_by_handle (le16toh (cmd -> conn_handle ));
401
+ if (!connsm ) {
402
+ return BLE_ERR_UNK_CONN_ID ;
403
+ }
404
+
405
+ if (!connsm -> flags .encrypted ) {
406
+ return BLE_ERR_INSUFFICIENT_SEC ;
407
+ }
408
+
409
+ ble_ll_ctrl_proc_start (connsm , BLE_LL_CTRL_PROC_CS_SEC_START , NULL );
410
+
411
+ return BLE_ERR_SUCCESS ;
286
412
}
287
413
288
414
int
0 commit comments