diff options
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r-- | net/bluetooth/mgmt.c | 492 |
1 files changed, 437 insertions, 55 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index a03ca3ca91bf..12fa6399c796 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include "smp.h" | 34 | #include "smp.h" |
35 | 35 | ||
36 | #define MGMT_VERSION 1 | 36 | #define MGMT_VERSION 1 |
37 | #define MGMT_REVISION 4 | 37 | #define MGMT_REVISION 5 |
38 | 38 | ||
39 | static const u16 mgmt_commands[] = { | 39 | static const u16 mgmt_commands[] = { |
40 | MGMT_OP_READ_INDEX_LIST, | 40 | MGMT_OP_READ_INDEX_LIST, |
@@ -79,6 +79,9 @@ static const u16 mgmt_commands[] = { | |||
79 | MGMT_OP_SET_BREDR, | 79 | MGMT_OP_SET_BREDR, |
80 | MGMT_OP_SET_STATIC_ADDRESS, | 80 | MGMT_OP_SET_STATIC_ADDRESS, |
81 | MGMT_OP_SET_SCAN_PARAMS, | 81 | MGMT_OP_SET_SCAN_PARAMS, |
82 | MGMT_OP_SET_SECURE_CONN, | ||
83 | MGMT_OP_SET_DEBUG_KEYS, | ||
84 | MGMT_OP_LOAD_IRKS, | ||
82 | }; | 85 | }; |
83 | 86 | ||
84 | static const u16 mgmt_events[] = { | 87 | static const u16 mgmt_events[] = { |
@@ -127,7 +130,7 @@ static u8 mgmt_status_table[] = { | |||
127 | MGMT_STATUS_FAILED, /* Hardware Failure */ | 130 | MGMT_STATUS_FAILED, /* Hardware Failure */ |
128 | MGMT_STATUS_CONNECT_FAILED, /* Page Timeout */ | 131 | MGMT_STATUS_CONNECT_FAILED, /* Page Timeout */ |
129 | MGMT_STATUS_AUTH_FAILED, /* Authentication Failed */ | 132 | MGMT_STATUS_AUTH_FAILED, /* Authentication Failed */ |
130 | MGMT_STATUS_NOT_PAIRED, /* PIN or Key Missing */ | 133 | MGMT_STATUS_AUTH_FAILED, /* PIN or Key Missing */ |
131 | MGMT_STATUS_NO_RESOURCES, /* Memory Full */ | 134 | MGMT_STATUS_NO_RESOURCES, /* Memory Full */ |
132 | MGMT_STATUS_TIMEOUT, /* Connection Timeout */ | 135 | MGMT_STATUS_TIMEOUT, /* Connection Timeout */ |
133 | MGMT_STATUS_NO_RESOURCES, /* Max Number of Connections */ | 136 | MGMT_STATUS_NO_RESOURCES, /* Max Number of Connections */ |
@@ -363,6 +366,7 @@ static u32 get_supported_settings(struct hci_dev *hdev) | |||
363 | 366 | ||
364 | settings |= MGMT_SETTING_POWERED; | 367 | settings |= MGMT_SETTING_POWERED; |
365 | settings |= MGMT_SETTING_PAIRABLE; | 368 | settings |= MGMT_SETTING_PAIRABLE; |
369 | settings |= MGMT_SETTING_DEBUG_KEYS; | ||
366 | 370 | ||
367 | if (lmp_bredr_capable(hdev)) { | 371 | if (lmp_bredr_capable(hdev)) { |
368 | settings |= MGMT_SETTING_CONNECTABLE; | 372 | settings |= MGMT_SETTING_CONNECTABLE; |
@@ -376,6 +380,10 @@ static u32 get_supported_settings(struct hci_dev *hdev) | |||
376 | settings |= MGMT_SETTING_SSP; | 380 | settings |= MGMT_SETTING_SSP; |
377 | settings |= MGMT_SETTING_HS; | 381 | settings |= MGMT_SETTING_HS; |
378 | } | 382 | } |
383 | |||
384 | if (lmp_sc_capable(hdev) || | ||
385 | test_bit(HCI_FORCE_SC, &hdev->dev_flags)) | ||
386 | settings |= MGMT_SETTING_SECURE_CONN; | ||
379 | } | 387 | } |
380 | 388 | ||
381 | if (lmp_le_capable(hdev)) { | 389 | if (lmp_le_capable(hdev)) { |
@@ -423,6 +431,12 @@ static u32 get_current_settings(struct hci_dev *hdev) | |||
423 | if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) | 431 | if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) |
424 | settings |= MGMT_SETTING_ADVERTISING; | 432 | settings |= MGMT_SETTING_ADVERTISING; |
425 | 433 | ||
434 | if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) | ||
435 | settings |= MGMT_SETTING_SECURE_CONN; | ||
436 | |||
437 | if (test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags)) | ||
438 | settings |= MGMT_SETTING_DEBUG_KEYS; | ||
439 | |||
426 | return settings; | 440 | return settings; |
427 | } | 441 | } |
428 | 442 | ||
@@ -629,14 +643,8 @@ static u8 create_adv_data(struct hci_dev *hdev, u8 *ptr) | |||
629 | 643 | ||
630 | flags |= get_adv_discov_flags(hdev); | 644 | flags |= get_adv_discov_flags(hdev); |
631 | 645 | ||
632 | if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) { | 646 | if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) |
633 | if (lmp_le_br_capable(hdev)) | ||
634 | flags |= LE_AD_SIM_LE_BREDR_CTRL; | ||
635 | if (lmp_host_le_br_capable(hdev)) | ||
636 | flags |= LE_AD_SIM_LE_BREDR_HOST; | ||
637 | } else { | ||
638 | flags |= LE_AD_NO_BREDR; | 647 | flags |= LE_AD_NO_BREDR; |
639 | } | ||
640 | 648 | ||
641 | if (flags) { | 649 | if (flags) { |
642 | BT_DBG("adv flags 0x%02x", flags); | 650 | BT_DBG("adv flags 0x%02x", flags); |
@@ -1366,7 +1374,7 @@ static void enable_advertising(struct hci_request *req) | |||
1366 | cp.max_interval = __constant_cpu_to_le16(0x0800); | 1374 | cp.max_interval = __constant_cpu_to_le16(0x0800); |
1367 | cp.type = get_adv_type(hdev); | 1375 | cp.type = get_adv_type(hdev); |
1368 | cp.own_address_type = hdev->own_addr_type; | 1376 | cp.own_address_type = hdev->own_addr_type; |
1369 | cp.channel_map = 0x07; | 1377 | cp.channel_map = hdev->le_adv_channel_map; |
1370 | 1378 | ||
1371 | hci_req_add(req, HCI_OP_LE_SET_ADV_PARAM, sizeof(cp), &cp); | 1379 | hci_req_add(req, HCI_OP_LE_SET_ADV_PARAM, sizeof(cp), &cp); |
1372 | 1380 | ||
@@ -2065,7 +2073,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2065 | } | 2073 | } |
2066 | 2074 | ||
2067 | if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) { | 2075 | if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) { |
2068 | err = hci_uuids_clear(hdev); | 2076 | hci_uuids_clear(hdev); |
2069 | 2077 | ||
2070 | if (enable_service_cache(hdev)) { | 2078 | if (enable_service_cache(hdev)) { |
2071 | err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID, | 2079 | err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID, |
@@ -2205,6 +2213,7 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2205 | { | 2213 | { |
2206 | struct mgmt_cp_load_link_keys *cp = data; | 2214 | struct mgmt_cp_load_link_keys *cp = data; |
2207 | u16 key_count, expected_len; | 2215 | u16 key_count, expected_len; |
2216 | bool changed; | ||
2208 | int i; | 2217 | int i; |
2209 | 2218 | ||
2210 | BT_DBG("request for %s", hdev->name); | 2219 | BT_DBG("request for %s", hdev->name); |
@@ -2234,7 +2243,7 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2234 | for (i = 0; i < key_count; i++) { | 2243 | for (i = 0; i < key_count; i++) { |
2235 | struct mgmt_link_key_info *key = &cp->keys[i]; | 2244 | struct mgmt_link_key_info *key = &cp->keys[i]; |
2236 | 2245 | ||
2237 | if (key->addr.type != BDADDR_BREDR) | 2246 | if (key->addr.type != BDADDR_BREDR || key->type > 0x08) |
2238 | return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, | 2247 | return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, |
2239 | MGMT_STATUS_INVALID_PARAMS); | 2248 | MGMT_STATUS_INVALID_PARAMS); |
2240 | } | 2249 | } |
@@ -2244,9 +2253,12 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2244 | hci_link_keys_clear(hdev); | 2253 | hci_link_keys_clear(hdev); |
2245 | 2254 | ||
2246 | if (cp->debug_keys) | 2255 | if (cp->debug_keys) |
2247 | set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags); | 2256 | changed = !test_and_set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags); |
2248 | else | 2257 | else |
2249 | clear_bit(HCI_DEBUG_KEYS, &hdev->dev_flags); | 2258 | changed = test_and_clear_bit(HCI_DEBUG_KEYS, &hdev->dev_flags); |
2259 | |||
2260 | if (changed) | ||
2261 | new_settings(hdev, NULL); | ||
2250 | 2262 | ||
2251 | for (i = 0; i < key_count; i++) { | 2263 | for (i = 0; i < key_count; i++) { |
2252 | struct mgmt_link_key_info *key = &cp->keys[i]; | 2264 | struct mgmt_link_key_info *key = &cp->keys[i]; |
@@ -2306,10 +2318,20 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2306 | goto unlock; | 2318 | goto unlock; |
2307 | } | 2319 | } |
2308 | 2320 | ||
2309 | if (cp->addr.type == BDADDR_BREDR) | 2321 | if (cp->addr.type == BDADDR_BREDR) { |
2310 | err = hci_remove_link_key(hdev, &cp->addr.bdaddr); | 2322 | err = hci_remove_link_key(hdev, &cp->addr.bdaddr); |
2311 | else | 2323 | } else { |
2312 | err = hci_remove_ltk(hdev, &cp->addr.bdaddr); | 2324 | u8 addr_type; |
2325 | |||
2326 | if (cp->addr.type == BDADDR_LE_PUBLIC) | ||
2327 | addr_type = ADDR_LE_DEV_PUBLIC; | ||
2328 | else | ||
2329 | addr_type = ADDR_LE_DEV_RANDOM; | ||
2330 | |||
2331 | hci_remove_irk(hdev, &cp->addr.bdaddr, addr_type); | ||
2332 | |||
2333 | err = hci_remove_ltk(hdev, &cp->addr.bdaddr, addr_type); | ||
2334 | } | ||
2313 | 2335 | ||
2314 | if (err < 0) { | 2336 | if (err < 0) { |
2315 | err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, | 2337 | err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, |
@@ -2633,6 +2655,16 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status) | |||
2633 | mgmt_pending_remove(cmd); | 2655 | mgmt_pending_remove(cmd); |
2634 | } | 2656 | } |
2635 | 2657 | ||
2658 | void mgmt_smp_complete(struct hci_conn *conn, bool complete) | ||
2659 | { | ||
2660 | u8 status = complete ? MGMT_STATUS_SUCCESS : MGMT_STATUS_FAILED; | ||
2661 | struct pending_cmd *cmd; | ||
2662 | |||
2663 | cmd = find_pairing(conn); | ||
2664 | if (cmd) | ||
2665 | pairing_complete(cmd, status); | ||
2666 | } | ||
2667 | |||
2636 | static void pairing_complete_cb(struct hci_conn *conn, u8 status) | 2668 | static void pairing_complete_cb(struct hci_conn *conn, u8 status) |
2637 | { | 2669 | { |
2638 | struct pending_cmd *cmd; | 2670 | struct pending_cmd *cmd; |
@@ -2646,7 +2678,7 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status) | |||
2646 | pairing_complete(cmd, mgmt_status(status)); | 2678 | pairing_complete(cmd, mgmt_status(status)); |
2647 | } | 2679 | } |
2648 | 2680 | ||
2649 | static void le_connect_complete_cb(struct hci_conn *conn, u8 status) | 2681 | static void le_pairing_complete_cb(struct hci_conn *conn, u8 status) |
2650 | { | 2682 | { |
2651 | struct pending_cmd *cmd; | 2683 | struct pending_cmd *cmd; |
2652 | 2684 | ||
@@ -2733,13 +2765,16 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2733 | } | 2765 | } |
2734 | 2766 | ||
2735 | /* For LE, just connecting isn't a proof that the pairing finished */ | 2767 | /* For LE, just connecting isn't a proof that the pairing finished */ |
2736 | if (cp->addr.type == BDADDR_BREDR) | 2768 | if (cp->addr.type == BDADDR_BREDR) { |
2737 | conn->connect_cfm_cb = pairing_complete_cb; | 2769 | conn->connect_cfm_cb = pairing_complete_cb; |
2738 | else | 2770 | conn->security_cfm_cb = pairing_complete_cb; |
2739 | conn->connect_cfm_cb = le_connect_complete_cb; | 2771 | conn->disconn_cfm_cb = pairing_complete_cb; |
2772 | } else { | ||
2773 | conn->connect_cfm_cb = le_pairing_complete_cb; | ||
2774 | conn->security_cfm_cb = le_pairing_complete_cb; | ||
2775 | conn->disconn_cfm_cb = le_pairing_complete_cb; | ||
2776 | } | ||
2740 | 2777 | ||
2741 | conn->security_cfm_cb = pairing_complete_cb; | ||
2742 | conn->disconn_cfm_cb = pairing_complete_cb; | ||
2743 | conn->io_capability = cp->io_cap; | 2778 | conn->io_capability = cp->io_cap; |
2744 | cmd->user_data = conn; | 2779 | cmd->user_data = conn; |
2745 | 2780 | ||
@@ -3071,7 +3106,12 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev, | |||
3071 | goto unlock; | 3106 | goto unlock; |
3072 | } | 3107 | } |
3073 | 3108 | ||
3074 | err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL); | 3109 | if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) |
3110 | err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_EXT_DATA, | ||
3111 | 0, NULL); | ||
3112 | else | ||
3113 | err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL); | ||
3114 | |||
3075 | if (err < 0) | 3115 | if (err < 0) |
3076 | mgmt_pending_remove(cmd); | 3116 | mgmt_pending_remove(cmd); |
3077 | 3117 | ||
@@ -3083,23 +3123,46 @@ unlock: | |||
3083 | static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, | 3123 | static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, |
3084 | void *data, u16 len) | 3124 | void *data, u16 len) |
3085 | { | 3125 | { |
3086 | struct mgmt_cp_add_remote_oob_data *cp = data; | ||
3087 | u8 status; | ||
3088 | int err; | 3126 | int err; |
3089 | 3127 | ||
3090 | BT_DBG("%s ", hdev->name); | 3128 | BT_DBG("%s ", hdev->name); |
3091 | 3129 | ||
3092 | hci_dev_lock(hdev); | 3130 | hci_dev_lock(hdev); |
3093 | 3131 | ||
3094 | err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, cp->hash, | 3132 | if (len == MGMT_ADD_REMOTE_OOB_DATA_SIZE) { |
3095 | cp->randomizer); | 3133 | struct mgmt_cp_add_remote_oob_data *cp = data; |
3096 | if (err < 0) | 3134 | u8 status; |
3097 | status = MGMT_STATUS_FAILED; | ||
3098 | else | ||
3099 | status = MGMT_STATUS_SUCCESS; | ||
3100 | 3135 | ||
3101 | err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, status, | 3136 | err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, |
3102 | &cp->addr, sizeof(cp->addr)); | 3137 | cp->hash, cp->randomizer); |
3138 | if (err < 0) | ||
3139 | status = MGMT_STATUS_FAILED; | ||
3140 | else | ||
3141 | status = MGMT_STATUS_SUCCESS; | ||
3142 | |||
3143 | err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, | ||
3144 | status, &cp->addr, sizeof(cp->addr)); | ||
3145 | } else if (len == MGMT_ADD_REMOTE_OOB_EXT_DATA_SIZE) { | ||
3146 | struct mgmt_cp_add_remote_oob_ext_data *cp = data; | ||
3147 | u8 status; | ||
3148 | |||
3149 | err = hci_add_remote_oob_ext_data(hdev, &cp->addr.bdaddr, | ||
3150 | cp->hash192, | ||
3151 | cp->randomizer192, | ||
3152 | cp->hash256, | ||
3153 | cp->randomizer256); | ||
3154 | if (err < 0) | ||
3155 | status = MGMT_STATUS_FAILED; | ||
3156 | else | ||
3157 | status = MGMT_STATUS_SUCCESS; | ||
3158 | |||
3159 | err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, | ||
3160 | status, &cp->addr, sizeof(cp->addr)); | ||
3161 | } else { | ||
3162 | BT_ERR("add_remote_oob_data: invalid length of %u bytes", len); | ||
3163 | err = cmd_status(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, | ||
3164 | MGMT_STATUS_INVALID_PARAMS); | ||
3165 | } | ||
3103 | 3166 | ||
3104 | hci_dev_unlock(hdev); | 3167 | hci_dev_unlock(hdev); |
3105 | return err; | 3168 | return err; |
@@ -3999,15 +4062,219 @@ unlock: | |||
3999 | return err; | 4062 | return err; |
4000 | } | 4063 | } |
4001 | 4064 | ||
4065 | static int set_secure_conn(struct sock *sk, struct hci_dev *hdev, | ||
4066 | void *data, u16 len) | ||
4067 | { | ||
4068 | struct mgmt_mode *cp = data; | ||
4069 | struct pending_cmd *cmd; | ||
4070 | u8 val, status; | ||
4071 | int err; | ||
4072 | |||
4073 | BT_DBG("request for %s", hdev->name); | ||
4074 | |||
4075 | status = mgmt_bredr_support(hdev); | ||
4076 | if (status) | ||
4077 | return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, | ||
4078 | status); | ||
4079 | |||
4080 | if (!lmp_sc_capable(hdev) && | ||
4081 | !test_bit(HCI_FORCE_SC, &hdev->dev_flags)) | ||
4082 | return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, | ||
4083 | MGMT_STATUS_NOT_SUPPORTED); | ||
4084 | |||
4085 | if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02) | ||
4086 | return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, | ||
4087 | MGMT_STATUS_INVALID_PARAMS); | ||
4088 | |||
4089 | hci_dev_lock(hdev); | ||
4090 | |||
4091 | if (!hdev_is_powered(hdev)) { | ||
4092 | bool changed; | ||
4093 | |||
4094 | if (cp->val) { | ||
4095 | changed = !test_and_set_bit(HCI_SC_ENABLED, | ||
4096 | &hdev->dev_flags); | ||
4097 | if (cp->val == 0x02) | ||
4098 | set_bit(HCI_SC_ONLY, &hdev->dev_flags); | ||
4099 | else | ||
4100 | clear_bit(HCI_SC_ONLY, &hdev->dev_flags); | ||
4101 | } else { | ||
4102 | changed = test_and_clear_bit(HCI_SC_ENABLED, | ||
4103 | &hdev->dev_flags); | ||
4104 | clear_bit(HCI_SC_ONLY, &hdev->dev_flags); | ||
4105 | } | ||
4106 | |||
4107 | err = send_settings_rsp(sk, MGMT_OP_SET_SECURE_CONN, hdev); | ||
4108 | if (err < 0) | ||
4109 | goto failed; | ||
4110 | |||
4111 | if (changed) | ||
4112 | err = new_settings(hdev, sk); | ||
4113 | |||
4114 | goto failed; | ||
4115 | } | ||
4116 | |||
4117 | if (mgmt_pending_find(MGMT_OP_SET_SECURE_CONN, hdev)) { | ||
4118 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN, | ||
4119 | MGMT_STATUS_BUSY); | ||
4120 | goto failed; | ||
4121 | } | ||
4122 | |||
4123 | val = !!cp->val; | ||
4124 | |||
4125 | if (val == test_bit(HCI_SC_ENABLED, &hdev->dev_flags) && | ||
4126 | (cp->val == 0x02) == test_bit(HCI_SC_ONLY, &hdev->dev_flags)) { | ||
4127 | err = send_settings_rsp(sk, MGMT_OP_SET_SECURE_CONN, hdev); | ||
4128 | goto failed; | ||
4129 | } | ||
4130 | |||
4131 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_SECURE_CONN, hdev, data, len); | ||
4132 | if (!cmd) { | ||
4133 | err = -ENOMEM; | ||
4134 | goto failed; | ||
4135 | } | ||
4136 | |||
4137 | err = hci_send_cmd(hdev, HCI_OP_WRITE_SC_SUPPORT, 1, &val); | ||
4138 | if (err < 0) { | ||
4139 | mgmt_pending_remove(cmd); | ||
4140 | goto failed; | ||
4141 | } | ||
4142 | |||
4143 | if (cp->val == 0x02) | ||
4144 | set_bit(HCI_SC_ONLY, &hdev->dev_flags); | ||
4145 | else | ||
4146 | clear_bit(HCI_SC_ONLY, &hdev->dev_flags); | ||
4147 | |||
4148 | failed: | ||
4149 | hci_dev_unlock(hdev); | ||
4150 | return err; | ||
4151 | } | ||
4152 | |||
4153 | static int set_debug_keys(struct sock *sk, struct hci_dev *hdev, | ||
4154 | void *data, u16 len) | ||
4155 | { | ||
4156 | struct mgmt_mode *cp = data; | ||
4157 | bool changed; | ||
4158 | int err; | ||
4159 | |||
4160 | BT_DBG("request for %s", hdev->name); | ||
4161 | |||
4162 | if (cp->val != 0x00 && cp->val != 0x01) | ||
4163 | return cmd_status(sk, hdev->id, MGMT_OP_SET_DEBUG_KEYS, | ||
4164 | MGMT_STATUS_INVALID_PARAMS); | ||
4165 | |||
4166 | hci_dev_lock(hdev); | ||
4167 | |||
4168 | if (cp->val) | ||
4169 | changed = !test_and_set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags); | ||
4170 | else | ||
4171 | changed = test_and_clear_bit(HCI_DEBUG_KEYS, &hdev->dev_flags); | ||
4172 | |||
4173 | err = send_settings_rsp(sk, MGMT_OP_SET_DEBUG_KEYS, hdev); | ||
4174 | if (err < 0) | ||
4175 | goto unlock; | ||
4176 | |||
4177 | if (changed) | ||
4178 | err = new_settings(hdev, sk); | ||
4179 | |||
4180 | unlock: | ||
4181 | hci_dev_unlock(hdev); | ||
4182 | return err; | ||
4183 | } | ||
4184 | |||
4185 | static bool irk_is_valid(struct mgmt_irk_info *irk) | ||
4186 | { | ||
4187 | switch (irk->addr.type) { | ||
4188 | case BDADDR_LE_PUBLIC: | ||
4189 | return true; | ||
4190 | |||
4191 | case BDADDR_LE_RANDOM: | ||
4192 | /* Two most significant bits shall be set */ | ||
4193 | if ((irk->addr.bdaddr.b[5] & 0xc0) != 0xc0) | ||
4194 | return false; | ||
4195 | return true; | ||
4196 | } | ||
4197 | |||
4198 | return false; | ||
4199 | } | ||
4200 | |||
4201 | static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, | ||
4202 | u16 len) | ||
4203 | { | ||
4204 | struct mgmt_cp_load_irks *cp = cp_data; | ||
4205 | u16 irk_count, expected_len; | ||
4206 | int i, err; | ||
4207 | |||
4208 | BT_DBG("request for %s", hdev->name); | ||
4209 | |||
4210 | if (!lmp_le_capable(hdev)) | ||
4211 | return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS, | ||
4212 | MGMT_STATUS_NOT_SUPPORTED); | ||
4213 | |||
4214 | irk_count = __le16_to_cpu(cp->irk_count); | ||
4215 | |||
4216 | expected_len = sizeof(*cp) + irk_count * sizeof(struct mgmt_irk_info); | ||
4217 | if (expected_len != len) { | ||
4218 | BT_ERR("load_irks: expected %u bytes, got %u bytes", | ||
4219 | len, expected_len); | ||
4220 | return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS, | ||
4221 | MGMT_STATUS_INVALID_PARAMS); | ||
4222 | } | ||
4223 | |||
4224 | BT_DBG("%s irk_count %u", hdev->name, irk_count); | ||
4225 | |||
4226 | for (i = 0; i < irk_count; i++) { | ||
4227 | struct mgmt_irk_info *key = &cp->irks[i]; | ||
4228 | |||
4229 | if (!irk_is_valid(key)) | ||
4230 | return cmd_status(sk, hdev->id, | ||
4231 | MGMT_OP_LOAD_IRKS, | ||
4232 | MGMT_STATUS_INVALID_PARAMS); | ||
4233 | } | ||
4234 | |||
4235 | hci_dev_lock(hdev); | ||
4236 | |||
4237 | hci_smp_irks_clear(hdev); | ||
4238 | |||
4239 | for (i = 0; i < irk_count; i++) { | ||
4240 | struct mgmt_irk_info *irk = &cp->irks[i]; | ||
4241 | u8 addr_type; | ||
4242 | |||
4243 | if (irk->addr.type == BDADDR_LE_PUBLIC) | ||
4244 | addr_type = ADDR_LE_DEV_PUBLIC; | ||
4245 | else | ||
4246 | addr_type = ADDR_LE_DEV_RANDOM; | ||
4247 | |||
4248 | hci_add_irk(hdev, &irk->addr.bdaddr, addr_type, irk->val, | ||
4249 | BDADDR_ANY); | ||
4250 | } | ||
4251 | |||
4252 | set_bit(HCI_RPA_RESOLVING, &hdev->dev_flags); | ||
4253 | |||
4254 | err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_IRKS, 0, NULL, 0); | ||
4255 | |||
4256 | hci_dev_unlock(hdev); | ||
4257 | |||
4258 | return err; | ||
4259 | } | ||
4260 | |||
4002 | static bool ltk_is_valid(struct mgmt_ltk_info *key) | 4261 | static bool ltk_is_valid(struct mgmt_ltk_info *key) |
4003 | { | 4262 | { |
4004 | if (key->authenticated != 0x00 && key->authenticated != 0x01) | ||
4005 | return false; | ||
4006 | if (key->master != 0x00 && key->master != 0x01) | 4263 | if (key->master != 0x00 && key->master != 0x01) |
4007 | return false; | 4264 | return false; |
4008 | if (!bdaddr_type_is_le(key->addr.type)) | 4265 | |
4009 | return false; | 4266 | switch (key->addr.type) { |
4010 | return true; | 4267 | case BDADDR_LE_PUBLIC: |
4268 | return true; | ||
4269 | |||
4270 | case BDADDR_LE_RANDOM: | ||
4271 | /* Two most significant bits shall be set */ | ||
4272 | if ((key->addr.bdaddr.b[5] & 0xc0) != 0xc0) | ||
4273 | return false; | ||
4274 | return true; | ||
4275 | } | ||
4276 | |||
4277 | return false; | ||
4011 | } | 4278 | } |
4012 | 4279 | ||
4013 | static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, | 4280 | static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, |
@@ -4063,9 +4330,9 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, | |||
4063 | else | 4330 | else |
4064 | type = HCI_SMP_LTK_SLAVE; | 4331 | type = HCI_SMP_LTK_SLAVE; |
4065 | 4332 | ||
4066 | hci_add_ltk(hdev, &key->addr.bdaddr, addr_type, | 4333 | hci_add_ltk(hdev, &key->addr.bdaddr, addr_type, type, |
4067 | type, 0, key->authenticated, key->val, | 4334 | key->type, key->val, key->enc_size, key->ediv, |
4068 | key->enc_size, key->ediv, key->rand); | 4335 | key->rand); |
4069 | } | 4336 | } |
4070 | 4337 | ||
4071 | err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, 0, | 4338 | err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, 0, |
@@ -4115,7 +4382,7 @@ static const struct mgmt_handler { | |||
4115 | { user_passkey_reply, false, MGMT_USER_PASSKEY_REPLY_SIZE }, | 4382 | { user_passkey_reply, false, MGMT_USER_PASSKEY_REPLY_SIZE }, |
4116 | { user_passkey_neg_reply, false, MGMT_USER_PASSKEY_NEG_REPLY_SIZE }, | 4383 | { user_passkey_neg_reply, false, MGMT_USER_PASSKEY_NEG_REPLY_SIZE }, |
4117 | { read_local_oob_data, false, MGMT_READ_LOCAL_OOB_DATA_SIZE }, | 4384 | { read_local_oob_data, false, MGMT_READ_LOCAL_OOB_DATA_SIZE }, |
4118 | { add_remote_oob_data, false, MGMT_ADD_REMOTE_OOB_DATA_SIZE }, | 4385 | { add_remote_oob_data, true, MGMT_ADD_REMOTE_OOB_DATA_SIZE }, |
4119 | { remove_remote_oob_data, false, MGMT_REMOVE_REMOTE_OOB_DATA_SIZE }, | 4386 | { remove_remote_oob_data, false, MGMT_REMOVE_REMOTE_OOB_DATA_SIZE }, |
4120 | { start_discovery, false, MGMT_START_DISCOVERY_SIZE }, | 4387 | { start_discovery, false, MGMT_START_DISCOVERY_SIZE }, |
4121 | { stop_discovery, false, MGMT_STOP_DISCOVERY_SIZE }, | 4388 | { stop_discovery, false, MGMT_STOP_DISCOVERY_SIZE }, |
@@ -4127,6 +4394,10 @@ static const struct mgmt_handler { | |||
4127 | { set_bredr, false, MGMT_SETTING_SIZE }, | 4394 | { set_bredr, false, MGMT_SETTING_SIZE }, |
4128 | { set_static_address, false, MGMT_SET_STATIC_ADDRESS_SIZE }, | 4395 | { set_static_address, false, MGMT_SET_STATIC_ADDRESS_SIZE }, |
4129 | { set_scan_params, false, MGMT_SET_SCAN_PARAMS_SIZE }, | 4396 | { set_scan_params, false, MGMT_SET_SCAN_PARAMS_SIZE }, |
4397 | { set_secure_conn, false, MGMT_SETTING_SIZE }, | ||
4398 | { set_debug_keys, false, MGMT_SETTING_SIZE }, | ||
4399 | { }, | ||
4400 | { load_irks, true, MGMT_LOAD_IRKS_SIZE }, | ||
4130 | }; | 4401 | }; |
4131 | 4402 | ||
4132 | 4403 | ||
@@ -4494,16 +4765,32 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, | |||
4494 | mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL); | 4765 | mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL); |
4495 | } | 4766 | } |
4496 | 4767 | ||
4497 | void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent) | 4768 | void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key) |
4498 | { | 4769 | { |
4499 | struct mgmt_ev_new_long_term_key ev; | 4770 | struct mgmt_ev_new_long_term_key ev; |
4500 | 4771 | ||
4501 | memset(&ev, 0, sizeof(ev)); | 4772 | memset(&ev, 0, sizeof(ev)); |
4502 | 4773 | ||
4503 | ev.store_hint = persistent; | 4774 | /* Devices using resolvable or non-resolvable random addresses |
4775 | * without providing an indentity resolving key don't require | ||
4776 | * to store long term keys. Their addresses will change the | ||
4777 | * next time around. | ||
4778 | * | ||
4779 | * Only when a remote device provides an identity address | ||
4780 | * make sure the long term key is stored. If the remote | ||
4781 | * identity is known, the long term keys are internally | ||
4782 | * mapped to the identity address. So allow static random | ||
4783 | * and public addresses here. | ||
4784 | */ | ||
4785 | if (key->bdaddr_type == ADDR_LE_DEV_RANDOM && | ||
4786 | (key->bdaddr.b[5] & 0xc0) != 0xc0) | ||
4787 | ev.store_hint = 0x00; | ||
4788 | else | ||
4789 | ev.store_hint = 0x01; | ||
4790 | |||
4504 | bacpy(&ev.key.addr.bdaddr, &key->bdaddr); | 4791 | bacpy(&ev.key.addr.bdaddr, &key->bdaddr); |
4505 | ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type); | 4792 | ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type); |
4506 | ev.key.authenticated = key->authenticated; | 4793 | ev.key.type = key->authenticated; |
4507 | ev.key.enc_size = key->enc_size; | 4794 | ev.key.enc_size = key->enc_size; |
4508 | ev.key.ediv = key->ediv; | 4795 | ev.key.ediv = key->ediv; |
4509 | 4796 | ||
@@ -4516,6 +4803,36 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent) | |||
4516 | mgmt_event(MGMT_EV_NEW_LONG_TERM_KEY, hdev, &ev, sizeof(ev), NULL); | 4803 | mgmt_event(MGMT_EV_NEW_LONG_TERM_KEY, hdev, &ev, sizeof(ev), NULL); |
4517 | } | 4804 | } |
4518 | 4805 | ||
4806 | void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk) | ||
4807 | { | ||
4808 | struct mgmt_ev_new_irk ev; | ||
4809 | |||
4810 | memset(&ev, 0, sizeof(ev)); | ||
4811 | |||
4812 | /* For identity resolving keys from devices that are already | ||
4813 | * using a public address or static random address, do not | ||
4814 | * ask for storing this key. The identity resolving key really | ||
4815 | * is only mandatory for devices using resovlable random | ||
4816 | * addresses. | ||
4817 | * | ||
4818 | * Storing all identity resolving keys has the downside that | ||
4819 | * they will be also loaded on next boot of they system. More | ||
4820 | * identity resolving keys, means more time during scanning is | ||
4821 | * needed to actually resolve these addresses. | ||
4822 | */ | ||
4823 | if (bacmp(&irk->rpa, BDADDR_ANY)) | ||
4824 | ev.store_hint = 0x01; | ||
4825 | else | ||
4826 | ev.store_hint = 0x00; | ||
4827 | |||
4828 | bacpy(&ev.rpa, &irk->rpa); | ||
4829 | bacpy(&ev.irk.addr.bdaddr, &irk->bdaddr); | ||
4830 | ev.irk.addr.type = link_to_bdaddr(LE_LINK, irk->addr_type); | ||
4831 | memcpy(ev.irk.val, irk->val, sizeof(irk->val)); | ||
4832 | |||
4833 | mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL); | ||
4834 | } | ||
4835 | |||
4519 | static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data, | 4836 | static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data, |
4520 | u8 data_len) | 4837 | u8 data_len) |
4521 | { | 4838 | { |
@@ -4910,6 +5227,43 @@ void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status) | |||
4910 | hci_req_run(&req, NULL); | 5227 | hci_req_run(&req, NULL); |
4911 | } | 5228 | } |
4912 | 5229 | ||
5230 | void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status) | ||
5231 | { | ||
5232 | struct cmd_lookup match = { NULL, hdev }; | ||
5233 | bool changed = false; | ||
5234 | |||
5235 | if (status) { | ||
5236 | u8 mgmt_err = mgmt_status(status); | ||
5237 | |||
5238 | if (enable) { | ||
5239 | if (test_and_clear_bit(HCI_SC_ENABLED, | ||
5240 | &hdev->dev_flags)) | ||
5241 | new_settings(hdev, NULL); | ||
5242 | clear_bit(HCI_SC_ONLY, &hdev->dev_flags); | ||
5243 | } | ||
5244 | |||
5245 | mgmt_pending_foreach(MGMT_OP_SET_SECURE_CONN, hdev, | ||
5246 | cmd_status_rsp, &mgmt_err); | ||
5247 | return; | ||
5248 | } | ||
5249 | |||
5250 | if (enable) { | ||
5251 | changed = !test_and_set_bit(HCI_SC_ENABLED, &hdev->dev_flags); | ||
5252 | } else { | ||
5253 | changed = test_and_clear_bit(HCI_SC_ENABLED, &hdev->dev_flags); | ||
5254 | clear_bit(HCI_SC_ONLY, &hdev->dev_flags); | ||
5255 | } | ||
5256 | |||
5257 | mgmt_pending_foreach(MGMT_OP_SET_SECURE_CONN, hdev, | ||
5258 | settings_rsp, &match); | ||
5259 | |||
5260 | if (changed) | ||
5261 | new_settings(hdev, match.sk); | ||
5262 | |||
5263 | if (match.sk) | ||
5264 | sock_put(match.sk); | ||
5265 | } | ||
5266 | |||
4913 | static void sk_lookup(struct pending_cmd *cmd, void *data) | 5267 | static void sk_lookup(struct pending_cmd *cmd, void *data) |
4914 | { | 5268 | { |
4915 | struct cmd_lookup *match = data; | 5269 | struct cmd_lookup *match = data; |
@@ -4964,8 +5318,9 @@ void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) | |||
4964 | cmd ? cmd->sk : NULL); | 5318 | cmd ? cmd->sk : NULL); |
4965 | } | 5319 | } |
4966 | 5320 | ||
4967 | void mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, | 5321 | void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, |
4968 | u8 *randomizer, u8 status) | 5322 | u8 *randomizer192, u8 *hash256, |
5323 | u8 *randomizer256, u8 status) | ||
4969 | { | 5324 | { |
4970 | struct pending_cmd *cmd; | 5325 | struct pending_cmd *cmd; |
4971 | 5326 | ||
@@ -4979,13 +5334,32 @@ void mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, | |||
4979 | cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, | 5334 | cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, |
4980 | mgmt_status(status)); | 5335 | mgmt_status(status)); |
4981 | } else { | 5336 | } else { |
4982 | struct mgmt_rp_read_local_oob_data rp; | 5337 | if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags) && |
5338 | hash256 && randomizer256) { | ||
5339 | struct mgmt_rp_read_local_oob_ext_data rp; | ||
5340 | |||
5341 | memcpy(rp.hash192, hash192, sizeof(rp.hash192)); | ||
5342 | memcpy(rp.randomizer192, randomizer192, | ||
5343 | sizeof(rp.randomizer192)); | ||
4983 | 5344 | ||
4984 | memcpy(rp.hash, hash, sizeof(rp.hash)); | 5345 | memcpy(rp.hash256, hash256, sizeof(rp.hash256)); |
4985 | memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer)); | 5346 | memcpy(rp.randomizer256, randomizer256, |
5347 | sizeof(rp.randomizer256)); | ||
5348 | |||
5349 | cmd_complete(cmd->sk, hdev->id, | ||
5350 | MGMT_OP_READ_LOCAL_OOB_DATA, 0, | ||
5351 | &rp, sizeof(rp)); | ||
5352 | } else { | ||
5353 | struct mgmt_rp_read_local_oob_data rp; | ||
4986 | 5354 | ||
4987 | cmd_complete(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, | 5355 | memcpy(rp.hash, hash192, sizeof(rp.hash)); |
4988 | 0, &rp, sizeof(rp)); | 5356 | memcpy(rp.randomizer, randomizer192, |
5357 | sizeof(rp.randomizer)); | ||
5358 | |||
5359 | cmd_complete(cmd->sk, hdev->id, | ||
5360 | MGMT_OP_READ_LOCAL_OOB_DATA, 0, | ||
5361 | &rp, sizeof(rp)); | ||
5362 | } | ||
4989 | } | 5363 | } |
4990 | 5364 | ||
4991 | mgmt_pending_remove(cmd); | 5365 | mgmt_pending_remove(cmd); |
@@ -4997,6 +5371,7 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
4997 | { | 5371 | { |
4998 | char buf[512]; | 5372 | char buf[512]; |
4999 | struct mgmt_ev_device_found *ev = (void *) buf; | 5373 | struct mgmt_ev_device_found *ev = (void *) buf; |
5374 | struct smp_irk *irk; | ||
5000 | size_t ev_size; | 5375 | size_t ev_size; |
5001 | 5376 | ||
5002 | if (!hci_discovery_active(hdev)) | 5377 | if (!hci_discovery_active(hdev)) |
@@ -5008,8 +5383,15 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
5008 | 5383 | ||
5009 | memset(buf, 0, sizeof(buf)); | 5384 | memset(buf, 0, sizeof(buf)); |
5010 | 5385 | ||
5011 | bacpy(&ev->addr.bdaddr, bdaddr); | 5386 | irk = hci_get_irk(hdev, bdaddr, addr_type); |
5012 | ev->addr.type = link_to_bdaddr(link_type, addr_type); | 5387 | if (irk) { |
5388 | bacpy(&ev->addr.bdaddr, &irk->bdaddr); | ||
5389 | ev->addr.type = link_to_bdaddr(link_type, irk->addr_type); | ||
5390 | } else { | ||
5391 | bacpy(&ev->addr.bdaddr, bdaddr); | ||
5392 | ev->addr.type = link_to_bdaddr(link_type, addr_type); | ||
5393 | } | ||
5394 | |||
5013 | ev->rssi = rssi; | 5395 | ev->rssi = rssi; |
5014 | if (cfm_name) | 5396 | if (cfm_name) |
5015 | ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME); | 5397 | ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME); |