From d01bae79b9eb1de41e380f24e700de03b55473d0 Mon Sep 17 00:00:00 2001 From: funkycode Date: Fri, 10 Nov 2023 12:51:28 +0200 Subject: [PATCH 1/2] POC of LESC --- adapter_nrf528xx-full.go | 56 +++++++++++++++++++++++++++++++++++++--- adapter_nrf528xx.go | 47 +++++++++++++++++++++++---------- adapter_sd.go | 9 +++++-- 3 files changed, 93 insertions(+), 19 deletions(-) diff --git a/adapter_nrf528xx-full.go b/adapter_nrf528xx-full.go index 27015e95..d53a7e5d 100644 --- a/adapter_nrf528xx-full.go +++ b/adapter_nrf528xx-full.go @@ -101,9 +101,55 @@ func handleEvent() { C.sd_ble_gap_phy_update(gapEvent.conn_handle, &phyUpdateRequest.peer_preferred_phys) case C.BLE_GAP_EVT_AUTH_STATUS: // here we get auth response + if debug { + authStatus := gapEvent.params.unionfield_auth_status() + if authStatus.auth_status != C.BLE_GAP_SEC_STATUS_SUCCESS { + if authStatus.bitfield_error_src() == C.BLE_GAP_SEC_STATUS_SOURCE_LOCAL { + println("auth failed from local source") + } else { + println("auth failed from remote source") + } + println("auth status failed with status:", authStatus.auth_status) + break + } + if authStatus.bitfield_bonded() == 1 { + println("auth status is bonded") + } + if authStatus.bitfield_lesc() == 1 { + println("connection is LE secure") + } + if authStatus.kdist_own.bitfield_enc() != 0 { + println("local peer distributed encription keys") + } + if authStatus.kdist_own.bitfield_id() != 0 { + println("local peer distributed id keys") + } + if authStatus.kdist_own.bitfield_sign() != 0 { + println("local peer distributed sign keys") + } + if authStatus.kdist_own.bitfield_link() != 0 { + println("local peer distributed link keys") + } + + if authStatus.kdist_peer.bitfield_enc() != 0 { + println("remote peer distributed encription keys") + } + if authStatus.kdist_peer.bitfield_id() != 0 { + println("remote peer distributed id keys") + } + if authStatus.kdist_peer.bitfield_sign() != 0 { + println("remote peer distributed sign keys") + } + if authStatus.kdist_peer.bitfield_link() != 0 { + println("remote peer distributed link keys") + } + } + // TODO: save keys to flash for pairing/bonding case C.BLE_GAP_EVT_PHY_UPDATE: // ignore confirmation of phy successfully updated + case C.BLE_GAP_EVT_CONN_SEC_UPDATE: + case C.BLE_GAP_EVT_SEC_PARAMS_REQUEST: if debug { println("evt: security parameters request") @@ -123,9 +169,13 @@ func handleEvent() { } case C.BLE_GAP_EVT_LESC_DHKEY_REQUEST: - // TODO: for LESC connection implementation - // peerPk := eventBuf.evt.unionfield_gatts_evt() - // sd_ble_gap_lesc_dhkey_reply(gapEvent.conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey)) + if debug { + println("evt: lesc dhkey request") + } + // lesc_request := gapEvent.params.unionfield_lesc_dhkey_request() + //DefaultAdapter.lescRequestHandler(lesc_request.p_pk_peer.pk[:]) + DefaultAdapter.lescRequestHandler(secKeySet.keys_peer.p_pk.pk[:]) + default: if debug { println("unknown GAP event:", id) diff --git a/adapter_nrf528xx.go b/adapter_nrf528xx.go index 1a405bf0..e714f182 100644 --- a/adapter_nrf528xx.go +++ b/adapter_nrf528xx.go @@ -38,20 +38,7 @@ var ( max_key_size: 16, } - secKeySet C.ble_gap_sec_keyset_t = C.ble_gap_sec_keyset_t{ - keys_peer: C.ble_gap_sec_keys_t{ - p_enc_key: &C.ble_gap_enc_key_t{}, /**< Encryption Key, or NULL. */ - p_id_key: &C.ble_gap_id_key_t{}, /**< Identity Key, or NULL. */ - p_sign_key: &C.ble_gap_sign_info_t{}, /**< Signing Key, or NULL. */ - p_pk: &C.ble_gap_lesc_p256_pk_t{}, - }, - keys_own: C.ble_gap_sec_keys_t{ - p_enc_key: &C.ble_gap_enc_key_t{}, /**< Encryption Key, or NULL. */ - p_id_key: &C.ble_gap_id_key_t{}, /**< Identity Key, or NULL. */ - p_sign_key: &C.ble_gap_sign_info_t{}, /**< Signing Key, or NULL. */ - p_pk: &C.ble_gap_lesc_p256_pk_t{}, - }, - } + secKeySet C.ble_gap_sec_keyset_t ) // are those should be methods for adapter as they are relevant for sd only @@ -59,6 +46,34 @@ func SetSecParamsBonding() { secParams.set_bitfield_bond(1) } +func SetSecParamsLesc() { + secParams.set_bitfield_bond(0) + secParams.set_bitfield_lesc(1) +} + +func SetLesPublicKey(key []uint8) { + secKeySet.keys_peer = C.ble_gap_sec_keys_t{ + p_pk: &C.ble_gap_lesc_p256_pk_t{}, + } + secKeySet.keys_own = C.ble_gap_sec_keys_t{ + p_pk: &C.ble_gap_lesc_p256_pk_t{ + pk: [C.BLE_GAP_LESC_P256_PK_LEN]uint8(key), + }, + } +} + +func ReplyLesc(key []byte) error { + lescKey := C.ble_gap_lesc_dhkey_t{ + key: [C.BLE_GAP_LESC_DHKEY_LEN]uint8(key), + } + errCode := C.sd_ble_gap_lesc_dhkey_reply(currentConnection.Reg, &lescKey) + if errCode != 0 { + return Error(errCode) + + } + return nil +} + func SetSecCapabilities(cap GapIOCapability) { secParams.set_bitfield_io_caps(uint8(cap)) } @@ -103,3 +118,7 @@ func (a *Adapter) Address() (MACAddress, error) { } return MACAddress{MAC: addr.addr}, nil } + +func (a *Adapter) SetLescRequestHandler(c func(pubKey []uint8)) { + a.lescRequestHandler = c +} diff --git a/adapter_sd.go b/adapter_sd.go index 24963b3a..af90dfee 100644 --- a/adapter_sd.go +++ b/adapter_sd.go @@ -48,7 +48,8 @@ type Adapter struct { scanning bool charWriteHandlers []charWriteHandler - connectHandler func(device Address, connected bool) + connectHandler func(device Address, connected bool) + lescRequestHandler func(pubKey []uint8) } // DefaultAdapter is the default adapter on the current system. On Nordic chips, @@ -58,7 +59,11 @@ type Adapter struct { var DefaultAdapter = &Adapter{isDefault: true, connectHandler: func(device Address, connected bool) { return - }} + }, + lescRequestHandler: func(pubKey []uint8) { + return + }, +} var eventBufLen uint16 From 5ca5416572d34ee84d8047e448d84ee04c6525b1 Mon Sep 17 00:00:00 2001 From: funkycode Date: Sat, 11 Nov 2023 15:36:34 +0200 Subject: [PATCH 2/2] reconnnect (that doesn't work properly yet) --- adapter_nrf528xx-full.go | 37 +++++++++++++++++++++++++++++++++---- adapter_nrf528xx.go | 12 ++++++++++-- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/adapter_nrf528xx-full.go b/adapter_nrf528xx-full.go index d53a7e5d..634b03dc 100644 --- a/adapter_nrf528xx-full.go +++ b/adapter_nrf528xx-full.go @@ -42,7 +42,9 @@ func handleEvent() { } case C.BLE_GAP_EVT_DISCONNECTED: if debug { - println("evt: disconnected") + disconn := gapEvent.params.unionfield_disconnected() + println("evt: disconnected with reason:", disconn.reason) + } // Clean up state for this connection. for i, cb := range gattcNotificationCallbacks { @@ -99,6 +101,35 @@ func handleEvent() { case C.BLE_GAP_EVT_PHY_UPDATE_REQUEST: phyUpdateRequest := gapEvent.params.unionfield_phy_update_request() C.sd_ble_gap_phy_update(gapEvent.conn_handle, &phyUpdateRequest.peer_preferred_phys) + case C.BLE_GAP_EVT_CONN_PARAM_UPDATE: + // just update on some settings, ignore it + case C.BLE_GAP_EVT_CONN_SEC_UPDATE: + if debug { + println("evt: connection security update") + } + case C.BLE_GAP_EVT_SEC_INFO_REQUEST: + if debug { + println("evt: sec info request") + } + + secInfo := gapEvent.params.unionfield_sec_info_request() + var errCode uint32 + if secInfo.master_id.ediv == secKeySet.keys_peer.p_enc_key.master_id.ediv { + println("evid match") + secKeySet.keys_peer.p_enc_key.enc_info.set_bitfield_lesc(1) + errCode = C.sd_ble_gap_sec_info_reply(gapEvent.conn_handle, &secKeySet.keys_peer.p_enc_key.enc_info, + &secKeySet.keys_peer.p_id_key.id_info, nil) //secKeySet.keys_own + } else { + println("evid no match") + errCode = C.sd_ble_gap_sec_info_reply(gapEvent.conn_handle, nil, + &secKeySet.keys_peer.p_id_key.id_info, nil) + } + if errCode != 0 { + println("security info request failed:", Error(errCode).Error()) + return + } + println("security info request succeesess") + case C.BLE_GAP_EVT_AUTH_STATUS: // here we get auth response if debug { @@ -148,8 +179,6 @@ func handleEvent() { // TODO: save keys to flash for pairing/bonding case C.BLE_GAP_EVT_PHY_UPDATE: // ignore confirmation of phy successfully updated - case C.BLE_GAP_EVT_CONN_SEC_UPDATE: - case C.BLE_GAP_EVT_SEC_PARAMS_REQUEST: if debug { println("evt: security parameters request") @@ -178,7 +207,7 @@ func handleEvent() { default: if debug { - println("unknown GAP event:", id) + println("unknown GAP event:", id-C.BLE_GAP_EVT_BASE) } } case id >= C.BLE_GATTS_EVT_BASE && id <= C.BLE_GATTS_EVT_LAST: diff --git a/adapter_nrf528xx.go b/adapter_nrf528xx.go index e714f182..01ff80bf 100644 --- a/adapter_nrf528xx.go +++ b/adapter_nrf528xx.go @@ -47,15 +47,23 @@ func SetSecParamsBonding() { } func SetSecParamsLesc() { - secParams.set_bitfield_bond(0) + secParams.set_bitfield_bond(0) //1) secParams.set_bitfield_lesc(1) + //secParams.set_bitfield_mitm(1) + //secParams.set_bitfield_io_caps(uint8(DisplayOnlyGapIOCapability)) } func SetLesPublicKey(key []uint8) { secKeySet.keys_peer = C.ble_gap_sec_keys_t{ - p_pk: &C.ble_gap_lesc_p256_pk_t{}, + p_pk: &C.ble_gap_lesc_p256_pk_t{}, + p_enc_key: &C.ble_gap_enc_key_t{}, + p_id_key: &C.ble_gap_id_key_t{}, + p_sign_key: &C.ble_gap_sign_info_t{}, } secKeySet.keys_own = C.ble_gap_sec_keys_t{ + p_enc_key: &C.ble_gap_enc_key_t{}, + p_id_key: &C.ble_gap_id_key_t{}, + p_sign_key: &C.ble_gap_sign_info_t{}, p_pk: &C.ble_gap_lesc_p256_pk_t{ pk: [C.BLE_GAP_LESC_P256_PK_LEN]uint8(key), },