diff options
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/6lowpan.c | 11 | ||||
-rw-r--r-- | net/bluetooth/Kconfig | 9 | ||||
-rw-r--r-- | net/bluetooth/Makefile | 1 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 17 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 7 | ||||
-rw-r--r-- | net/bluetooth/hci_request.c | 56 | ||||
-rw-r--r-- | net/bluetooth/hci_request.h | 2 | ||||
-rw-r--r-- | net/bluetooth/leds.c | 74 | ||||
-rw-r--r-- | net/bluetooth/leds.h | 16 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 22 | ||||
-rw-r--r-- | net/bluetooth/smp.c | 135 |
11 files changed, 257 insertions, 93 deletions
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 8a4cc2f7f..e45cb9155 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -431,15 +431,18 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev, bdaddr_t *peer_addr, u8 *peer_addr_type) { struct in6_addr ipv6_daddr; + struct ipv6hdr *hdr; struct lowpan_dev *dev; struct lowpan_peer *peer; bdaddr_t addr, *any = BDADDR_ANY; u8 *daddr = any->b; int err, status = 0; + hdr = ipv6_hdr(skb); + dev = lowpan_dev(netdev); - memcpy(&ipv6_daddr, &lowpan_cb(skb)->addr, sizeof(ipv6_daddr)); + memcpy(&ipv6_daddr, &hdr->daddr, sizeof(ipv6_daddr)); if (ipv6_addr_is_multicast(&ipv6_daddr)) { lowpan_cb(skb)->chan = NULL; @@ -489,15 +492,9 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev, unsigned short type, const void *_daddr, const void *_saddr, unsigned int len) { - struct ipv6hdr *hdr; - if (type != ETH_P_IPV6) return -EINVAL; - hdr = ipv6_hdr(skb); - - memcpy(&lowpan_cb(skb)->addr, &hdr->daddr, sizeof(struct in6_addr)); - return 0; } diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 95d1a66ba..06c31b9a6 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -69,6 +69,15 @@ config BT_6LOWPAN help IPv6 compression over Bluetooth Low Energy. +config BT_LEDS + bool "Enable LED triggers" + depends on BT + depends on LEDS_CLASS + select LEDS_TRIGGERS + help + This option selects a few LED triggers for different + Bluetooth events. + config BT_SELFTEST bool "Bluetooth self testing support" depends on BT && DEBUG_KERNEL diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index 2b15ae8c1..b3ff12eb9 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile @@ -17,6 +17,7 @@ bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \ bluetooth-$(CONFIG_BT_BREDR) += sco.o bluetooth-$(CONFIG_BT_HS) += a2mp.o amp.o +bluetooth-$(CONFIG_BT_LEDS) += leds.o bluetooth-$(CONFIG_BT_DEBUGFS) += hci_debugfs.o bluetooth-$(CONFIG_BT_SELFTEST) += selftest.o diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 32575b49f..bf9f8a801 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -719,6 +719,13 @@ done: hci_dev_unlock(hdev); } +static bool conn_use_rpa(struct hci_conn *conn) +{ + struct hci_dev *hdev = conn->hdev; + + return hci_dev_test_flag(hdev, HCI_PRIVACY); +} + static void hci_req_add_le_create_conn(struct hci_request *req, struct hci_conn *conn) { @@ -726,14 +733,15 @@ static void hci_req_add_le_create_conn(struct hci_request *req, struct hci_dev *hdev = conn->hdev; u8 own_addr_type; - memset(&cp, 0, sizeof(cp)); - /* Update random address, but set require_privacy to false so * that we never connect with an non-resolvable address. */ - if (hci_update_random_address(req, false, &own_addr_type)) + if (hci_update_random_address(req, false, conn_use_rpa(conn), + &own_addr_type)) return; + memset(&cp, 0, sizeof(cp)); + /* Set window to be the same value as the interval to enable * continuous scanning. */ @@ -774,7 +782,8 @@ static void hci_req_directed_advertising(struct hci_request *req, /* Set require_privacy to false so that the remote device has a * chance of identifying us. */ - if (hci_update_random_address(req, false, &own_addr_type) < 0) + if (hci_update_random_address(req, false, conn_use_rpa(conn), + &own_addr_type) < 0) return; memset(&cp, 0, sizeof(cp)); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 883c821a9..2713fc86e 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -40,6 +40,7 @@ #include "hci_request.h" #include "hci_debugfs.h" #include "smp.h" +#include "leds.h" static void hci_rx_work(struct work_struct *work); static void hci_cmd_work(struct work_struct *work); @@ -1395,6 +1396,7 @@ static int hci_dev_do_open(struct hci_dev *hdev) hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); set_bit(HCI_UP, &hdev->flags); hci_sock_dev_event(hdev, HCI_DEV_UP); + hci_leds_update_powered(hdev, true); if (!hci_dev_test_flag(hdev, HCI_SETUP) && !hci_dev_test_flag(hdev, HCI_CONFIG) && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && @@ -1532,6 +1534,8 @@ int hci_dev_do_close(struct hci_dev *hdev) return 0; } + hci_leds_update_powered(hdev, false); + /* Flush RX and TX works */ flush_work(&hdev->tx_work); flush_work(&hdev->rx_work); @@ -2017,6 +2021,7 @@ static void hci_power_on(struct work_struct *work) if (test_bit(HCI_UP, &hdev->flags) && hci_dev_test_flag(hdev, HCI_MGMT) && hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) { + cancel_delayed_work(&hdev->power_off); hci_req_sync_lock(hdev); err = __hci_req_hci_power_on(hdev); hci_req_sync_unlock(hdev); @@ -3067,6 +3072,8 @@ int hci_register_dev(struct hci_dev *hdev) if (error < 0) goto err_wqueue; + hci_leds_init(hdev); + hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index c78ee2dc9..6e125d76d 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -771,6 +771,11 @@ static u8 update_white_list(struct hci_request *req) return 0x01; } +static bool scan_use_rpa(struct hci_dev *hdev) +{ + return hci_dev_test_flag(hdev, HCI_PRIVACY); +} + void hci_req_add_le_passive_scan(struct hci_request *req) { struct hci_cp_le_set_scan_param param_cp; @@ -785,7 +790,8 @@ void hci_req_add_le_passive_scan(struct hci_request *req) * advertising with our address will be correctly reported * by the controller. */ - if (hci_update_random_address(req, false, &own_addr_type)) + if (hci_update_random_address(req, false, scan_use_rpa(hdev), + &own_addr_type)) return; /* Adding or removing entries from the white list must @@ -866,6 +872,11 @@ static u32 get_adv_instance_flags(struct hci_dev *hdev, u8 instance) if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE)) flags |= MGMT_ADV_FLAG_CONNECTABLE; + if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE)) + flags |= MGMT_ADV_FLAG_LIMITED_DISCOV; + else if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE)) + flags |= MGMT_ADV_FLAG_DISCOV; + return flags; } @@ -878,6 +889,29 @@ static u32 get_adv_instance_flags(struct hci_dev *hdev, u8 instance) return adv_instance->flags; } +static bool adv_use_rpa(struct hci_dev *hdev, uint32_t flags) +{ + /* If privacy is not enabled don't use RPA */ + if (!hci_dev_test_flag(hdev, HCI_PRIVACY)) + return false; + + /* If basic privacy mode is enabled use RPA */ + if (!hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY)) + return true; + + /* If limited privacy mode is enabled don't use RPA if we're + * both discoverable and bondable. + */ + if ((flags & MGMT_ADV_FLAG_DISCOV) && + hci_dev_test_flag(hdev, HCI_BONDABLE)) + return false; + + /* We're neither bondable nor discoverable in the limited + * privacy mode, therefore use RPA. + */ + return true; +} + void __hci_req_enable_advertising(struct hci_request *req) { struct hci_dev *hdev = req->hdev; @@ -911,7 +945,9 @@ void __hci_req_enable_advertising(struct hci_request *req) * advertising is used. In that case it is fine to use a * non-resolvable private address. */ - if (hci_update_random_address(req, !connectable, &own_addr_type) < 0) + if (hci_update_random_address(req, !connectable, + adv_use_rpa(hdev, flags), + &own_addr_type) < 0) return; memset(&cp, 0, sizeof(cp)); @@ -1325,7 +1361,7 @@ static void set_random_addr(struct hci_request *req, bdaddr_t *rpa) } int hci_update_random_address(struct hci_request *req, bool require_privacy, - u8 *own_addr_type) + bool use_rpa, u8 *own_addr_type) { struct hci_dev *hdev = req->hdev; int err; @@ -1334,7 +1370,7 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy, * current RPA has expired or there is something else than * the current RPA in use, then generate a new one. */ - if (hci_dev_test_flag(hdev, HCI_PRIVACY)) { + if (use_rpa) { int to; *own_addr_type = ADDR_LE_DEV_RANDOM; @@ -1596,9 +1632,16 @@ static int discoverable_update(struct hci_request *req, unsigned long opt) /* Advertising instances don't use the global discoverable setting, so * only update AD if advertising was enabled using Set Advertising. */ - if (hci_dev_test_flag(hdev, HCI_ADVERTISING)) + if (hci_dev_test_flag(hdev, HCI_ADVERTISING)) { __hci_req_update_adv_data(req, 0x00); + /* Discoverable mode affects the local advertising + * address in limited privacy mode. + */ + if (hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY)) + __hci_req_enable_advertising(req); + } + hci_dev_unlock(hdev); return 0; @@ -1941,7 +1984,8 @@ static int active_scan(struct hci_request *req, unsigned long opt) * address (when privacy feature has been enabled) or non-resolvable * private address. */ - err = hci_update_random_address(req, true, &own_addr_type); + err = hci_update_random_address(req, true, scan_use_rpa(hdev), + &own_addr_type); if (err < 0) own_addr_type = ADDR_LE_DEV_PUBLIC; diff --git a/net/bluetooth/hci_request.h b/net/bluetooth/hci_request.h index 64ff8c040..b2d044bdc 100644 --- a/net/bluetooth/hci_request.h +++ b/net/bluetooth/hci_request.h @@ -89,7 +89,7 @@ static inline void hci_req_update_scan(struct hci_dev *hdev) void __hci_req_update_scan(struct hci_request *req); int hci_update_random_address(struct hci_request *req, bool require_privacy, - u8 *own_addr_type); + bool use_rpa, u8 *own_addr_type); int hci_abort_conn(struct hci_conn *conn, u8 reason); void __hci_abort_conn(struct hci_request *req, struct hci_conn *conn, diff --git a/net/bluetooth/leds.c b/net/bluetooth/leds.c new file mode 100644 index 000000000..8319c8440 --- /dev/null +++ b/net/bluetooth/leds.c @@ -0,0 +1,74 @@ +/* + * Copyright 2015, Heiner Kallweit <hkallweit1@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <net/bluetooth/bluetooth.h> +#include <net/bluetooth/hci_core.h> + +#include "leds.h" + +struct hci_basic_led_trigger { + struct led_trigger led_trigger; + struct hci_dev *hdev; +}; + +#define to_hci_basic_led_trigger(arg) container_of(arg, \ + struct hci_basic_led_trigger, led_trigger) + +void hci_leds_update_powered(struct hci_dev *hdev, bool enabled) +{ + if (hdev->power_led) + led_trigger_event(hdev->power_led, + enabled ? LED_FULL : LED_OFF); +} + +static void power_activate(struct led_classdev *led_cdev) +{ + struct hci_basic_led_trigger *htrig; + bool powered; + + htrig = to_hci_basic_led_trigger(led_cdev->trigger); + powered = test_bit(HCI_UP, &htrig->hdev->flags); + + led_trigger_event(led_cdev->trigger, powered ? LED_FULL : LED_OFF); +} + +static struct led_trigger *led_allocate_basic(struct hci_dev *hdev, + void (*activate)(struct led_classdev *led_cdev), + const char *name) +{ + struct hci_basic_led_trigger *htrig; + + htrig = devm_kzalloc(&hdev->dev, sizeof(*htrig), GFP_KERNEL); + if (!htrig) + return NULL; + + htrig->hdev = hdev; + htrig->led_trigger.activate = activate; + htrig->led_trigger.name = devm_kasprintf(&hdev->dev, GFP_KERNEL, + "%s-%s", hdev->name, + name); + if (!htrig->led_trigger.name) + goto err_alloc; + + if (devm_led_trigger_register(&hdev->dev, &htrig->led_trigger)) + goto err_register; + + return &htrig->led_trigger; + +err_register: + devm_kfree(&hdev->dev, (void *)htrig->led_trigger.name); +err_alloc: + devm_kfree(&hdev->dev, htrig); + return NULL; +} + +void hci_leds_init(struct hci_dev *hdev) +{ + /* initialize power_led */ + hdev->power_led = led_allocate_basic(hdev, power_activate, "power"); +} diff --git a/net/bluetooth/leds.h b/net/bluetooth/leds.h new file mode 100644 index 000000000..a9c4d6ea0 --- /dev/null +++ b/net/bluetooth/leds.h @@ -0,0 +1,16 @@ +/* + * Copyright 2015, Heiner Kallweit <hkallweit1@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#if IS_ENABLED(CONFIG_BT_LEDS) +void hci_leds_update_powered(struct hci_dev *hdev, bool enabled); +void hci_leds_init(struct hci_dev *hdev); +#else +static inline void hci_leds_update_powered(struct hci_dev *hdev, + bool enabled) {} +static inline void hci_leds_init(struct hci_dev *hdev) {} +#endif diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 1363b8ffd..9e4b93158 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -38,7 +38,7 @@ #include "mgmt_util.h" #define MGMT_VERSION 1 -#define MGMT_REVISION 11 +#define MGMT_REVISION 12 static const u16 mgmt_commands[] = { MGMT_OP_READ_INDEX_LIST, @@ -1382,8 +1382,19 @@ static int set_bondable(struct sock *sk, struct hci_dev *hdev, void *data, if (err < 0) goto unlock; - if (changed) + if (changed) { + /* In limited privacy mode the change of bondable mode + * may affect the local advertising address. + */ + if (hdev_is_powered(hdev) && + hci_dev_test_flag(hdev, HCI_ADVERTISING) && + hci_dev_test_flag(hdev, HCI_DISCOVERABLE) && + hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY)) + queue_work(hdev->req_workqueue, + &hdev->discoverable_update); + err = new_settings(hdev, sk); + } unlock: hci_dev_unlock(hdev); @@ -4423,7 +4434,7 @@ static int set_privacy(struct sock *sk, struct hci_dev *hdev, void *cp_data, return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY, MGMT_STATUS_NOT_SUPPORTED); - if (cp->privacy != 0x00 && cp->privacy != 0x01) + if (cp->privacy != 0x00 && cp->privacy != 0x01 && cp->privacy != 0x02) return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY, MGMT_STATUS_INVALID_PARAMS); @@ -4442,10 +4453,15 @@ static int set_privacy(struct sock *sk, struct hci_dev *hdev, void *cp_data, changed = !hci_dev_test_and_set_flag(hdev, HCI_PRIVACY); memcpy(hdev->irk, cp->irk, sizeof(hdev->irk)); hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); + if (cp->privacy == 0x02) + hci_dev_set_flag(hdev, HCI_LIMITED_PRIVACY); + else + hci_dev_clear_flag(hdev, HCI_LIMITED_PRIVACY); } else { changed = hci_dev_test_and_clear_flag(hdev, HCI_PRIVACY); memset(hdev->irk, 0, sizeof(hdev->irk)); hci_dev_clear_flag(hdev, HCI_RPA_EXPIRED); + hci_dev_clear_flag(hdev, HCI_LIMITED_PRIVACY); } err = send_settings_rsp(sk, MGMT_OP_SET_PRIVACY, hdev); diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 4b175df35..50976a648 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -21,9 +21,10 @@ */ #include <linux/debugfs.h> -#include <linux/crypto.h> #include <linux/scatterlist.h> #include <crypto/b128ops.h> +#include <crypto/hash.h> +#include <crypto/skcipher.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> @@ -87,8 +88,8 @@ struct smp_dev { u8 min_key_size; u8 max_key_size; - struct crypto_blkcipher *tfm_aes; - struct crypto_hash *tfm_cmac; + struct crypto_skcipher *tfm_aes; + struct crypto_shash *tfm_cmac; }; struct smp_chan { @@ -126,8 +127,8 @@ struct smp_chan { u8 dhkey[32]; u8 mackey[16]; - struct crypto_blkcipher *tfm_aes; - struct crypto_hash *tfm_cmac; + struct crypto_skcipher *tfm_aes; + struct crypto_shash *tfm_cmac; }; /* These debug key values are defined in the SMP section of the core @@ -165,12 +166,11 @@ static inline void swap_buf(const u8 *src, u8 *dst, size_t len) * AES-CMAC, f4, f5, f6, g2 and h6. */ -static int aes_cmac(struct crypto_hash *tfm, const u8 k[16], const u8 *m, +static int aes_cmac(struct crypto_shash *tfm, const u8 k[16], const u8 *m, size_t len, u8 mac[16]) { uint8_t tmp[16], mac_msb[16], msg_msb[CMAC_MSG_MAX]; - struct hash_desc desc; - struct scatterlist sg; + SHASH_DESC_ON_STACK(desc, tfm); int err; if (len > CMAC_MSG_MAX) @@ -181,10 +181,8 @@ static int aes_cmac(struct crypto_hash *tfm, const u8 k[16], const u8 *m, return -EINVAL; } - desc.tfm = tfm; - desc.flags = 0; - - crypto_hash_init(&desc); + desc->tfm = tfm; + desc->flags = 0; /* Swap key and message from LSB to MSB */ swap_buf(k, tmp, 16); @@ -193,23 +191,16 @@ static int aes_cmac(struct crypto_hash *tfm, const u8 k[16], const u8 *m, SMP_DBG("msg (len %zu) %*phN", len, (int) len, m); SMP_DBG("key %16phN", k); - err = crypto_hash_setkey(tfm, tmp, 16); + err = crypto_shash_setkey(tfm, tmp, 16); if (err) { BT_ERR("cipher setkey failed: %d", err); return err; } - sg_init_one(&sg, msg_msb, len); - - err = crypto_hash_update(&desc, &sg, len); + err = crypto_shash_digest(desc, msg_msb, len, mac_msb); + shash_desc_zero(desc); if (err) { - BT_ERR("Hash update error %d", err); - return err; - } - - err = crypto_hash_final(&desc, mac_msb); - if (err) { - BT_ERR("Hash final error %d", err); + BT_ERR("Hash computation error %d", err); return err; } @@ -220,8 +211,8 @@ static int aes_cmac(struct crypto_hash *tfm, const u8 k[16], const u8 *m, return 0; } -static int smp_f4(struct crypto_hash *tfm_cmac, const u8 u[32], const u8 v[32], - const u8 x[16], u8 z, u8 res[16]) +static int smp_f4(struct crypto_shash *tfm_cmac, const u8 u[32], + const u8 v[32], const u8 x[16], u8 z, u8 res[16]) { u8 m[65]; int err; @@ -243,7 +234,7 @@ static int smp_f4(struct crypto_hash *tfm_cmac, const u8 u[32], const u8 v[32], return err; } -static int smp_f5(struct crypto_hash *tfm_cmac, const u8 w[32], +static int smp_f5(struct crypto_shash *tfm_cmac, const u8 w[32], const u8 n1[16], const u8 n2[16], const u8 a1[7], const u8 a2[7], u8 mackey[16], u8 ltk[16]) { @@ -296,7 +287,7 @@ static int smp_f5(struct crypto_hash *tfm_cmac, const u8 w[32], return 0; } -static int smp_f6(struct crypto_hash *tfm_cmac, const u8 w[16], +static int smp_f6(struct crypto_shash *tfm_cmac, const u8 w[16], const u8 n1[16], const u8 n2[16], const u8 r[16], const u8 io_cap[3], const u8 a1[7], const u8 a2[7], u8 res[16]) @@ -324,7 +315,7 @@ static int smp_f6(struct crypto_hash *tfm_cmac, const u8 w[16], return err; } -static int smp_g2(struct crypto_hash *tfm_cmac, const u8 u[32], const u8 v[32], +static int smp_g2(struct crypto_shash *tfm_cmac, const u8 u[32], const u8 v[32], const u8 x[16], const u8 y[16], u32 *val) { u8 m[80], tmp[16]; @@ -350,7 +341,7 @@ static int smp_g2(struct crypto_hash *tfm_cmac, const u8 u[32], const u8 v[32], return 0; } -static int smp_h6(struct crypto_hash *tfm_cmac, const u8 w[16], +static int smp_h6(struct crypto_shash *tfm_cmac, const u8 w[16], const u8 key_id[4], u8 res[16]) { int err; @@ -370,9 +361,9 @@ static int smp_h6(struct crypto_hash *tfm_cmac, const u8 w[16], * s1 and ah. */ -static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) +static int smp_e(struct crypto_skcipher *tfm, const u8 *k, u8 *r) { - struct blkcipher_desc desc; + SKCIPHER_REQUEST_ON_STACK(req, tfm); struct scatterlist sg; uint8_t tmp[16], data[16]; int err; @@ -384,13 +375,10 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) return -EINVAL; } - desc.tfm = tfm; - desc.flags = 0; - /* The most significant octet of key corresponds to k[0] */ swap_buf(k, tmp, 16); - err = crypto_blkcipher_setkey(tfm, tmp, 16); + err = crypto_skcipher_setkey(tfm, tmp, 16); if (err) { BT_ERR("cipher setkey failed: %d", err); return err; @@ -401,7 +389,12 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) sg_init_one(&sg, data, 16); - err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16); + skcipher_request_set_tfm(req, tfm); + skcipher_request_set_callback(req, 0, NULL, NULL); + skcipher_request_set_crypt(req, &sg, &sg, 16, NULL); + + err = crypto_skcipher_encrypt(req); + skcipher_request_zero(req); if (err) BT_ERR("Encrypt data error %d", err); @@ -413,7 +406,7 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) return err; } -static int smp_c1(struct crypto_blkcipher *tfm_aes, const u8 k[16], +static int smp_c1(struct crypto_skcipher *tfm_aes, const u8 k[16], const u8 r[16], const u8 preq[7], const u8 pres[7], u8 _iat, const bdaddr_t *ia, u8 _rat, const bdaddr_t *ra, u8 res[16]) { @@ -462,7 +455,7 @@ static int smp_c1(struct crypto_blkcipher *tfm_aes, const u8 k[16], return err; } -static int smp_s1(struct crypto_blkcipher *tfm_aes, const u8 k[16], +static int smp_s1(struct crypto_skcipher *tfm_aes, const u8 k[16], const u8 r1[16], const u8 r2[16], u8 _r[16]) { int err; @@ -478,7 +471,7 @@ static int smp_s1(struct crypto_blkcipher *tfm_aes, const u8 k[16], return err; } -static int smp_ah(struct crypto_blkcipher *tfm, const u8 irk[16], +static int smp_ah(struct crypto_skcipher *tfm, const u8 irk[16], const u8 r[3], u8 res[3]) { u8 _res[16]; @@ -766,8 +759,8 @@ static void smp_chan_destroy(struct l2cap_conn *conn) kzfree(smp->slave_csrk); kzfree(smp->link_key); - crypto_free_blkcipher(smp->tfm_aes); - crypto_free_hash(smp->tfm_cmac); + crypto_free_skcipher(smp->tfm_aes); + crypto_free_shash(smp->tfm_cmac); /* Ensure that we don't leave any debug key around if debug key * support hasn't been explicitly enabled. @@ -1366,17 +1359,17 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) if (!smp) return NULL; - smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); + smp->tfm_aes = crypto_alloc_skcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(smp->tfm_aes)) { BT_ERR("Unable to create ECB crypto context"); kzfree(smp); return NULL; } - smp->tfm_cmac = crypto_alloc_hash("cmac(aes)", 0, CRYPTO_ALG_ASYNC); + smp->tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0); if (IS_ERR(smp->tfm_cmac)) { BT_ERR("Unable to create CMAC crypto context"); - crypto_free_blkcipher(smp->tfm_aes); + crypto_free_skcipher(smp->tfm_aes); kzfree(smp); return NULL; } @@ -3127,8 +3120,8 @@ static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid) { struct l2cap_chan *chan; struct smp_dev *smp; - struct crypto_blkcipher *tfm_aes; - struct crypto_hash *tfm_cmac; + struct crypto_skcipher *tfm_aes; + struct crypto_shash *tfm_cmac; if (cid == L2CAP_CID_SMP_BREDR) { smp = NULL; @@ -3139,17 +3132,17 @@ static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid) if (!smp) return ERR_PTR(-ENOMEM); - tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); + tfm_aes = crypto_alloc_skcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm_aes)) { BT_ERR("Unable to create ECB crypto context"); kzfree(smp); return ERR_CAST(tfm_aes); } - tfm_cmac = crypto_alloc_hash("cmac(aes)", 0, CRYPTO_ALG_ASYNC); + tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0); if (IS_ERR(tfm_cmac)) { BT_ERR("Unable to create CMAC crypto context"); - crypto_free_blkcipher(tfm_aes); + crypto_free_skcipher(tfm_aes); kzfree(smp); return ERR_CAST(tfm_cmac); } @@ -3163,8 +3156,8 @@ create_chan: chan = l2cap_chan_create(); if (!chan) { if (smp) { - crypto_free_blkcipher(smp->tfm_aes); - crypto_free_hash(smp->tfm_cmac); + crypto_free_skcipher(smp->tfm_aes); + crypto_free_shash(smp->tfm_cmac); kzfree(smp); } return ERR_PTR(-ENOMEM); @@ -3210,10 +3203,8 @@ static void smp_del_chan(struct l2cap_chan *chan) smp = chan->data; if (smp) { chan->data = NULL; - if (smp->tfm_aes) - crypto_free_blkcipher(smp->tfm_aes); - if (smp->tfm_cmac) - crypto_free_hash(smp->tfm_cmac); + crypto_free_skcipher(smp->tfm_aes); + crypto_free_shash(smp->tfm_cmac); kzfree(smp); } @@ -3449,7 +3440,7 @@ void smp_unregister(struct hci_dev *hdev) #if IS_ENABLED(CONFIG_BT_SELFTEST_SMP) -static int __init test_ah(struct crypto_blkcipher *tfm_aes) +static int __init test_ah(struct crypto_skcipher *tfm_aes) { const u8 irk[16] = { 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, @@ -3469,7 +3460,7 @@ static int __init test_ah(struct crypto_blkcipher *tfm_aes) return 0; } -static int __init test_c1(struct crypto_blkcipher *tfm_aes) +static int __init test_c1(struct crypto_skcipher *tfm_aes) { const u8 k[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -3499,7 +3490,7 @@ static int __init test_c1(struct crypto_blkcipher *tfm_aes) return 0; } -static int __init test_s1(struct crypto_blkcipher *tfm_aes) +static int __init test_s1(struct crypto_skcipher *tfm_aes) { const u8 k[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -3524,7 +3515,7 @@ static int __init test_s1(struct crypto_blkcipher *tfm_aes) return 0; } -static int __init test_f4(struct crypto_hash *tfm_cmac) +static int __init test_f4(struct crypto_shash *tfm_cmac) { const u8 u[32] = { 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, @@ -3556,7 +3547,7 @@ static int __init test_f4(struct crypto_hash *tfm_cmac) return 0; } -static int __init test_f5(struct crypto_hash *tfm_cmac) +static int __init test_f5(struct crypto_shash *tfm_cmac) { const u8 w[32] = { 0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86, @@ -3593,7 +3584,7 @@ static int __init test_f5(struct crypto_hash *tfm_cmac) return 0; } -static int __init test_f6(struct crypto_hash *tfm_cmac) +static int __init test_f6(struct crypto_shash *tfm_cmac) { const u8 w[16] = { 0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd, @@ -3626,7 +3617,7 @@ static int __init test_f6(struct crypto_hash *tfm_cmac) return 0; } -static int __init test_g2(struct crypto_hash *tfm_cmac) +static int __init test_g2(struct crypto_shash *tfm_cmac) { const u8 u[32] = { 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, @@ -3658,7 +3649,7 @@ static int __init test_g2(struct crypto_hash *tfm_cmac) return 0; } -static int __init test_h6(struct crypto_hash *tfm_cmac) +static int __init test_h6(struct crypto_shash *tfm_cmac) { const u8 w[16] = { 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, @@ -3695,8 +3686,8 @@ static const struct file_operations test_smp_fops = { .llseek = default_llseek, }; -static int __init run_selftests(struct crypto_blkcipher *tfm_aes, - struct crypto_hash *tfm_cmac) +static int __init run_selftests(struct crypto_skcipher *tfm_aes, + struct crypto_shash *tfm_cmac) { ktime_t calltime, delta, rettime; unsigned long long duration; @@ -3773,27 +3764,27 @@ done: int __init bt_selftest_smp(void) { - struct crypto_blkcipher *tfm_aes; - struct crypto_hash *tfm_cmac; + struct crypto_skcipher *tfm_aes; + struct crypto_shash *tfm_cmac; int err; - tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); + tfm_aes = crypto_alloc_skcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm_aes)) { BT_ERR("Unable to create ECB crypto context"); return PTR_ERR(tfm_aes); } - tfm_cmac = crypto_alloc_hash("cmac(aes)", 0, CRYPTO_ALG_ASYNC); + tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm_cmac)) { BT_ERR("Unable to create CMAC crypto context"); - crypto_free_blkcipher(tfm_aes); + crypto_free_skcipher(tfm_aes); return PTR_ERR(tfm_cmac); } err = run_selftests(tfm_aes, tfm_cmac); - crypto_free_hash(tfm_cmac); - crypto_free_blkcipher(tfm_aes); + crypto_free_shash(tfm_cmac); + crypto_free_skcipher(tfm_aes); return err; } |