Bluetooth: smp: Adding Legacy OOB only mode and no JW/Passkey mode
Added CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY option that completely disables all legacy and SC pairing modes(except for Out of Band) and frees the memory previously used by these. Added CONFIG_BT_SMP_DISABLE_LEGACY_JW_PASSKEY option that force rejects pair requests that lead to legacy Just Works or Passkey pairing. Signed-off-by: Iván Morales <ivan98ams@gmail.com>
This commit is contained in:
parent
cc0d2447f1
commit
e85dd8af5d
4 changed files with 75 additions and 8 deletions
|
@ -293,7 +293,6 @@ config BT_SMP
|
||||||
select TINYCRYPT_AES
|
select TINYCRYPT_AES
|
||||||
select TINYCRYPT_AES_CMAC
|
select TINYCRYPT_AES_CMAC
|
||||||
select BT_RPA
|
select BT_RPA
|
||||||
select BT_ECC
|
|
||||||
help
|
help
|
||||||
This option enables support for the Security Manager Protocol
|
This option enables support for the Security Manager Protocol
|
||||||
(SMP), making it possible to pair devices over LE.
|
(SMP), making it possible to pair devices over LE.
|
||||||
|
@ -349,6 +348,20 @@ config BT_SMP_SC_ONLY
|
||||||
Security Mode 1 Level 4 stands for authenticated LE Secure Connections
|
Security Mode 1 Level 4 stands for authenticated LE Secure Connections
|
||||||
pairing with encryption. Enabling this option disables legacy pairing.
|
pairing with encryption. Enabling this option disables legacy pairing.
|
||||||
|
|
||||||
|
config BT_SMP_OOB_LEGACY_PAIR_ONLY
|
||||||
|
bool "Force Out Of Band Legacy pairing"
|
||||||
|
depends on !(BT_SMP_SC_PAIR_ONLY || BT_SMP_SC_ONLY)
|
||||||
|
help
|
||||||
|
This option disables Legacy and LE SC pairing and forces legacy OOB.
|
||||||
|
|
||||||
|
config BT_SMP_DISABLE_LEGACY_JW_PASSKEY
|
||||||
|
bool "Forbid usage of insecure legacy pairing methods"
|
||||||
|
depends on !(BT_SMP_SC_PAIR_ONLY || BT_SMP_SC_ONLY || \
|
||||||
|
BT_SMP_OOB_LEGACY_PAIR_ONLY)
|
||||||
|
help
|
||||||
|
This option disables Just Works and Passkey legacy pairing methods to
|
||||||
|
increase security.
|
||||||
|
|
||||||
config BT_SMP_ALLOW_UNAUTH_OVERWRITE
|
config BT_SMP_ALLOW_UNAUTH_OVERWRITE
|
||||||
bool "Allow unauthenticated pairing for paired device"
|
bool "Allow unauthenticated pairing for paired device"
|
||||||
help
|
help
|
||||||
|
@ -545,6 +558,7 @@ endif # BT_HCI_HOST
|
||||||
|
|
||||||
config BT_ECC
|
config BT_ECC
|
||||||
bool "Enable ECDH key generation support"
|
bool "Enable ECDH key generation support"
|
||||||
|
default y if !BT_SMP_OOB_LEGACY_PAIR_ONLY
|
||||||
help
|
help
|
||||||
This option adds support for ECDH HCI commands.
|
This option adds support for ECDH HCI commands.
|
||||||
|
|
||||||
|
|
|
@ -1123,6 +1123,11 @@ int bt_conn_set_security(struct bt_conn *conn, bt_security_t sec)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) &&
|
||||||
|
sec > BT_SECURITY_L3) {
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
if (conn->sec_level >= sec || conn->required_sec_level >= sec) {
|
if (conn->sec_level >= sec || conn->required_sec_level >= sec) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -6865,7 +6865,8 @@ int bt_le_oob_get_local(u8_t id, struct bt_le_oob *oob)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_SMP)) {
|
if (IS_ENABLED(CONFIG_BT_SMP) &&
|
||||||
|
!IS_ENABLED(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)) {
|
||||||
err = bt_smp_le_oob_generate_sc_data(&oob->le_sc_data);
|
err = bt_smp_le_oob_generate_sc_data(&oob->le_sc_data);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
|
@ -6883,6 +6884,7 @@ int bt_le_oob_set_legacy_tk(struct bt_conn *conn, const u8_t *tk)
|
||||||
}
|
}
|
||||||
#endif /* !defined(CONFIG_BT_SMP_SC_PAIR_ONLY) */
|
#endif /* !defined(CONFIG_BT_SMP_SC_PAIR_ONLY) */
|
||||||
|
|
||||||
|
#if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
|
||||||
int bt_le_oob_set_sc_data(struct bt_conn *conn,
|
int bt_le_oob_set_sc_data(struct bt_conn *conn,
|
||||||
const struct bt_le_oob_sc_data *oobd_local,
|
const struct bt_le_oob_sc_data *oobd_local,
|
||||||
const struct bt_le_oob_sc_data *oobd_remote)
|
const struct bt_le_oob_sc_data *oobd_remote)
|
||||||
|
@ -6904,4 +6906,5 @@ int bt_le_oob_get_sc_data(struct bt_conn *conn,
|
||||||
|
|
||||||
return bt_smp_le_oob_get_sc_data(conn, oobd_local, oobd_remote);
|
return bt_smp_le_oob_get_sc_data(conn, oobd_local, oobd_remote);
|
||||||
}
|
}
|
||||||
|
#endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
|
||||||
#endif /* defined(CONFIG_BT_SMP) */
|
#endif /* defined(CONFIG_BT_SMP) */
|
||||||
|
|
|
@ -80,13 +80,25 @@
|
||||||
#endif /* CONFIG_BT_BONDABLE */
|
#endif /* CONFIG_BT_BONDABLE */
|
||||||
|
|
||||||
#if defined(CONFIG_BT_BREDR)
|
#if defined(CONFIG_BT_BREDR)
|
||||||
|
|
||||||
#define BT_SMP_AUTH_MASK_SC 0x2f
|
#define BT_SMP_AUTH_MASK_SC 0x2f
|
||||||
#define BT_SMP_AUTH_DEFAULT (BT_SMP_AUTH_BONDING_FLAGS | BT_SMP_AUTH_SC |\
|
#if defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
|
||||||
BT_SMP_AUTH_CT2)
|
#define BT_SMP_AUTH_DEFAULT (BT_SMP_AUTH_BONDING_FLAGS | BT_SMP_AUTH_CT2)
|
||||||
#else
|
#else
|
||||||
|
#define BT_SMP_AUTH_DEFAULT (BT_SMP_AUTH_BONDING_FLAGS | BT_SMP_AUTH_CT2 |\
|
||||||
|
BT_SMP_AUTH_SC)
|
||||||
|
#endif /* CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY */
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
#define BT_SMP_AUTH_MASK_SC 0x0f
|
#define BT_SMP_AUTH_MASK_SC 0x0f
|
||||||
|
#if defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
|
||||||
|
#define BT_SMP_AUTH_DEFAULT (BT_SMP_AUTH_BONDING_FLAGS)
|
||||||
|
#else
|
||||||
#define BT_SMP_AUTH_DEFAULT (BT_SMP_AUTH_BONDING_FLAGS | BT_SMP_AUTH_SC)
|
#define BT_SMP_AUTH_DEFAULT (BT_SMP_AUTH_BONDING_FLAGS | BT_SMP_AUTH_SC)
|
||||||
#endif
|
#endif /* CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY */
|
||||||
|
|
||||||
|
#endif /* CONFIG_BT_BREDR */
|
||||||
|
|
||||||
enum pairing_method {
|
enum pairing_method {
|
||||||
JUST_WORKS, /* JustWorks pairing */
|
JUST_WORKS, /* JustWorks pairing */
|
||||||
|
@ -209,6 +221,7 @@ static const u8_t gen_method_legacy[5 /* remote */][5 /* local */] = {
|
||||||
};
|
};
|
||||||
#endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
|
#endif /* CONFIG_BT_SMP_SC_PAIR_ONLY */
|
||||||
|
|
||||||
|
#if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
|
||||||
/* based on table 2.8 Core Spec 2.3.5.1 Vol. 3 Part H */
|
/* based on table 2.8 Core Spec 2.3.5.1 Vol. 3 Part H */
|
||||||
static const u8_t gen_method_sc[5 /* remote */][5 /* local */] = {
|
static const u8_t gen_method_sc[5 /* remote */][5 /* local */] = {
|
||||||
{ JUST_WORKS, JUST_WORKS, PASSKEY_INPUT, JUST_WORKS, PASSKEY_INPUT },
|
{ JUST_WORKS, JUST_WORKS, PASSKEY_INPUT, JUST_WORKS, PASSKEY_INPUT },
|
||||||
|
@ -220,6 +233,7 @@ static const u8_t gen_method_sc[5 /* remote */][5 /* local */] = {
|
||||||
{ PASSKEY_DISPLAY, PASSKEY_CONFIRM, PASSKEY_INPUT, JUST_WORKS,
|
{ PASSKEY_DISPLAY, PASSKEY_CONFIRM, PASSKEY_INPUT, JUST_WORKS,
|
||||||
PASSKEY_CONFIRM },
|
PASSKEY_CONFIRM },
|
||||||
};
|
};
|
||||||
|
#endif /* !CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY */
|
||||||
|
|
||||||
static const u8_t sc_debug_public_key[64] = {
|
static const u8_t sc_debug_public_key[64] = {
|
||||||
0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 0xdb, 0xfd, 0xf4, 0xac,
|
0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 0xdb, 0xfd, 0xf4, 0xac,
|
||||||
|
@ -347,14 +361,15 @@ static bool smp_keys_check(struct bt_conn *conn)
|
||||||
|
|
||||||
static u8_t get_pair_method(struct bt_smp *smp, u8_t remote_io)
|
static u8_t get_pair_method(struct bt_smp *smp, u8_t remote_io)
|
||||||
{
|
{
|
||||||
struct bt_smp_pairing *req, *rsp;
|
|
||||||
|
|
||||||
#if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
|
#if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
|
||||||
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
|
if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) {
|
||||||
return legacy_get_pair_method(smp, remote_io);
|
return legacy_get_pair_method(smp, remote_io);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
|
||||||
|
struct bt_smp_pairing *req, *rsp;
|
||||||
|
|
||||||
req = (struct bt_smp_pairing *)&smp->preq[1];
|
req = (struct bt_smp_pairing *)&smp->preq[1];
|
||||||
rsp = (struct bt_smp_pairing *)&smp->prsp[1];
|
rsp = (struct bt_smp_pairing *)&smp->prsp[1];
|
||||||
|
|
||||||
|
@ -375,6 +390,9 @@ static u8_t get_pair_method(struct bt_smp *smp, u8_t remote_io)
|
||||||
}
|
}
|
||||||
|
|
||||||
return gen_method_sc[remote_io][get_io_capa()];
|
return gen_method_sc[remote_io][get_io_capa()];
|
||||||
|
#else
|
||||||
|
return JUST_WORKS;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum bt_security_err auth_err_get(u8_t smp_err)
|
static enum bt_security_err auth_err_get(u8_t smp_err)
|
||||||
|
@ -712,6 +730,17 @@ static bool update_keys_check(struct bt_smp *smp)
|
||||||
conn->le.keys = bt_keys_get_addr(conn->id, &conn->le.dst);
|
conn->le.keys = bt_keys_get_addr(conn->id, &conn->le.dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_BT_SMP_DISABLE_LEGACY_JW_PASSKEY) &&
|
||||||
|
!atomic_test_bit(smp->flags, SMP_FLAG_SC) &&
|
||||||
|
smp->method != LEGACY_OOB) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) &&
|
||||||
|
smp->method != LEGACY_OOB) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!conn->le.keys ||
|
if (!conn->le.keys ||
|
||||||
!(conn->le.keys->keys & (BT_KEYS_LTK_P256 | BT_KEYS_LTK))) {
|
!(conn->le.keys->keys & (BT_KEYS_LTK_P256 | BT_KEYS_LTK))) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -2598,7 +2627,9 @@ static int smp_init(struct bt_smp *smp)
|
||||||
|
|
||||||
atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_FAIL);
|
atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_FAIL);
|
||||||
|
|
||||||
|
#if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
|
||||||
sc_public_key = bt_pub_key_get();
|
sc_public_key = bt_pub_key_get();
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3902,6 +3933,10 @@ static u8_t smp_security_request(struct bt_smp *smp, struct net_buf *buf)
|
||||||
|
|
||||||
static u8_t generate_dhkey(struct bt_smp *smp)
|
static u8_t generate_dhkey(struct bt_smp *smp)
|
||||||
{
|
{
|
||||||
|
if (IS_ENABLED(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)) {
|
||||||
|
return BT_SMP_ERR_UNSPECIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
if (bt_dh_key_gen(smp->pkey, bt_smp_dhkey_ready)) {
|
if (bt_dh_key_gen(smp->pkey, bt_smp_dhkey_ready)) {
|
||||||
return BT_SMP_ERR_UNSPECIFIED;
|
return BT_SMP_ERR_UNSPECIFIED;
|
||||||
}
|
}
|
||||||
|
@ -5064,6 +5099,7 @@ int bt_smp_le_oob_set_tk(struct bt_conn *conn, const u8_t *tk)
|
||||||
}
|
}
|
||||||
#endif /* !defined(CONFIG_BT_SMP_SC_PAIR_ONLY) */
|
#endif /* !defined(CONFIG_BT_SMP_SC_PAIR_ONLY) */
|
||||||
|
|
||||||
|
#if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
|
||||||
int bt_smp_le_oob_generate_sc_data(struct bt_le_oob_sc_data *le_sc_oob)
|
int bt_smp_le_oob_generate_sc_data(struct bt_le_oob_sc_data *le_sc_oob)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
@ -5097,7 +5133,9 @@ int bt_smp_le_oob_generate_sc_data(struct bt_le_oob_sc_data *le_sc_oob)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */
|
||||||
|
|
||||||
|
#if !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)
|
||||||
static bool le_sc_oob_data_check(struct bt_smp *smp, bool oobd_local_present,
|
static bool le_sc_oob_data_check(struct bt_smp *smp, bool oobd_local_present,
|
||||||
bool oobd_remote_present)
|
bool oobd_remote_present)
|
||||||
{
|
{
|
||||||
|
@ -5201,6 +5239,7 @@ int bt_smp_le_oob_get_sc_data(struct bt_conn *conn,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif /* !CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY */
|
||||||
|
|
||||||
int bt_smp_auth_cancel(struct bt_conn *conn)
|
int bt_smp_auth_cancel(struct bt_conn *conn)
|
||||||
{
|
{
|
||||||
|
@ -5470,6 +5509,10 @@ static bool le_sc_supported(void)
|
||||||
* "LE Read Local P-256 Public Key" and "LE Generate DH Key" commands.
|
* "LE Read Local P-256 Public Key" and "LE Generate DH Key" commands.
|
||||||
* Otherwise LE SC are not supported.
|
* Otherwise LE SC are not supported.
|
||||||
*/
|
*/
|
||||||
|
if (IS_ENABLED(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return BT_CMD_TEST(bt_dev.supported_commands, 34, 1) &&
|
return BT_CMD_TEST(bt_dev.supported_commands, 34, 1) &&
|
||||||
BT_CMD_TEST(bt_dev.supported_commands, 34, 2);
|
BT_CMD_TEST(bt_dev.supported_commands, 34, 2);
|
||||||
}
|
}
|
||||||
|
@ -5499,7 +5542,9 @@ int bt_smp_init(void)
|
||||||
|
|
||||||
BT_DBG("LE SC %s", sc_supported ? "enabled" : "disabled");
|
BT_DBG("LE SC %s", sc_supported ? "enabled" : "disabled");
|
||||||
|
|
||||||
bt_pub_key_gen(&pub_key_cb);
|
if (!IS_ENABLED(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY)) {
|
||||||
|
bt_pub_key_gen(&pub_key_cb);
|
||||||
|
}
|
||||||
|
|
||||||
return smp_self_test();
|
return smp_self_test();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue