Skip to content

Commit 0ff829a

Browse files
HaavardReim-alperen-sener
authored andcommitted
[nrf fromtree] Bluetooth: Host: Add BT_APP_PASSKEY Kconfig option
Adds the BT_APP_PASSKEY Kconfig, which allows the application to provide passkeys for pairing using the new `app_passkey()` callback. This is an alternative to BT_FIXED_PASSKEY, which will be deprecated in a later commit. Signed-off-by: Håvard Reierstad <[email protected]> (cherry picked from commit 6c64054) Signed-off-by: alperen sener <[email protected]>
1 parent b5cf3ea commit 0ff829a

File tree

3 files changed

+99
-19
lines changed

3 files changed

+99
-19
lines changed

include/zephyr/bluetooth/conn.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2481,6 +2481,13 @@ struct bt_conn_pairing_feat {
24812481
};
24822482
#endif /* CONFIG_BT_SMP_APP_PAIRING_ACCEPT */
24832483

2484+
/**
2485+
* Special passkey value that can be used to generate a random passkey when using the
2486+
* app_passkey callback from @ref bt_conn_auth_cb.
2487+
*
2488+
*/
2489+
#define BT_PASSKEY_RAND 0xffffffff
2490+
24842491
/** Authenticated pairing callback structure */
24852492
struct bt_conn_auth_cb {
24862493
#if defined(CONFIG_BT_SMP_APP_PAIRING_ACCEPT)
@@ -2680,6 +2687,30 @@ struct bt_conn_auth_cb {
26802687
*/
26812688
void (*pincode_entry)(struct bt_conn *conn, bool highsec);
26822689
#endif
2690+
2691+
#if defined(CONFIG_BT_APP_PASSKEY)
2692+
/** @brief Allow the application to provide a passkey for pairing.
2693+
*
2694+
* If implemented, this callback allows the application to provide passkeys for pairing.
2695+
* The valid range of passkeys is 0 - 999999. The application shall return the passkey for
2696+
* pairing, or BT_PASSKEY_RAND to generate a random passkey. This callback is invoked only
2697+
* for the Passkey Entry method as defined in Core Specification Vol. 3, Part H. Which
2698+
* device in the pairing is showing the passkey depends on the IO capabilities of the
2699+
* device; see Table 2.8 of the Bluetooth Core Specification V6.0, Vol. 3, Part H for more
2700+
* details. For the purposes of this table, the device gains the "display" capability when
2701+
* this callback is non-NULL. This is irrespective of whether the callback returns a
2702+
* specified key or BT_PASSKEY_RAND.
2703+
*
2704+
*
2705+
* @note When using this callback, it is the responsibility of the application to use
2706+
* random and unique keys.
2707+
*
2708+
* @param conn Connection where pairing is currently active.
2709+
* @return Passkey for pairing, or BT_PASSKEY_RAND for the Host to generate a random
2710+
* passkey.
2711+
*/
2712+
uint32_t (*app_passkey)(struct bt_conn *conn);
2713+
#endif /* CONFIG_BT_APP_PASSKEY */
26832714
};
26842715

26852716
/** Authenticated pairing information callback structure */

subsys/bluetooth/host/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,16 @@ config BT_FIXED_PASSKEY
706706
bt_passkey_set() API to set a fixed passkey. If set, the
707707
pairing_confirm() callback will be called for all incoming pairings.
708708

709+
config BT_APP_PASSKEY
710+
bool "Allow the application to provide passkeys for pairing"
711+
depends on !BT_FIXED_PASSKEY
712+
help
713+
With this option enabled, the application will be able to provide passkeys for pairing
714+
using the app_passkey() callback. If the application does not provide a passkey, a
715+
random passkey will be generated by the Host.
716+
717+
WARNING: It is the responsibility of the application to use random and unique keys.
718+
709719
config BT_USE_DEBUG_KEYS
710720
bool "Security Manager Debug Mode"
711721
help

subsys/bluetooth/host/smp.c

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,10 @@ struct bt_smp {
222222
atomic_t bondable;
223223
};
224224

225-
static unsigned int fixed_passkey = BT_PASSKEY_INVALID;
225+
static unsigned int fixed_passkey = BT_PASSKEY_RAND;
226226

227227
#define DISPLAY_FIXED(smp) (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) && \
228-
fixed_passkey != BT_PASSKEY_INVALID && \
228+
fixed_passkey != BT_PASSKEY_RAND && \
229229
(smp)->method == PASSKEY_DISPLAY)
230230

231231
#if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
@@ -363,9 +363,21 @@ static uint8_t get_io_capa(struct bt_smp *smp)
363363
return BT_SMP_IO_DISPLAY_YESNO;
364364
}
365365

366+
#if defined(CONFIG_BT_APP_PASSKEY)
367+
/* Implementation of the app_passkey cb implies that the application can "know" the passkey
368+
* without actually having a display, thus earning the "display" capability.
369+
*/
370+
if (smp_auth_cb->app_passkey) {
371+
if (smp_auth_cb->passkey_entry) {
372+
return BT_SMP_IO_KEYBOARD_DISPLAY;
373+
}
374+
375+
return BT_SMP_IO_DISPLAY_ONLY;
376+
}
377+
#endif /* CONFIG_BT_APP_PASSKEY */
378+
366379
if (smp_auth_cb->passkey_entry) {
367-
if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) &&
368-
fixed_passkey != BT_PASSKEY_INVALID) {
380+
if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) && fixed_passkey != BT_PASSKEY_RAND) {
369381
return BT_SMP_IO_KEYBOARD_DISPLAY;
370382
} else {
371383
return BT_SMP_IO_KEYBOARD_ONLY;
@@ -377,8 +389,7 @@ static uint8_t get_io_capa(struct bt_smp *smp)
377389
}
378390

379391
no_callbacks:
380-
if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) &&
381-
fixed_passkey != BT_PASSKEY_INVALID) {
392+
if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) && fixed_passkey != BT_PASSKEY_RAND) {
382393
return BT_SMP_IO_DISPLAY_ONLY;
383394
} else {
384395
return BT_SMP_IO_NO_INPUT_OUTPUT;
@@ -2467,7 +2478,6 @@ static uint8_t legacy_request_tk(struct bt_smp *smp)
24672478
struct bt_conn *conn = smp->chan.chan.conn;
24682479
const struct bt_conn_auth_cb *smp_auth_cb = latch_auth_cb(smp);
24692480
struct bt_keys *keys;
2470-
uint32_t passkey;
24712481

24722482
/*
24732483
* Fail if we have keys that are stronger than keys that will be
@@ -2495,11 +2505,25 @@ static uint8_t legacy_request_tk(struct bt_smp *smp)
24952505
}
24962506

24972507
break;
2498-
case PASSKEY_DISPLAY:
2499-
if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) &&
2500-
fixed_passkey != BT_PASSKEY_INVALID) {
2508+
case PASSKEY_DISPLAY: {
2509+
uint32_t passkey;
2510+
2511+
if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) && fixed_passkey != BT_PASSKEY_RAND) {
25012512
passkey = fixed_passkey;
2502-
} else {
2513+
#if defined(CONFIG_BT_APP_PASSKEY)
2514+
} else if (smp_auth_cb && smp_auth_cb->app_passkey) {
2515+
passkey = smp_auth_cb->app_passkey(conn);
2516+
2517+
if (passkey != BT_PASSKEY_RAND && passkey > 999999) {
2518+
LOG_WRN("App-provided passkey is out of valid range: %u", passkey);
2519+
return BT_SMP_ERR_UNSPECIFIED;
2520+
}
2521+
#endif /* CONFIG_BT_APP_PASSKEY */
2522+
} else {
2523+
passkey = BT_PASSKEY_RAND;
2524+
}
2525+
2526+
if (passkey == BT_PASSKEY_RAND) {
25032527
if (bt_rand(&passkey, sizeof(passkey))) {
25042528
return BT_SMP_ERR_UNSPECIFIED;
25052529
}
@@ -2519,6 +2543,7 @@ static uint8_t legacy_request_tk(struct bt_smp *smp)
25192543
sys_put_le32(passkey, smp->tk);
25202544

25212545
break;
2546+
}
25222547
case PASSKEY_INPUT:
25232548
atomic_set_bit(smp->flags, SMP_FLAG_USER);
25242549
smp_auth_cb->passkey_entry(conn);
@@ -4429,18 +4454,32 @@ __maybe_unused static uint8_t display_passkey(struct bt_smp *smp)
44294454
{
44304455
struct bt_conn *conn = smp->chan.chan.conn;
44314456
const struct bt_conn_auth_cb *smp_auth_cb = latch_auth_cb(smp);
4457+
uint32_t passkey = BT_PASSKEY_RAND;
44324458

4433-
if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) &&
4434-
fixed_passkey != BT_PASSKEY_INVALID) {
4435-
smp->passkey = fixed_passkey;
4436-
} else {
4437-
if (bt_rand(&smp->passkey, sizeof(smp->passkey))) {
4459+
if (IS_ENABLED(CONFIG_BT_FIXED_PASSKEY) && fixed_passkey != BT_PASSKEY_RAND) {
4460+
passkey = fixed_passkey;
4461+
}
4462+
4463+
#if defined(CONFIG_BT_APP_PASSKEY)
4464+
if (smp_auth_cb && smp_auth_cb->app_passkey) {
4465+
passkey = smp_auth_cb->app_passkey(conn);
4466+
4467+
if (passkey != BT_PASSKEY_RAND && passkey > 999999) {
4468+
LOG_WRN("App-provided passkey is out of valid range: %u", passkey);
4469+
return BT_SMP_ERR_UNSPECIFIED;
4470+
}
4471+
}
4472+
#endif /* CONFIG_BT_APP_PASSKEY */
4473+
4474+
if (passkey == BT_PASSKEY_RAND) {
4475+
if (bt_rand(&passkey, sizeof(passkey))) {
44384476
return BT_SMP_ERR_UNSPECIFIED;
44394477
}
44404478

4441-
smp->passkey %= 1000000;
4479+
passkey %= 1000000;
44424480
}
44434481

4482+
smp->passkey = passkey;
44444483
smp->passkey_round = 0U;
44454484

44464485
if (smp_auth_cb && smp_auth_cb->passkey_display) {
@@ -6172,8 +6211,8 @@ int bt_smp_auth_pairing_confirm(struct bt_conn *conn)
61726211
#if defined(CONFIG_BT_FIXED_PASSKEY)
61736212
int bt_passkey_set(unsigned int passkey)
61746213
{
6175-
if (passkey == BT_PASSKEY_INVALID) {
6176-
fixed_passkey = BT_PASSKEY_INVALID;
6214+
if (passkey == BT_PASSKEY_INVALID || passkey == BT_PASSKEY_RAND) {
6215+
fixed_passkey = BT_PASSKEY_RAND;
61776216
return 0;
61786217
}
61796218

0 commit comments

Comments
 (0)