summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Mussared <jim.mussared@gmail.com>2020-11-24 23:54:46 +1100
committerDamien George <damien@micropython.org>2020-12-02 14:40:49 +1100
commita1fcf301217b34ae74fbb937a9488be5bc6e61a5 (patch)
tree0625c5cabd5c5072c35e43b4ba0c6688d34e3fef
parent05fef8c6a4113bc05dd09ddd8d0bf7d136d59f39 (diff)
extmod/modbluetooth: Allow configuration of pairing/bonding parameters.
This allows setting the security and MITM-protection requirements. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
-rw-r--r--extmod/btstack/modbluetooth_btstack.c38
-rw-r--r--extmod/modbluetooth.c22
-rw-r--r--extmod/modbluetooth.h24
-rw-r--r--extmod/nimble/modbluetooth_nimble.c18
-rw-r--r--extmod/nimble/syscfg/syscfg.h13
5 files changed, 109 insertions, 6 deletions
diff --git a/extmod/btstack/modbluetooth_btstack.c b/extmod/btstack/modbluetooth_btstack.c
index 825a9ab7b..ae4bac009 100644
--- a/extmod/btstack/modbluetooth_btstack.c
+++ b/extmod/btstack/modbluetooth_btstack.c
@@ -53,6 +53,11 @@ STATIC const uint16_t BTSTACK_GAP_DEVICE_NAME_HANDLE = 3;
volatile int mp_bluetooth_btstack_state = MP_BLUETOOTH_BTSTACK_STATE_OFF;
+// sm_set_authentication_requirements is set-only, so cache current value.
+#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
+STATIC uint8_t mp_bluetooth_btstack_sm_auth_req = 0;
+#endif
+
#define ERRNO_BLUETOOTH_NOT_ACTIVE MP_ENODEV
STATIC int btstack_error_to_errno(int err) {
@@ -795,6 +800,39 @@ void mp_bluetooth_set_address_mode(uint8_t addr_mode) {
}
}
+#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
+void mp_bluetooth_set_bonding(bool enabled) {
+ if (enabled) {
+ mp_bluetooth_btstack_sm_auth_req |= SM_AUTHREQ_BONDING;
+ } else {
+ mp_bluetooth_btstack_sm_auth_req &= ~SM_AUTHREQ_BONDING;
+ }
+ sm_set_authentication_requirements(mp_bluetooth_btstack_sm_auth_req);
+}
+
+void mp_bluetooth_set_mitm_protection(bool enabled) {
+ if (enabled) {
+ mp_bluetooth_btstack_sm_auth_req |= SM_AUTHREQ_MITM_PROTECTION;
+ } else {
+ mp_bluetooth_btstack_sm_auth_req &= ~SM_AUTHREQ_MITM_PROTECTION;
+ }
+ sm_set_authentication_requirements(mp_bluetooth_btstack_sm_auth_req);
+}
+
+void mp_bluetooth_set_le_secure(bool enabled) {
+ if (enabled) {
+ mp_bluetooth_btstack_sm_auth_req |= SM_AUTHREQ_SECURE_CONNECTION;
+ } else {
+ mp_bluetooth_btstack_sm_auth_req &= ~SM_AUTHREQ_SECURE_CONNECTION;
+ }
+ sm_set_authentication_requirements(mp_bluetooth_btstack_sm_auth_req);
+}
+
+void mp_bluetooth_set_io_capability(uint8_t capability) {
+ sm_set_io_capabilities(capability);
+}
+#endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
+
size_t mp_bluetooth_gap_get_device_name(const uint8_t **buf) {
uint8_t *value = NULL;
size_t value_len = 0;
diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c
index 5d7de7b97..06e340c42 100644
--- a/extmod/modbluetooth.c
+++ b/extmod/modbluetooth.c
@@ -387,6 +387,28 @@ STATIC mp_obj_t bluetooth_ble_config(size_t n_args, const mp_obj_t *args, mp_map
mp_bluetooth_set_address_mode(addr_mode);
break;
}
+ #if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
+ case MP_QSTR_bond: {
+ bool bonding_enabled = mp_obj_is_true(e->value);
+ mp_bluetooth_set_bonding(bonding_enabled);
+ break;
+ }
+ case MP_QSTR_mitm: {
+ bool mitm_protection = mp_obj_is_true(e->value);
+ mp_bluetooth_set_mitm_protection(mitm_protection);
+ break;
+ }
+ case MP_QSTR_io: {
+ mp_int_t io_capability = mp_obj_get_int(e->value);
+ mp_bluetooth_set_io_capability(io_capability);
+ break;
+ }
+ case MP_QSTR_le_secure: {
+ bool le_secure_required = mp_obj_is_true(e->value);
+ mp_bluetooth_set_le_secure(le_secure_required);
+ break;
+ }
+ #endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
default:
mp_raise_ValueError(MP_ERROR_TEXT("unknown config param"));
}
diff --git a/extmod/modbluetooth.h b/extmod/modbluetooth.h
index 62ff6f2f9..977453bec 100644
--- a/extmod/modbluetooth.h
+++ b/extmod/modbluetooth.h
@@ -152,6 +152,13 @@
#define MP_BLUETOOTH_ADDRESS_MODE_RPA (2)
#define MP_BLUETOOTH_ADDRESS_MODE_NRPA (3)
+// These match the spec values, can be used directly by the stack.
+#define MP_BLUETOOTH_IO_CAPABILITY_DISPLAY_ONLY (0)
+#define MP_BLUETOOTH_IO_CAPABILITY_DISPLAY_YESNO (1)
+#define MP_BLUETOOTH_IO_CAPABILITY_KEYBOARD_ONLY (2)
+#define MP_BLUETOOTH_IO_CAPABILITY_NO_INPUT_OUTPUT (3)
+#define MP_BLUETOOTH_IO_CAPABILITY_KEYBOARD_DISPLAY (4)
+
/*
These aren't included in the module for space reasons, but can be used
in your Python code if necessary.
@@ -208,6 +215,12 @@ _GATTS_ERROR_WRITE_NOT_PERMITTED = const(0x03)
_GATTS_ERROR_INSUFFICIENT_AUTHENTICATION = const(0x05)
_GATTS_ERROR_INSUFFICIENT_AUTHORIZATION = const(0x08)
_GATTS_ERROR_INSUFFICIENT_ENCRYPTION = const(0x0f)
+
+_IO_CAPABILITY_DISPLAY_ONLY = const(0)
+_IO_CAPABILITY_DISPLAY_YESNO = const(1)
+_IO_CAPABILITY_KEYBOARD_ONLY = const(2)
+_IO_CAPABILITY_NO_INPUT_OUTPUT = const(3)
+_IO_CAPABILITY_KEYBOARD_DISPLAY = const(4)
*/
// bluetooth.UUID type.
@@ -254,6 +267,17 @@ void mp_bluetooth_get_current_address(uint8_t *addr_type, uint8_t *addr);
// Sets the addressing mode to use.
void mp_bluetooth_set_address_mode(uint8_t addr_mode);
+#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
+// Set bonding flag in pairing requests (i.e. persist security keys).
+void mp_bluetooth_set_bonding(bool enabled);
+// Require MITM protection.
+void mp_bluetooth_set_mitm_protection(bool enabled);
+// Require LE Secure pairing (rather than Legacy Pairing)
+void mp_bluetooth_set_le_secure(bool enabled);
+// I/O capabilities for authentication (see MP_BLUETOOTH_IO_CAPABILITY_*).
+void mp_bluetooth_set_io_capability(uint8_t capability);
+#endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
+
// Get or set the GAP device name that will be used by service 0x1800, characteristic 0x2a00.
size_t mp_bluetooth_gap_get_device_name(const uint8_t **buf);
int mp_bluetooth_gap_set_device_name(const uint8_t *buf, size_t len);
diff --git a/extmod/nimble/modbluetooth_nimble.c b/extmod/nimble/modbluetooth_nimble.c
index 312a56426..852b9eac0 100644
--- a/extmod/nimble/modbluetooth_nimble.c
+++ b/extmod/nimble/modbluetooth_nimble.c
@@ -552,6 +552,24 @@ void mp_bluetooth_set_address_mode(uint8_t addr_mode) {
}
}
+#if MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
+void mp_bluetooth_set_bonding(bool enabled) {
+ ble_hs_cfg.sm_bonding = enabled;
+}
+
+void mp_bluetooth_set_mitm_protection(bool enabled) {
+ ble_hs_cfg.sm_mitm = enabled;
+}
+
+void mp_bluetooth_set_le_secure(bool enabled) {
+ ble_hs_cfg.sm_sc = enabled;
+}
+
+void mp_bluetooth_set_io_capability(uint8_t capability) {
+ ble_hs_cfg.sm_io_cap = capability;
+}
+#endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
+
size_t mp_bluetooth_gap_get_device_name(const uint8_t **buf) {
const char *name = ble_svc_gap_device_name();
*buf = (const uint8_t *)name;
diff --git a/extmod/nimble/syscfg/syscfg.h b/extmod/nimble/syscfg/syscfg.h
index bef6b3b92..a051a8fef 100644
--- a/extmod/nimble/syscfg/syscfg.h
+++ b/extmod/nimble/syscfg/syscfg.h
@@ -116,18 +116,19 @@ int nimble_sprintf(char *str, const char *fmt, ...);
#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64)
#define MYNEWT_VAL_BLE_MONITOR_UART_DEV ("uart0")
#define MYNEWT_VAL_BLE_RPA_TIMEOUT (300)
-#define MYNEWT_VAL_BLE_SM_BONDING (0)
-#define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_NO_INPUT_OUTPUT)
#define MYNEWT_VAL_BLE_SM_KEYPRESS (0)
#define MYNEWT_VAL_BLE_SM_LEGACY (1)
#define MYNEWT_VAL_BLE_SM_MAX_PROCS (1)
-#define MYNEWT_VAL_BLE_SM_MITM (0)
#define MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG (0)
-#define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (0)
-#define MYNEWT_VAL_BLE_SM_SC (1)
-#define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (0)
+#define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (7)
+#define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (7)
#define MYNEWT_VAL_BLE_STORE_MAX_BONDS (3)
#define MYNEWT_VAL_BLE_STORE_MAX_CCCDS (8)
+// These can be overridden at runtime with ble.config(le_secure, mitm, bond, io).
+#define MYNEWT_VAL_BLE_SM_SC (1)
+#define MYNEWT_VAL_BLE_SM_MITM (0)
+#define MYNEWT_VAL_BLE_SM_BONDING (0)
+#define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_NO_INPUT_OUTPUT)
/*** nimble/host/services/gap */
#define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE (0)