feat(nimble): Add support for static passkey

This commit is contained in:
Rahul Tank
2025-12-19 16:01:08 +05:30
parent 872f3c1849
commit 445bdeb281
7 changed files with 168 additions and 1 deletions
+1
View File
@@ -417,6 +417,7 @@ struct ble_gap_passkey_params {
* - BLE_SM_IOACT_INPUT
* - BLE_SM_IOACT_DISP
* - BLE_SM_IOACT_NUMCMP
* - BLE_SM_IOACT_STATIC
*/
uint8_t action;
+16
View File
@@ -358,6 +358,22 @@ struct ble_hs_cfg {
/** @brief Weather to use GATT caching or not for discovery operations */
uint8_t gatt_use_cache;
#if MYNEWT_VAL(STATIC_PASSKEY)
/** @brief Security Manager Static Passkey flag
*
* If set, the device will use a static passkey for pairing instead of
* generating dynamic passkeys.
*/
unsigned sm_static_passkey:1;
/** @brief Security Manager Static Passkey Value
*
* The static passkey value to use when sm_static_passkey is enabled.
* Must be a 6-digit number (0-999999).
*/
uint32_t sm_static_passkey_val;
#endif
/** @brief Stack reset callback
*
* This callback is executed when the host resets itself and the controller
+38 -1
View File
@@ -22,6 +22,9 @@
#include <inttypes.h>
#include "syscfg/syscfg.h"
#if MYNEWT_VAL(STATIC_PASSKEY)
#include <stdbool.h>
#endif
#ifdef __cplusplus
extern "C" {
@@ -87,7 +90,8 @@ extern "C" {
#define BLE_SM_IOACT_DISP 3
#define BLE_SM_IOACT_NUMCMP 4
#define BLE_SM_IOACT_OOB_SC 5
#define BLE_SM_IOACT_MAX_PLUS_ONE 6
#define BLE_SM_IOACT_STATIC 6
#define BLE_SM_IOACT_MAX_PLUS_ONE 7
struct ble_sm_sc_oob_data {
/** Random Number. */
@@ -114,9 +118,42 @@ int ble_sm_sc_oob_generate_data(struct ble_sm_sc_oob_data *oob_data);
#if NIMBLE_BLE_SM
int ble_sm_inject_io(uint16_t conn_handle, struct ble_sm_io *pkey);
#if MYNEWT_VAL(STATIC_PASSKEY)
/**
* @brief Configure static passkey for BLE pairing
*
* This function enables static passkey mode and sets the passkey value.
* When enabled, the device will automatically use the specified passkey
* for both display and input actions during pairing, eliminating the
* need for dynamic passkey generation.
*
* @param passkey The 6-digit static passkey (0-999999)
* @param enable Whether to enable (true) or disable (false) static passkey
*
* @return 0 on success, error code on failure
*/
int ble_sm_configure_static_passkey(uint32_t passkey, bool enable);
/**
* @brief Get the current static passkey configuration
*
* @param passkey Pointer to store the current static passkey value
* @param enabled Pointer to store whether static passkey is enabled
*
* @return 0 on success, error code on failure
*/
int ble_sm_get_static_passkey_config(uint32_t *passkey, bool *enabled);
#endif
#else
#define ble_sm_inject_io(conn_handle, pkey) \
((void)(conn_handle), BLE_HS_ENOTSUP)
#if !MYNEWT_VAL(STATIC_PASSKEY)
#define ble_sm_configure_static_passkey(passkey, enable) \
((void)(passkey), (void)(enable), BLE_HS_ENOTSUP)
#define ble_sm_get_static_passkey_config(passkey, enabled) \
((void)(passkey), (void)(enabled), BLE_HS_ENOTSUP)
#endif
#endif
#ifdef __cplusplus
+17
View File
@@ -8848,6 +8848,23 @@ ble_gap_passkey_event(uint16_t conn_handle,
BLE_HS_LOG(DEBUG, "send passkey action request %d\n",
passkey_params->action);
#if MYNEWT_VAL(STATIC_PASSKEY)
/* Check if static passkey is configured and handle automatically */
if (ble_hs_cfg.sm_static_passkey) {
struct ble_sm_io pk;
int rc;
if (passkey_params->action == BLE_SM_IOACT_STATIC) {
pk.action = BLE_SM_IOACT_STATIC;
pk.passkey = ble_hs_cfg.sm_static_passkey_val;
rc = ble_sm_inject_io(conn_handle, &pk);
if (rc == 0) {
BLE_HS_LOG(INFO, "static passkey injected");
return;
}
}
}
#endif
memset(&event, 0, sizeof event);
event.type = BLE_GAP_EVENT_PASSKEY_ACTION;
+60
View File
@@ -806,6 +806,11 @@ ble_sm_ioact_state(uint8_t action)
case BLE_SM_IOACT_DISP:
return BLE_SM_PROC_STATE_CONFIRM;
#if MYNEWT_VAL(STATIC_PASSKEY)
case BLE_SM_IOACT_STATIC:
return BLE_SM_PROC_STATE_CONFIRM;
#endif
default:
BLE_HS_DBG_ASSERT(0);
return BLE_SM_PROC_STATE_NONE;
@@ -3056,7 +3061,26 @@ ble_sm_inject_io(uint16_t conn_handle, struct ble_sm_io *pkey)
}
break;
#endif
#if MYNEWT_VAL(STATIC_PASSKEY)
case BLE_SM_IOACT_STATIC:
if (pkey->passkey > 999999) {
rc = BLE_HS_EINVAL;
} else {
proc->flags |= BLE_SM_PROC_F_IO_INJECTED;
memset(proc->tk, 0, 16);
proc->tk[0] = (pkey->passkey >> 0) & 0xff;
proc->tk[1] = (pkey->passkey >> 8) & 0xff;
proc->tk[2] = (pkey->passkey >> 16) & 0xff;
proc->tk[3] = (pkey->passkey >> 24) & 0xff;
if ((proc->flags & BLE_SM_PROC_F_INITIATOR) ||
(proc->flags & BLE_SM_PROC_F_ADVANCE_ON_IO))
{
res.execute = 1;
}
}
break;
#endif
default:
BLE_HS_DBG_ASSERT(0);
rc = BLE_HS_EINVAL;
@@ -3160,4 +3184,40 @@ ble_sm_create_chan(uint16_t conn_handle)
return chan;
}
#if MYNEWT_VAL(STATIC_PASSKEY)
int
ble_sm_configure_static_passkey(uint32_t passkey, bool enable)
{
if (enable) {
/* Validate passkey is 6 digits */
if (passkey > 999999) {
return BLE_HS_EINVAL;
}
/* Passkey authentication requires MITM; ensure it is enabled. */
ble_hs_cfg.sm_mitm = 1;
ble_hs_cfg.sm_static_passkey = 1;
ble_hs_cfg.sm_static_passkey_val = passkey;
BLE_HS_LOG(DEBUG, "static passkey enabled\n");
} else {
ble_hs_cfg.sm_static_passkey = 0;
ble_hs_cfg.sm_static_passkey_val = 0;
BLE_HS_LOG(INFO, "static passkey disabled\n");
}
return 0;
}
int
ble_sm_get_static_passkey_config(uint32_t *passkey, bool *enabled)
{
if (passkey == NULL || enabled == NULL) {
return BLE_HS_EINVAL;
}
*enabled = ble_hs_cfg.sm_static_passkey;
*passkey = ble_hs_cfg.sm_static_passkey_val;
return 0;
}
#endif
#endif
+18
View File
@@ -68,6 +68,17 @@ ble_sm_lgcy_io_action(struct ble_sm_proc *proc, uint8_t *action)
pair_req = (struct ble_sm_pair_cmd *) &proc->pair_req[1];
pair_rsp = (struct ble_sm_pair_cmd *) &proc->pair_rsp[1];
#if MYNEWT_VAL(STATIC_PASSKEY)
/* Check if static passkey is enabled - if so, use static passkey action */
if (ble_hs_cfg.sm_static_passkey)
{
*action = BLE_SM_IOACT_STATIC;
proc->pair_alg = BLE_SM_PAIR_ALG_PASSKEY;
proc->flags |= BLE_SM_PROC_F_AUTHENTICATED;
return 0;
}
#endif
if (pair_req->oob_data_flag == BLE_SM_PAIR_OOB_YES &&
pair_rsp->oob_data_flag == BLE_SM_PAIR_OOB_YES) {
*action = BLE_SM_IOACT_OOB;
@@ -100,6 +111,13 @@ ble_sm_lgcy_io_action(struct ble_sm_proc *proc, uint8_t *action)
proc->flags |= BLE_SM_PROC_F_AUTHENTICATED;
break;
#if MYNEWT_VAL(STATIC_PASSKEY)
case BLE_SM_IOACT_STATIC:
proc->pair_alg = BLE_SM_PAIR_ALG_PASSKEY;
proc->flags |= BLE_SM_PROC_F_AUTHENTICATED;
break;
#endif
default:
BLE_HS_DBG_ASSERT(0);
return BLE_HS_EINVAL;
+18
View File
@@ -105,6 +105,17 @@ ble_sm_sc_io_action(struct ble_sm_proc *proc, uint8_t *action)
pair_req = (struct ble_sm_pair_cmd *) &proc->pair_req[1];
pair_rsp = (struct ble_sm_pair_cmd *) &proc->pair_rsp[1];
#if MYNEWT_VAL(STATIC_PASSKEY)
/* Check if static passkey is enabled - if so, use static passkey action */
if (ble_hs_cfg.sm_static_passkey)
{
*action = BLE_SM_IOACT_STATIC;
proc->pair_alg = BLE_SM_PAIR_ALG_PASSKEY;
proc->flags |= BLE_SM_PROC_F_AUTHENTICATED;
return 0;
}
#endif
if (pair_req->oob_data_flag == BLE_SM_PAIR_OOB_YES ||
pair_rsp->oob_data_flag == BLE_SM_PAIR_OOB_YES) {
*action = BLE_SM_IOACT_OOB_SC;
@@ -137,6 +148,13 @@ ble_sm_sc_io_action(struct ble_sm_proc *proc, uint8_t *action)
proc->flags |= BLE_SM_PROC_F_AUTHENTICATED;
break;
#if MYNEWT_VAL(STATIC_PASSKEY)
case BLE_SM_IOACT_STATIC:
proc->pair_alg = BLE_SM_PAIR_ALG_PASSKEY;
proc->flags |= BLE_SM_PROC_F_AUTHENTICATED;
break;
#endif
case BLE_SM_IOACT_NUMCMP:
proc->pair_alg = BLE_SM_PAIR_ALG_NUMCMP;
proc->flags |= BLE_SM_PROC_F_AUTHENTICATED;