* RE: Bluetooth: btnxpuart: Add secure interface support for NXP chipsets
2025-11-18 14:20 [PATCH v1 01/11] Bluetooth: btnxpuart: Add firmware metadata parsing for secure interface Neeraj Sanjay Kale
@ 2025-11-18 15:07 ` bluez.test.bot
0 siblings, 0 replies; 23+ messages in thread
From: bluez.test.bot @ 2025-11-18 15:07 UTC (permalink / raw)
To: linux-bluetooth, neeraj.sanjaykale
[-- Attachment #1: Type: text/plain, Size: 2377 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1024897
---Test result---
Test Summary:
CheckPatch PENDING 0.49 seconds
GitLint PENDING 0.38 seconds
SubjectPrefix PASS 2.65 seconds
BuildKernel PASS 26.39 seconds
CheckAllWarning PASS 28.81 seconds
CheckSparse PASS 32.64 seconds
BuildKernel32 PASS 25.57 seconds
TestRunnerSetup PASS 564.06 seconds
TestRunner_l2cap-tester PASS 24.55 seconds
TestRunner_iso-tester PASS 83.26 seconds
TestRunner_bnep-tester PASS 6.20 seconds
TestRunner_mgmt-tester FAIL 122.95 seconds
TestRunner_rfcomm-tester PASS 9.43 seconds
TestRunner_sco-tester PASS 14.50 seconds
TestRunner_ioctl-tester PASS 10.08 seconds
TestRunner_mesh-tester FAIL 10.58 seconds
TestRunner_smp-tester PASS 8.58 seconds
TestRunner_userchan-tester PASS 6.65 seconds
IncrementalBuild PENDING 1.14 seconds
Details
##############################
Test: CheckPatch - PENDING
Desc: Run checkpatch.pl script
Output:
##############################
Test: GitLint - PENDING
Desc: Run gitlint
Output:
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 494, Passed: 488 (98.8%), Failed: 2, Not Run: 4
Failed Test Cases
Read Exp Feature - Success Failed 0.100 seconds
LL Privacy - Start Discovery 1 (Disable RL) Failed 0.173 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0
Failed Test Cases
Mesh - Send cancel - 1 Failed 0.132 seconds
Mesh - Send cancel - 2 Timed out 2.699 seconds
##############################
Test: IncrementalBuild - PENDING
Desc: Incremental build with the patches in the series
Output:
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: Bluetooth: btnxpuart: Add secure interface support for NXP chipsets
2025-11-28 9:14 [PATCH v2 01/11] Bluetooth: btnxpuart: Add firmware metadata parsing for secure interface Neeraj Sanjay Kale
@ 2025-11-28 10:02 ` bluez.test.bot
0 siblings, 0 replies; 23+ messages in thread
From: bluez.test.bot @ 2025-11-28 10:02 UTC (permalink / raw)
To: linux-bluetooth, neeraj.sanjaykale
[-- Attachment #1: Type: text/plain, Size: 2296 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1028593
---Test result---
Test Summary:
CheckPatch PENDING 0.47 seconds
GitLint PENDING 0.43 seconds
SubjectPrefix PASS 0.80 seconds
BuildKernel PASS 25.26 seconds
CheckAllWarning PASS 27.15 seconds
CheckSparse PASS 31.02 seconds
BuildKernel32 PASS 24.50 seconds
TestRunnerSetup PASS 545.19 seconds
TestRunner_l2cap-tester PASS 23.24 seconds
TestRunner_iso-tester PASS 76.46 seconds
TestRunner_bnep-tester PASS 6.08 seconds
TestRunner_mgmt-tester FAIL 113.15 seconds
TestRunner_rfcomm-tester PASS 8.96 seconds
TestRunner_sco-tester PASS 12.52 seconds
TestRunner_ioctl-tester PASS 9.88 seconds
TestRunner_mesh-tester FAIL 11.46 seconds
TestRunner_smp-tester PASS 8.28 seconds
TestRunner_userchan-tester PASS 6.39 seconds
IncrementalBuild PENDING 0.71 seconds
Details
##############################
Test: CheckPatch - PENDING
Desc: Run checkpatch.pl script
Output:
##############################
Test: GitLint - PENDING
Desc: Run gitlint
Output:
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 494, Passed: 489 (99.0%), Failed: 1, Not Run: 4
Failed Test Cases
Read Exp Feature - Success Failed 0.096 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0
Failed Test Cases
Mesh - Send cancel - 1 Timed out 2.121 seconds
Mesh - Send cancel - 2 Timed out 1.993 seconds
##############################
Test: IncrementalBuild - PENDING
Desc: Incremental build with the patches in the series
Output:
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 23+ messages in thread
* [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets
@ 2026-01-13 7:47 Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 01/11] Bluetooth: btnxpuart: Add firmware metadata parsing for secure interface Neeraj Sanjay Kale
` (11 more replies)
0 siblings, 12 replies; 23+ messages in thread
From: Neeraj Sanjay Kale @ 2026-01-13 7:47 UTC (permalink / raw)
To: marcel, luiz.dentz
Cc: amitkumar.karwar, neeraj.sanjaykale, sherry.sun, dmitrii.lebed,
linux-bluetooth, linux-kernel
This patch series adds secure interface support for NXP Bluetooth chipsets
to protect against UART-based attacks on Bluetooth security keys.
Problem Statement:
==================
Bluetooth UART drivers are vulnerable to physical attacks where adversaries
can monitor UART TX/RX lines to extract sensitive cryptographic material.
As demonstrated in research [1], attackers can capture H4 packets
containing Link Keys, LTKs, and other pairing data transmitted in plaintext
over UART.
Once an attacker obtains these keys from UART traffic, they can:
- Decrypt all Bluetooth communication for paired devices
- Impersonate trusted devices
- Perform man-in-the-middle attacks
This vulnerability affects any Bluetooth implementation using UART
transport, making physical access to UART lines equivalent to compromising
all paired device security.
Solution:
=========
Implement a TLS 1.3-inspired secure interface that:
- Authenticates the chipset using ECDSA signature verification
- Establishes shared encryption keys via ECDH key exchange
- Encrypts sensitive HCI commands (Link Key Reply, LTK Reply, etc.) using
AES-GCM
- Decrypts encrypted vendor events from the chipset
This ensures that even with full UART access, attackers cannot extract
usable cryptographic keys from the communication channel.
Implementation Overview:
========================
The solution is implemented in 11 incremental patches:
1-2: Add firmware metadata parsing and version detection
3-4: Establish secure interface framework and crypto setup
5-7: Implement TLS handshake (Host Hello, Device Hello, authentication)
8: Derive application traffic keys for encryption/decryption
9-10: Add command encryption and event decryption support
11: Add required crypto algorithm dependencies
The implementation automatically detects secure interface capability via
firmware version strings and enables encryption only when needed. Legacy
chipsets continue to work without modification.
Security Properties:
===================
- Chipset authentication prevents rogue device substitution
- Forward secrecy through ephemeral ECDH key exchange
- Authenticated encryption (AES-GCM) prevents tampering
- Per-session keys limit exposure from key compromise
Testing:
========
Tested on AW693 chipsets with secure firmware. Verified that:
- Authentication handshake completes successfully
- Sensitive commands are encrypted before transmission
- Encrypted events are properly decrypted
- UART monitoring shows only encrypted payloads for sensitive operations
- Legacy chipsets remain unaffected
[1] "BLAP: Bluetooth Low Energy Attacks on Pairing" - DSN 2022
https://netsec.ethz.ch/publications/papers/dsn22_blap.pdf
Neeraj Sanjay Kale (11):
Bluetooth: btnxpuart: Add firmware metadata parsing for secure
interface
Bluetooth: btnxpuart: Print FW version and enable chip specific
features
Bluetooth: btnxpuart: Add secure interface TLS authentication support
Bluetooth: btnxpuart: Implement TLS authentication crypto framework
Bluetooth: btnxpuart: Add TLS host hello handshake implementation
Bluetooth: btnxpuart: Add TLS device hello processing
Bluetooth: btnxpuart: Add device authentication
Bluetooth: btnxpuart: Derive traffic keys from TLS 1.3 handshake
Bluetooth: btnxpuart: Add command encryption for sensitive HCI
commands
Bluetooth: btnxpuart: Add encrypted event handling
Bluetooth: btnxpuart: Select crypto algorithms for secure interface
drivers/bluetooth/Kconfig | 7 +
drivers/bluetooth/btnxpuart.c | 1442 ++++++++++++++++++++++++++++++++-
2 files changed, 1440 insertions(+), 9 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 01/11] Bluetooth: btnxpuart: Add firmware metadata parsing for secure interface
2026-01-13 7:47 [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Neeraj Sanjay Kale
@ 2026-01-13 7:47 ` Neeraj Sanjay Kale
2026-01-13 8:46 ` Bluetooth: btnxpuart: Add secure interface support for NXP chipsets bluez.test.bot
2026-01-13 7:47 ` [PATCH v2 02/11] Bluetooth: btnxpuart: Print FW version and enable chip specific features Neeraj Sanjay Kale
` (10 subsequent siblings)
11 siblings, 1 reply; 23+ messages in thread
From: Neeraj Sanjay Kale @ 2026-01-13 7:47 UTC (permalink / raw)
To: marcel, luiz.dentz
Cc: amitkumar.karwar, neeraj.sanjaykale, sherry.sun, dmitrii.lebed,
linux-bluetooth, linux-kernel
This adds support for parsing firmware metadata TLVs to extract FW UUID and
ECDSA Public Key from FW metadata for secure interface authentication.
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
---
v2: Fix sparse warnings. (kernel test robot)
---
drivers/bluetooth/btnxpuart.c | 133 ++++++++++++++++++++++++++++++++--
1 file changed, 125 insertions(+), 8 deletions(-)
diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index 3b1e9224e965..78a7651d55d6 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -15,6 +15,7 @@
#include <linux/string.h>
#include <linux/crc8.h>
#include <linux/crc32.h>
+#include <linux/math.h>
#include <linux/string_helpers.h>
#include <linux/gpio/consumer.h>
#include <linux/of_irq.h>
@@ -134,6 +135,14 @@
#define BT_CTRL_WAKEUP_METHOD_EXT_BREAK 0x04
#define BT_CTRL_WAKEUP_METHOD_RTS 0x05
+/* FW Metadata */
+#define FW_METADATA_TLV_UUID 0x40
+#define FW_METADATA_TLV_ECDSA_KEY 0x50
+#define FW_METADATA_FLAG_BT 0x02
+
+#define NXP_FW_UUID_SIZE 16
+#define NXP_FW_ECDSA_PUBKEY_SIZE 65
+
struct ps_data {
u8 target_ps_mode; /* ps mode to be set */
u8 cur_psmode; /* current ps_mode */
@@ -180,6 +189,11 @@ enum bootloader_param_change {
changed
};
+struct btnxpuart_crypto {
+ u8 ecdsa_public[NXP_FW_ECDSA_PUBKEY_SIZE]; /* ECDSA public key, Authentication*/
+ u8 fw_uuid[NXP_FW_UUID_SIZE];
+};
+
struct btnxpuart_dev {
struct hci_dev *hdev;
struct serdev_device *serdev;
@@ -213,6 +227,7 @@ struct btnxpuart_dev {
struct btnxpuart_data *nxp_data;
struct reset_control *pdn;
struct hci_uart hu;
+ struct btnxpuart_crypto crypto;
};
#define NXP_V1_FW_REQ_PKT 0xa5
@@ -362,6 +377,26 @@ union nxp_set_bd_addr_payload {
u8 buf[8];
};
+/* FW Meta Data */
+struct fw_metadata_hdr {
+ __le32 cmd;
+ __le32 addr;
+ __le32 len;
+ __le32 crc;
+};
+
+struct fw_metadata_tail {
+ __le32 len;
+ u8 magic[8];
+ __le32 crc;
+};
+
+struct fw_metadata_tlv {
+ __le16 id;
+ __le16 flag;
+ __le32 len;
+};
+
static u8 crc8_table[CRC8_TABLE_SIZE];
/* Default configurations */
@@ -1190,6 +1225,85 @@ static void nxp_handle_fw_download_error(struct hci_dev *hdev, struct v3_data_re
}
}
+static u32 nxp_process_fw_metadata_tlv(struct hci_dev *hdev, char **payload)
+{
+ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ struct fw_metadata_tlv *tlv = (struct fw_metadata_tlv *)(*payload);
+ u32 ret = sizeof(*tlv) + le32_to_cpu(tlv->len);
+
+ /* Process only BT specific metadata TLVs */
+ if (!(le16_to_cpu(tlv->flag) & FW_METADATA_FLAG_BT))
+ goto align_and_return;
+
+ switch (le16_to_cpu(tlv->id)) {
+ case FW_METADATA_TLV_UUID:
+ if (le32_to_cpu(tlv->len) == NXP_FW_UUID_SIZE)
+ memcpy(nxpdev->crypto.fw_uuid,
+ *payload + sizeof(*tlv), NXP_FW_UUID_SIZE);
+ break;
+ case FW_METADATA_TLV_ECDSA_KEY:
+ if (le32_to_cpu(tlv->len) == NXP_FW_ECDSA_PUBKEY_SIZE)
+ memcpy(nxpdev->crypto.ecdsa_public,
+ *payload + sizeof(*tlv), NXP_FW_ECDSA_PUBKEY_SIZE);
+ break;
+ default:
+ bt_dev_err(hdev, "Unknown metadata TLV ID: 0x%x", le16_to_cpu(tlv->id));
+ break;
+ }
+
+align_and_return:
+ /* Align the pointer to 4 byte structure alignment */
+ ret = round_up(ret, 4);
+ *payload += ret;
+
+ return ret;
+}
+
+static void nxp_process_fw_meta_data(struct hci_dev *hdev, const struct firmware *fw)
+{
+ const char *metamagc = "metamagc";
+ struct fw_metadata_hdr *hdr = NULL;
+ struct fw_metadata_tail *tail;
+ u32 hdr_crc = 0;
+ u32 payload_crc = 0;
+ char *payload;
+ u32 payload_len = 0;
+
+ /* FW metadata should contain at least header and tail */
+ if (fw->size < (sizeof(*hdr) + sizeof(*tail)))
+ return;
+
+ tail = (struct fw_metadata_tail *)&fw->data[fw->size - sizeof(*tail)];
+
+ /* If tail doesn't contain the string "metamagc", this is invalid FW metadata */
+ if (memcmp(metamagc, tail->magic, strlen(metamagc)))
+ return;
+
+ hdr = (struct fw_metadata_hdr *)&fw->data[fw->size -
+ sizeof(*tail) -
+ le32_to_cpu(tail->len)];
+
+ /* If metadata header isn't cmd24, this is invalid FW metadata */
+ if (le32_to_cpu(hdr->cmd) != 24)
+ return;
+
+ /* If header CRC doesn't match, this is invalid FW metadata */
+ hdr_crc = crc32_be(0, (u8 *)hdr, offsetof(struct fw_metadata_hdr, crc));
+ if (hdr_crc != le32_to_cpu(hdr->crc))
+ return;
+
+ /* If payload CRC doesn't match, this is invalid FW metadata */
+ payload = (u8 *)hdr + sizeof(*hdr);
+ payload_crc = crc32_be(0, payload, le32_to_cpu(hdr->len) - 4);
+ if (payload_crc != le32_to_cpu(tail->crc))
+ return;
+
+ payload_len = le32_to_cpu(hdr->len) - sizeof(*tail);
+
+ while (payload_len > sizeof(struct fw_metadata_tlv))
+ payload_len -= nxp_process_fw_metadata_tlv(hdev, &payload);
+}
+
static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb)
{
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
@@ -1248,14 +1362,6 @@ static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb)
goto free_skb;
}
- if (req->len == 0) {
- bt_dev_info(hdev, "FW Download Complete: %zu bytes",
- nxpdev->fw->size);
- clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
- wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q);
- goto free_skb;
- }
-
offset = __le32_to_cpu(req->offset);
if (offset < nxpdev->fw_v3_offset_correction) {
/* This scenario should ideally never occur. But if it ever does,
@@ -1267,6 +1373,17 @@ static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb)
}
nxpdev->fw_dnld_v3_offset = offset - nxpdev->fw_v3_offset_correction;
+
+ if (req->len == 0) {
+ if (nxpdev->fw_dnld_v3_offset < nxpdev->fw->size)
+ nxp_process_fw_meta_data(hdev, nxpdev->fw);
+ bt_dev_info(hdev, "FW Download Complete: %u bytes.",
+ req->offset - nxpdev->fw_v3_offset_correction);
+ clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
+ wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q);
+ goto free_skb;
+ }
+
serdev_device_write_buf(nxpdev->serdev, nxpdev->fw->data +
nxpdev->fw_dnld_v3_offset, len);
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 02/11] Bluetooth: btnxpuart: Print FW version and enable chip specific features
2026-01-13 7:47 [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 01/11] Bluetooth: btnxpuart: Add firmware metadata parsing for secure interface Neeraj Sanjay Kale
@ 2026-01-13 7:47 ` Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 03/11] Bluetooth: btnxpuart: Add secure interface TLS authentication support Neeraj Sanjay Kale
` (9 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Neeraj Sanjay Kale @ 2026-01-13 7:47 UTC (permalink / raw)
To: marcel, luiz.dentz
Cc: amitkumar.karwar, neeraj.sanjaykale, sherry.sun, dmitrii.lebed,
linux-bluetooth, linux-kernel
This adds a print for FW version after FW is downloaded, and a way to
enable chip specific features.
Currently, secure interface feature is enabled for AW693 chipset.
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
---
drivers/bluetooth/btnxpuart.c | 46 +++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index 78a7651d55d6..d2c79c462ebb 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -105,6 +105,8 @@
#define PS_STATE_SLEEP 1
/* NXP Vendor Commands. Refer user manual UM11628 on nxp.com */
+/* Get FW version */
+#define HCI_NXP_GET_FW_VERSION 0xfc0f
/* Set custom BD Address */
#define HCI_NXP_SET_BD_ADDR 0xfc22
/* Set Auto-Sleep mode */
@@ -227,6 +229,7 @@ struct btnxpuart_dev {
struct btnxpuart_data *nxp_data;
struct reset_control *pdn;
struct hci_uart hu;
+ bool secure_interface;
struct btnxpuart_crypto crypto;
};
@@ -1554,6 +1557,47 @@ static int nxp_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
return 0;
}
+static void nxp_handle_chip_specific_features(struct hci_dev *hdev, u8 *version)
+{
+ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+
+ if (!version || strlen(version) == 0)
+ return;
+
+ if (!strncmp(version, "aw693n-V1", strlen("aw693n-V1")))
+ nxpdev->secure_interface = true;
+}
+
+static void nxp_get_fw_version(struct hci_dev *hdev)
+{
+ struct sk_buff *skb;
+ u8 version[100] = {0};
+ u8 cmd = 0;
+ u8 *status;
+
+ skb = nxp_drv_send_cmd(hdev, HCI_NXP_GET_FW_VERSION, 1, &cmd, true);
+ if (IS_ERR(skb)) {
+ bt_dev_err(hdev, "Failed to get firmware version (%ld)",
+ PTR_ERR(skb));
+ return;
+ }
+
+ status = skb_pull_data(skb, 1);
+ if (status) {
+ if (*status) {
+ bt_dev_err(hdev, "Error get FW version: %d", *status);
+ } else if (skb->len < 10 || skb->len >= 100) {
+ bt_dev_err(hdev, "Invalid FW version");
+ } else {
+ memcpy(version, skb->data, skb->len);
+ bt_dev_info(hdev, "FW Version: %s", version);
+ nxp_handle_chip_specific_features(hdev, version);
+ }
+ }
+
+ kfree_skb(skb);
+}
+
/* NXP protocol */
static int nxp_setup(struct hci_dev *hdev)
{
@@ -1583,6 +1627,8 @@ static int nxp_setup(struct hci_dev *hdev)
serdev_device_set_baudrate(nxpdev->serdev, nxpdev->fw_init_baudrate);
nxpdev->current_baudrate = nxpdev->fw_init_baudrate;
+ nxp_get_fw_version(hdev);
+
ps_init(hdev);
if (test_and_clear_bit(BTNXPUART_IR_IN_PROGRESS, &nxpdev->tx_state))
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 03/11] Bluetooth: btnxpuart: Add secure interface TLS authentication support
2026-01-13 7:47 [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 01/11] Bluetooth: btnxpuart: Add firmware metadata parsing for secure interface Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 02/11] Bluetooth: btnxpuart: Print FW version and enable chip specific features Neeraj Sanjay Kale
@ 2026-01-13 7:47 ` Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 04/11] Bluetooth: btnxpuart: Implement TLS authentication crypto framework Neeraj Sanjay Kale
` (8 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Neeraj Sanjay Kale @ 2026-01-13 7:47 UTC (permalink / raw)
To: marcel, luiz.dentz
Cc: amitkumar.karwar, neeraj.sanjaykale, sherry.sun, dmitrii.lebed,
linux-bluetooth, linux-kernel
This includes a placeholder nxp_authenticate_device() function if the
chip supports secure interface feature.
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
---
drivers/bluetooth/btnxpuart.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index d2c79c462ebb..3455460d30f5 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -1598,6 +1598,23 @@ static void nxp_get_fw_version(struct hci_dev *hdev)
kfree_skb(skb);
}
+/* Secure Interface */
+static int nxp_authenticate_device(struct hci_dev *hdev)
+{
+ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ int ret = 0;
+
+ /* TODO: Implement actual TLS handshake protocol
+ * This will include:
+ * 1. Crypto allocation (SHA256, ECDH-P256)
+ * 2. Host/Device hello message exchange
+ * 3. Master secret and traffic key derivation
+ * 4. Proper error handling and cleanup
+ */
+
+ return ret;
+}
+
/* NXP protocol */
static int nxp_setup(struct hci_dev *hdev)
{
@@ -1629,6 +1646,12 @@ static int nxp_setup(struct hci_dev *hdev)
nxp_get_fw_version(hdev);
+ if (nxpdev->secure_interface) {
+ err = nxp_authenticate_device(hdev);
+ if (err)
+ return -EACCES;
+ }
+
ps_init(hdev);
if (test_and_clear_bit(BTNXPUART_IR_IN_PROGRESS, &nxpdev->tx_state))
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 04/11] Bluetooth: btnxpuart: Implement TLS authentication crypto framework
2026-01-13 7:47 [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Neeraj Sanjay Kale
` (2 preceding siblings ...)
2026-01-13 7:47 ` [PATCH v2 03/11] Bluetooth: btnxpuart: Add secure interface TLS authentication support Neeraj Sanjay Kale
@ 2026-01-13 7:47 ` Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 05/11] Bluetooth: btnxpuart: Add TLS host hello handshake implementation Neeraj Sanjay Kale
` (7 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Neeraj Sanjay Kale @ 2026-01-13 7:47 UTC (permalink / raw)
To: marcel, luiz.dentz
Cc: amitkumar.karwar, neeraj.sanjaykale, sherry.sun, dmitrii.lebed,
linux-bluetooth, linux-kernel
This adds nxp_authenticate_device() function that sets up cryptographic
resources for TLS handshake authentication. Allocates SHA256 hash and
ECDH-P256 key exchange with proper cleanup after handshake completion
to maintain only traffic keys.
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
---
drivers/bluetooth/btnxpuart.c | 48 ++++++++++++++++++++++++++++++++---
1 file changed, 44 insertions(+), 4 deletions(-)
diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index 3455460d30f5..7c94d8ab94f3 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -22,6 +22,11 @@
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
+#include <linux/crypto.h>
+#include <crypto/sha2.h>
+#include <crypto/hash.h>
+#include <crypto/kpp.h>
+
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -192,6 +197,9 @@ enum bootloader_param_change {
};
struct btnxpuart_crypto {
+ struct crypto_shash *tls_handshake_hash_tfm;
+ struct shash_desc *tls_handshake_hash_desc;
+ struct crypto_kpp *kpp;
u8 ecdsa_public[NXP_FW_ECDSA_PUBKEY_SIZE]; /* ECDSA public key, Authentication*/
u8 fw_uuid[NXP_FW_UUID_SIZE];
};
@@ -1602,16 +1610,48 @@ static void nxp_get_fw_version(struct hci_dev *hdev)
static int nxp_authenticate_device(struct hci_dev *hdev)
{
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ size_t desc_size = 0;
int ret = 0;
+ nxpdev->crypto.tls_handshake_hash_tfm = crypto_alloc_shash("sha256", 0, 0);
+ if (IS_ERR(nxpdev->crypto.tls_handshake_hash_tfm))
+ return PTR_ERR(nxpdev->crypto.tls_handshake_hash_tfm);
+
+ desc_size = sizeof(struct shash_desc) +
+ crypto_shash_descsize(nxpdev->crypto.tls_handshake_hash_tfm);
+ nxpdev->crypto.tls_handshake_hash_desc = kzalloc(desc_size, GFP_KERNEL);
+ if (!nxpdev->crypto.tls_handshake_hash_desc) {
+ ret = -ENOMEM;
+ goto free_tfm;
+ }
+
+ nxpdev->crypto.kpp = crypto_alloc_kpp("ecdh-nist-p256", 0, 0);
+ if (IS_ERR(nxpdev->crypto.kpp)) {
+ ret = PTR_ERR(nxpdev->crypto.kpp);
+ goto free_desc;
+ }
+
+ nxpdev->crypto.tls_handshake_hash_desc->tfm = nxpdev->crypto.tls_handshake_hash_tfm;
+ crypto_shash_init(nxpdev->crypto.tls_handshake_hash_desc);
+
/* TODO: Implement actual TLS handshake protocol
* This will include:
- * 1. Crypto allocation (SHA256, ECDH-P256)
- * 2. Host/Device hello message exchange
- * 3. Master secret and traffic key derivation
- * 4. Proper error handling and cleanup
+ * 1. Host/Device hello message exchange
+ * 2. Master secret and traffic key derivation
*/
+free_kpp:
+ crypto_free_kpp(nxpdev->crypto.kpp);
+ nxpdev->crypto.kpp = NULL;
+free_desc:
+ kfree(nxpdev->crypto.tls_handshake_hash_desc);
+ nxpdev->crypto.tls_handshake_hash_desc = NULL;
+free_tfm:
+ crypto_free_shash(nxpdev->crypto.tls_handshake_hash_tfm);
+ nxpdev->crypto.tls_handshake_hash_tfm = NULL;
+ if (ret)
+ bt_dev_err(hdev, "Device Authentication failed: %d", ret);
+
return ret;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 05/11] Bluetooth: btnxpuart: Add TLS host hello handshake implementation
2026-01-13 7:47 [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Neeraj Sanjay Kale
` (3 preceding siblings ...)
2026-01-13 7:47 ` [PATCH v2 04/11] Bluetooth: btnxpuart: Implement TLS authentication crypto framework Neeraj Sanjay Kale
@ 2026-01-13 7:47 ` Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 06/11] Bluetooth: btnxpuart: Add TLS device hello processing Neeraj Sanjay Kale
` (6 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Neeraj Sanjay Kale @ 2026-01-13 7:47 UTC (permalink / raw)
To: marcel, luiz.dentz
Cc: amitkumar.karwar, neeraj.sanjaykale, sherry.sun, dmitrii.lebed,
linux-bluetooth, linux-kernel
Implement TLS handshake initiation for secure interface authentication.
Includes ECDH public key generation, host hello message creation, and
handshake hash computation for secure chip authentication.
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
---
drivers/bluetooth/btnxpuart.c | 189 +++++++++++++++++++++++++++++++++-
1 file changed, 188 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index 7c94d8ab94f3..8208b0748f97 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -26,6 +26,7 @@
#include <crypto/sha2.h>
#include <crypto/hash.h>
#include <crypto/kpp.h>
+#include <crypto/ecdh.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -124,6 +125,8 @@
#define HCI_NXP_IND_RESET 0xfcfc
/* Bluetooth vendor command: Trigger FW dump */
#define HCI_NXP_TRIGGER_DUMP 0xfe91
+/* Bluetooth vendor command: Secure Host Interface */
+#define HCI_NXP_SHI_ENCRYPT 0xfe9c
/* Bluetooth Power State : Vendor cmd params */
#define BT_PS_ENABLE 0x02
@@ -388,6 +391,55 @@ union nxp_set_bd_addr_payload {
u8 buf[8];
};
+/* Secure Host Interface */
+#define NXP_TLS_MAGIC 0x43b826f3
+#define NXP_TLS_VERSION 1
+
+#define NXP_TLS_ECDH_PUBLIC_KEY_SIZE 64
+
+enum nxp_tls_signature_algorithm {
+ NXP_TLS_ECDSA_SECP256R1_SHA256 = 0x0403,
+};
+
+enum nxp_tls_key_exchange_type {
+ NXP_TLS_ECDHE_SECP256R1 = 0x0017,
+};
+
+enum nxp_tls_cipher_suite {
+ NXP_TLS_AES_128_GCM_SHA256 = 0x1301,
+};
+
+enum nxp_tls_message_id {
+ NXP_TLS_HOST_HELLO = 1,
+ NXP_TLS_DEVICE_HELLO = 2,
+ NXP_TLS_HOST_FINISHED = 3,
+};
+
+struct nxp_tls_message_hdr {
+ __le32 magic;
+ __le16 len;
+ u8 message_id;
+ u8 protocol_version;
+};
+
+struct nxp_tls_host_hello {
+ struct nxp_tls_message_hdr hdr;
+ __le16 sig_alg;
+ __le16 key_exchange_type;
+ __le16 cipher_suite;
+ __le16 reserved;
+ u8 random[32];
+ u8 pubkey[NXP_TLS_ECDH_PUBLIC_KEY_SIZE]; /* ECDHE */
+};
+
+union nxp_tls_host_hello_payload {
+ struct {
+ u8 msg_type;
+ struct nxp_tls_host_hello host_hello;
+ } __packed;
+ u8 buf[113];
+};
+
/* FW Meta Data */
struct fw_metadata_hdr {
__le32 cmd;
@@ -1607,10 +1659,137 @@ static void nxp_get_fw_version(struct hci_dev *hdev)
}
/* Secure Interface */
+static int nxp_generate_ecdh_public_key(struct crypto_kpp *tfm, u8 public_key[64])
+{
+ DECLARE_CRYPTO_WAIT(result);
+ struct kpp_request *req;
+ u8 *tmp;
+ struct scatterlist dst;
+ int err;
+
+ tmp = kzalloc(64, GFP_KERNEL);
+ if (!tmp)
+ return -ENOMEM;
+
+ req = kpp_request_alloc(tfm, GFP_KERNEL);
+ if (!req) {
+ err = -ENOMEM;
+ goto free_tmp;
+ }
+
+ sg_init_one(&dst, tmp, 64);
+ kpp_request_set_input(req, NULL, 0);
+ kpp_request_set_output(req, &dst, 64);
+ kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ crypto_req_done, &result);
+
+ err = crypto_kpp_generate_public_key(req);
+ err = crypto_wait_req(err, &result);
+ if (err < 0)
+ goto free_all;
+
+ memcpy(public_key, tmp, 64);
+
+free_all:
+ kpp_request_free(req);
+free_tmp:
+ kfree(tmp);
+ return err;
+}
+
+static inline void nxp_tls_hdr_init(struct nxp_tls_message_hdr *hdr, size_t len,
+ enum nxp_tls_message_id id)
+{
+ hdr->magic = cpu_to_le32(NXP_TLS_MAGIC);
+ hdr->len = cpu_to_le16((u16)len);
+ hdr->message_id = (u8)id;
+ hdr->protocol_version = NXP_TLS_VERSION;
+}
+
+static struct sk_buff *nxp_host_do_hello(struct hci_dev *hdev)
+{
+ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ union nxp_tls_host_hello_payload tls_hello;
+ struct nxp_tls_host_hello *host_hello = &tls_hello.host_hello;
+ struct ecdh p = {0};
+ u8 *buf = NULL;
+ unsigned int buf_len;
+ struct sk_buff *skb;
+ int ret;
+
+ nxp_tls_hdr_init(&host_hello->hdr, sizeof(*host_hello), NXP_TLS_HOST_HELLO);
+
+ host_hello->sig_alg = cpu_to_le16(NXP_TLS_ECDSA_SECP256R1_SHA256);
+ host_hello->key_exchange_type = cpu_to_le16(NXP_TLS_ECDHE_SECP256R1);
+ host_hello->cipher_suite = cpu_to_le16(NXP_TLS_AES_128_GCM_SHA256);
+
+ get_random_bytes(host_hello->random, sizeof(host_hello->random));
+
+ /* Generate random private key */
+ p.key_size = 32;
+ p.key = kzalloc(p.key_size, GFP_KERNEL);
+ if (!p.key)
+ return ERR_PTR(-ENOMEM);
+
+ get_random_bytes(p.key, p.key_size);
+
+ buf_len = crypto_ecdh_key_len(&p);
+ buf = kzalloc(buf_len, GFP_KERNEL);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto free_key;
+ }
+
+ ret = crypto_ecdh_encode_key(buf, buf_len, &p);
+ if (ret) {
+ bt_dev_err(hdev, "crypto_ecdh_encode_key() failed");
+ goto free_buf;
+ }
+
+ ret = crypto_kpp_set_secret(nxpdev->crypto.kpp, buf, buf_len);
+ if (ret) {
+ bt_dev_err(hdev, "crypto_kpp_set_secret() failed");
+ goto free_buf;
+ }
+
+ ret = nxp_generate_ecdh_public_key(nxpdev->crypto.kpp, host_hello->pubkey);
+ if (ret) {
+ bt_dev_err(hdev, "Failed to generate ECDH public key: %d", ret);
+ goto free_buf;
+ }
+
+ ret = crypto_shash_update(nxpdev->crypto.tls_handshake_hash_desc,
+ (u8 *)host_hello, sizeof(*host_hello));
+ if (ret) {
+ bt_dev_err(hdev, "Failed to update handshake hash: %d", ret);
+ goto free_buf;
+ }
+
+ tls_hello.msg_type = 0;
+
+ skb = __hci_cmd_sync(hdev, HCI_NXP_SHI_ENCRYPT, sizeof(tls_hello),
+ tls_hello.buf, HCI_CMD_TIMEOUT);
+ if (IS_ERR(skb)) {
+ bt_dev_err(hdev, "Host Hello command failed: %ld", PTR_ERR(skb));
+ ret = PTR_ERR(skb);
+ }
+
+free_buf:
+ kfree(buf);
+free_key:
+ memset(p.key, 0, p.key_size);
+ kfree(p.key);
+ if (ret)
+ return ERR_PTR(ret);
+ else
+ return skb;
+}
+
static int nxp_authenticate_device(struct hci_dev *hdev)
{
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
size_t desc_size = 0;
+ struct sk_buff *skb;
int ret = 0;
nxpdev->crypto.tls_handshake_hash_tfm = crypto_alloc_shash("sha256", 0, 0);
@@ -1634,12 +1813,20 @@ static int nxp_authenticate_device(struct hci_dev *hdev)
nxpdev->crypto.tls_handshake_hash_desc->tfm = nxpdev->crypto.tls_handshake_hash_tfm;
crypto_shash_init(nxpdev->crypto.tls_handshake_hash_desc);
+ skb = nxp_host_do_hello(hdev);
+ if (IS_ERR(skb)) {
+ ret = PTR_ERR(skb);
+ goto free_kpp;
+ }
+
/* TODO: Implement actual TLS handshake protocol
* This will include:
- * 1. Host/Device hello message exchange
+ * 1. Handle Device hello message exchange
* 2. Master secret and traffic key derivation
*/
+free_skb:
+ kfree_skb(skb);
free_kpp:
crypto_free_kpp(nxpdev->crypto.kpp);
nxpdev->crypto.kpp = NULL;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 06/11] Bluetooth: btnxpuart: Add TLS device hello processing
2026-01-13 7:47 [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Neeraj Sanjay Kale
` (4 preceding siblings ...)
2026-01-13 7:47 ` [PATCH v2 05/11] Bluetooth: btnxpuart: Add TLS host hello handshake implementation Neeraj Sanjay Kale
@ 2026-01-13 7:47 ` Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 07/11] Bluetooth: btnxpuart: Add device authentication Neeraj Sanjay Kale
` (5 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Neeraj Sanjay Kale @ 2026-01-13 7:47 UTC (permalink / raw)
To: marcel, luiz.dentz
Cc: amitkumar.karwar, neeraj.sanjaykale, sherry.sun, dmitrii.lebed,
linux-bluetooth, linux-kernel
This implements device hello message processing to derive handshake
traffic secrets:
- Add HKDF-SHA256 functions for TLS 1.3 traffic secret derivation
following RFC 5869/8446
- Extract device ECDH public key and compute shared secret using
KPP API with host private key and device public key
- Derive handshake traffic secret from ECDH shared secret
following TLS 1.3 key schedule
- Validate device hello message and update handshake hash state
The handshake traffic secret enables decryption of the
device_finish portion within the device_hello message.
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
---
drivers/bluetooth/btnxpuart.c | 274 +++++++++++++++++++++++++++++++++-
1 file changed, 270 insertions(+), 4 deletions(-)
diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index 8208b0748f97..0e71f68a408e 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -150,8 +150,9 @@
#define FW_METADATA_TLV_ECDSA_KEY 0x50
#define FW_METADATA_FLAG_BT 0x02
-#define NXP_FW_UUID_SIZE 16
-#define NXP_FW_ECDSA_PUBKEY_SIZE 65
+#define NXP_FW_UUID_SIZE 16
+#define NXP_FW_ECDH_PUBKEY_SIZE 64
+#define NXP_FW_ECDSA_PUBKEY_SIZE 65
struct ps_data {
u8 target_ps_mode; /* ps mode to be set */
@@ -203,8 +204,11 @@ struct btnxpuart_crypto {
struct crypto_shash *tls_handshake_hash_tfm;
struct shash_desc *tls_handshake_hash_desc;
struct crypto_kpp *kpp;
+ uint8_t ecdh_public[NXP_FW_ECDH_PUBKEY_SIZE]; /* ECDH public key, Key negotiation */
u8 ecdsa_public[NXP_FW_ECDSA_PUBKEY_SIZE]; /* ECDSA public key, Authentication*/
u8 fw_uuid[NXP_FW_UUID_SIZE];
+ u8 handshake_h2_hash[SHA256_DIGEST_SIZE];
+ u8 handshake_secret[SHA256_DIGEST_SIZE];
};
struct btnxpuart_dev {
@@ -396,6 +400,11 @@ union nxp_set_bd_addr_payload {
#define NXP_TLS_VERSION 1
#define NXP_TLS_ECDH_PUBLIC_KEY_SIZE 64
+#define NXP_DEVICE_UUID_LEN 16
+#define NXP_ENC_AUTH_TAG_SIZE 16
+
+#define NXP_TLS_LABEL(str) str, strlen(str)
+#define NXP_TLS_DEVICE_HS_TS_LABEL NXP_TLS_LABEL("D HS TS")
enum nxp_tls_signature_algorithm {
NXP_TLS_ECDSA_SECP256R1_SHA256 = 0x0403,
@@ -440,6 +449,38 @@ union nxp_tls_host_hello_payload {
u8 buf[113];
};
+struct nxp_tls_device_info {
+ __le16 chip_id;
+ __le16 device_flags;
+ u8 reserved[4];
+ u8 uuid[NXP_DEVICE_UUID_LEN];
+};
+
+struct nxp_tls_signature {
+ u8 sig[64]; /* P-256 ECDSA signature, two points */
+};
+
+struct nxp_tls_finished {
+ u8 verify_data[32];
+};
+
+struct nxp_tls_device_hello {
+ struct nxp_tls_message_hdr hdr;
+ __le32 reserved;
+ u8 random[32];
+ u8 pubkey[NXP_TLS_ECDH_PUBLIC_KEY_SIZE];
+ /* Encrypted portion */
+ struct {
+ struct nxp_tls_device_info device_info;
+ struct nxp_tls_signature device_handshake_sig; /* TLS Certificate Verify */
+ struct nxp_tls_finished device_finished;
+ } enc;
+ u8 auth_tag[NXP_ENC_AUTH_TAG_SIZE]; /* Auth tag for the encrypted portion */
+};
+
+#define DEVICE_HELLO_SIG_CUTOFF_POS \
+ offsetof(struct nxp_tls_device_hello, enc)
+
/* FW Meta Data */
struct fw_metadata_hdr {
__le32 cmd;
@@ -1698,7 +1739,7 @@ static int nxp_generate_ecdh_public_key(struct crypto_kpp *tfm, u8 public_key[64
}
static inline void nxp_tls_hdr_init(struct nxp_tls_message_hdr *hdr, size_t len,
- enum nxp_tls_message_id id)
+ enum nxp_tls_message_id id)
{
hdr->magic = cpu_to_le32(NXP_TLS_MAGIC);
hdr->len = cpu_to_le16((u16)len);
@@ -1785,11 +1826,222 @@ static struct sk_buff *nxp_host_do_hello(struct hci_dev *hdev)
return skb;
}
+static int nxp_crypto_shash_final(struct shash_desc *desc, u8 *out)
+{
+ struct shash_desc *desc_tmp = kzalloc(sizeof(struct shash_desc) +
+ crypto_shash_descsize(desc->tfm),
+ GFP_KERNEL);
+
+ if (!desc_tmp)
+ return -ENOMEM;
+
+ crypto_shash_export(desc, desc_tmp);
+ crypto_shash_final(desc, out);
+ crypto_shash_import(desc, desc_tmp);
+ kfree(desc_tmp);
+
+ return 0;
+}
+
+static int nxp_compute_shared_secret(struct crypto_kpp *tfm, const u8 public_key[64], u8 secret[32])
+{
+ DECLARE_CRYPTO_WAIT(result);
+ struct kpp_request *req;
+ struct scatterlist src, dst;
+ int err;
+
+ req = kpp_request_alloc(tfm, GFP_KERNEL);
+ if (!req) {
+ pr_err("Failed to allocate memory for KPP request\n");
+ return -ENOMEM;
+ }
+
+ sg_init_one(&src, public_key, 64);
+ sg_init_one(&dst, secret, 32);
+ kpp_request_set_input(req, &src, 64);
+ kpp_request_set_output(req, &dst, 32);
+ kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ crypto_req_done, &result);
+ err = crypto_kpp_compute_shared_secret(req);
+ err = crypto_wait_req(err, &result);
+ if (err < 0) {
+ pr_err("alg: ecdh: compute shared secret failed. err %d\n", err);
+ goto free_all;
+ }
+
+free_all:
+ kpp_request_free(req);
+ return err;
+}
+
+static int nxp_hkdf_sha256_extract(const void *salt, size_t salt_len,
+ const void *ikm, size_t ikm_len,
+ u8 result[SHA256_DIGEST_SIZE])
+{
+ struct crypto_shash *tfm;
+ struct shash_desc *desc;
+ u8 zeroes[SHA256_DIGEST_SIZE] = {0};
+ int ret = 0;
+
+ tfm = crypto_alloc_shash("hmac(sha256)", 0, 0);
+ if (IS_ERR(tfm))
+ return PTR_ERR(tfm);
+
+ desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL);
+ if (!desc) {
+ crypto_free_shash(tfm);
+ return -ENOMEM;
+ }
+
+ desc->tfm = tfm;
+
+ /* RFC 5869: If salt is empty, use HashLen zero octets */
+ if (salt_len == 0)
+ ret = crypto_shash_setkey(tfm, zeroes, SHA256_DIGEST_SIZE);
+ else
+ ret = crypto_shash_setkey(tfm, salt, salt_len);
+
+ if (ret)
+ goto cleanup;
+
+ ret = crypto_shash_init(desc);
+ if (ret)
+ goto cleanup;
+
+ ret = crypto_shash_update(desc, ikm, ikm_len);
+ if (ret)
+ goto cleanup;
+
+ ret = crypto_shash_final(desc, result);
+
+cleanup:
+ kfree(desc);
+ crypto_free_shash(tfm);
+ return ret;
+}
+
+static int nxp_hkdf_expand_label(const u8 secret[SHA256_DIGEST_SIZE],
+ const char *label, size_t label_size,
+ u8 *context, size_t context_size,
+ void *output, size_t output_size)
+{
+ struct crypto_shash *tfm = crypto_alloc_shash("hmac(sha256)", 0, 0);
+ struct shash_desc *desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(tfm),
+ GFP_KERNEL);
+ u8 hmac_out[SHA256_DIGEST_SIZE];
+ u16 length = output_size;
+ u8 one = 0x01;
+
+ if (IS_ERR(tfm)) {
+ pr_err("Failed to alloc shash for HMAC\n");
+ return -ENOMEM;
+ }
+
+ if (!desc) {
+ crypto_free_shash(tfm);
+ return -ENOMEM;
+ }
+
+ crypto_shash_setkey(tfm, secret, SHA256_DIGEST_SIZE);
+ desc->tfm = tfm;
+
+ crypto_shash_init(desc);
+ crypto_shash_update(desc, (u8 *)&length, sizeof(length));
+ crypto_shash_update(desc, label, label_size);
+
+ if (context && context_size > 0)
+ crypto_shash_update(desc, context, context_size);
+
+ /* RFC 5869: HKDF-Expand counter starts at 0x01 */
+ crypto_shash_update(desc, &one, sizeof(one));
+ crypto_shash_final(desc, hmac_out);
+
+ memcpy(output, hmac_out, output_size);
+
+ kfree(desc);
+ crypto_free_shash(tfm);
+ return 0;
+}
+
+static int nxp_hkdf_derive_secret(u8 secret[32], const char *label, size_t label_size,
+ u8 context[SHA256_DIGEST_SIZE],
+ u8 output[SHA256_DIGEST_SIZE])
+{
+ return nxp_hkdf_expand_label(secret, label, label_size, context, SHA256_DIGEST_SIZE,
+ output, SHA256_DIGEST_SIZE);
+}
+
+static int nxp_process_device_hello(struct hci_dev *hdev, struct nxp_tls_device_hello *msg)
+{
+ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ struct nxp_tls_message_hdr *hdr;
+ u8 hs_traffic_secret[SHA256_DIGEST_SIZE];
+ u8 *shared_secret = NULL;
+ int ret;
+
+ if (!msg)
+ return -EINVAL;
+
+ hdr = &msg->hdr;
+
+ if (le32_to_cpu(hdr->magic) != NXP_TLS_MAGIC ||
+ le16_to_cpu(hdr->len) != sizeof(*msg) ||
+ hdr->message_id != NXP_TLS_DEVICE_HELLO ||
+ hdr->protocol_version != NXP_TLS_VERSION) {
+ bt_dev_err(hdev, "Invalid device hello header");
+ return -EINVAL;
+ }
+
+ shared_secret = kzalloc(32, GFP_KERNEL);
+ if (!shared_secret)
+ return -ENOMEM;
+
+ ret = crypto_shash_update(nxpdev->crypto.tls_handshake_hash_desc, (u8 *)msg,
+ DEVICE_HELLO_SIG_CUTOFF_POS);
+ if (ret)
+ goto fail;
+
+ ret = nxp_crypto_shash_final(nxpdev->crypto.tls_handshake_hash_desc,
+ nxpdev->crypto.handshake_h2_hash);
+ if (ret)
+ goto fail;
+
+ memcpy(nxpdev->crypto.ecdh_public, msg->pubkey, NXP_FW_ECDH_PUBKEY_SIZE);
+
+ ret = nxp_compute_shared_secret(nxpdev->crypto.kpp, nxpdev->crypto.ecdh_public,
+ shared_secret);
+ if (ret)
+ goto fail;
+
+ ret = nxp_hkdf_sha256_extract(NULL, 0, shared_secret, 32,
+ nxpdev->crypto.handshake_secret);
+ if (ret)
+ goto fail;
+
+ ret = nxp_hkdf_derive_secret(nxpdev->crypto.handshake_secret,
+ NXP_TLS_DEVICE_HS_TS_LABEL,
+ nxpdev->crypto.handshake_h2_hash,
+ hs_traffic_secret);
+ if (ret)
+ goto fail;
+
+ /* TODO: Verify Signature in Device Hello using ECDSA Public Key
+ * extracted from the FW metadata.
+ */
+
+fail:
+ memset(shared_secret, 0, 32);
+ kfree(shared_secret);
+ return ret;
+}
+
static int nxp_authenticate_device(struct hci_dev *hdev)
{
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ struct nxp_tls_device_hello *device_hello;
size_t desc_size = 0;
struct sk_buff *skb;
+ u8 *status;
int ret = 0;
nxpdev->crypto.tls_handshake_hash_tfm = crypto_alloc_shash("sha256", 0, 0);
@@ -1819,9 +2071,23 @@ static int nxp_authenticate_device(struct hci_dev *hdev)
goto free_kpp;
}
+ status = skb_pull_data(skb, 1);
+ if (*status)
+ goto free_skb;
+
+ if (skb->len != sizeof(struct nxp_tls_device_hello)) {
+ bt_dev_err(hdev, "Invalid Device Hello Length: %d", skb->len);
+ goto free_skb;
+ }
+
+ device_hello = skb_pull_data(skb, sizeof(*device_hello));
+ ret = nxp_process_device_hello(hdev, device_hello);
+ if (ret)
+ goto free_skb;
+
/* TODO: Implement actual TLS handshake protocol
* This will include:
- * 1. Handle Device hello message exchange
+ * 1. Send Host Finish TLS message
* 2. Master secret and traffic key derivation
*/
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 07/11] Bluetooth: btnxpuart: Add device authentication
2026-01-13 7:47 [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Neeraj Sanjay Kale
` (5 preceding siblings ...)
2026-01-13 7:47 ` [PATCH v2 06/11] Bluetooth: btnxpuart: Add TLS device hello processing Neeraj Sanjay Kale
@ 2026-01-13 7:47 ` Neeraj Sanjay Kale
2026-01-21 19:19 ` Marcel Holtmann
2026-01-13 7:47 ` [PATCH v2 08/11] Bluetooth: btnxpuart: Derive traffic keys from TLS 1.3 handshake Neeraj Sanjay Kale
` (4 subsequent siblings)
11 siblings, 1 reply; 23+ messages in thread
From: Neeraj Sanjay Kale @ 2026-01-13 7:47 UTC (permalink / raw)
To: marcel, luiz.dentz
Cc: amitkumar.karwar, neeraj.sanjaykale, sherry.sun, dmitrii.lebed,
linux-bluetooth, linux-kernel
This implements secure device authentication during TLS 1.3-like
handshake with ECDSA signature verification.
The authentication flow:
- Derive handshake traffic secret from ECDH shared secret
- Decrypt device hello encrypted section using AES-GCM with traffic secret
- Extract ECDSA public key from firmware metadata for verification
- Verify device handshake signature to authenticate device identity
- Validate device finished message using calculated verify data
- Clear handshake traffic secret after successful authentication
This ensures only devices with valid private keys can complete the
handshake.
Key components added:
- AES-GCM encrypt/decrypt with traffic secret derived keys
- ECDSA P-256 signature verification using kernel crypto API
- X9.62 to P1363 signature format conversion
- TLS 1.3 finished message verification
- Secure memory cleanup of cryptographic material
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
---
v2: Fix sparse warnings. (kernel test robot)
---
drivers/bluetooth/btnxpuart.c | 504 +++++++++++++++++++++++++++++++++-
1 file changed, 499 insertions(+), 5 deletions(-)
diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index 0e71f68a408e..9ed4cece7e42 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -27,6 +27,12 @@
#include <crypto/hash.h>
#include <crypto/kpp.h>
#include <crypto/ecdh.h>
+#include <linux/scatterlist.h>
+#include <linux/completion.h>
+#include <crypto/aes.h>
+#include <crypto/gcm.h>
+#include <crypto/aead.h>
+#include <crypto/public_key.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -204,11 +210,13 @@ struct btnxpuart_crypto {
struct crypto_shash *tls_handshake_hash_tfm;
struct shash_desc *tls_handshake_hash_desc;
struct crypto_kpp *kpp;
- uint8_t ecdh_public[NXP_FW_ECDH_PUBKEY_SIZE]; /* ECDH public key, Key negotiation */
+ u8 ecdh_public[NXP_FW_ECDH_PUBKEY_SIZE]; /* ECDH public key, Key negotiation */
u8 ecdsa_public[NXP_FW_ECDSA_PUBKEY_SIZE]; /* ECDSA public key, Authentication*/
u8 fw_uuid[NXP_FW_UUID_SIZE];
u8 handshake_h2_hash[SHA256_DIGEST_SIZE];
u8 handshake_secret[SHA256_DIGEST_SIZE];
+ struct completion completion;
+ int decrypt_result;
};
struct btnxpuart_dev {
@@ -405,6 +413,10 @@ union nxp_set_bd_addr_payload {
#define NXP_TLS_LABEL(str) str, strlen(str)
#define NXP_TLS_DEVICE_HS_TS_LABEL NXP_TLS_LABEL("D HS TS")
+#define NXP_TLS_KEYING_IV_LABEL NXP_TLS_LABEL("iv")
+#define NXP_TLS_KEYING_KEY_LABEL NXP_TLS_LABEL("key")
+#define NXP_TLS_FINISHED_LABEL NXP_TLS_LABEL("finished")
+#define NXP_TLS_HOST_HS_TS_LABEL NXP_TLS_LABEL("H HS TS")
enum nxp_tls_signature_algorithm {
NXP_TLS_ECDSA_SECP256R1_SHA256 = 0x0403,
@@ -478,9 +490,42 @@ struct nxp_tls_device_hello {
u8 auth_tag[NXP_ENC_AUTH_TAG_SIZE]; /* Auth tag for the encrypted portion */
};
+struct nxp_tls_data_add {
+ u8 version; /* NXP_TLS_VERSION */
+ u8 reserved[5]; /* zeroes */
+ __le16 len;
+};
+
+struct nxp_tls_host_finished {
+ struct nxp_tls_message_hdr hdr;
+ __le32 reserved;
+ /* Encrypted portion */
+ struct {
+ struct nxp_tls_signature reserved2;
+ struct nxp_tls_finished host_finished;
+ } enc;
+ u8 auth_tag[NXP_ENC_AUTH_TAG_SIZE]; /* Auth tag for the encrypted portion */
+};
+
+union nxp_tls_host_finished_payload {
+ struct {
+ u8 msg_type;
+ struct nxp_tls_host_finished host_finished;
+ } __packed;
+ u8 buf[125];
+};
+
#define DEVICE_HELLO_SIG_CUTOFF_POS \
offsetof(struct nxp_tls_device_hello, enc)
+#define DEVICE_HELLO_FINISHED_ENC_CUTOFF_POS \
+ (offsetof(struct nxp_tls_device_hello, enc.device_finished) - \
+ DEVICE_HELLO_SIG_CUTOFF_POS)
+
+
+#define HOST_FINISHED_CUTOFF_POS \
+ offsetof(struct nxp_tls_host_finished, enc.host_finished)
+
/* FW Meta Data */
struct fw_metadata_hdr {
__le32 cmd;
@@ -1700,6 +1745,38 @@ static void nxp_get_fw_version(struct hci_dev *hdev)
}
/* Secure Interface */
+static int nxp_get_pub_key(struct hci_dev *hdev,
+ const struct nxp_tls_device_info *device_info,
+ u8 ecdsa_pub_key[NXP_FW_ECDSA_PUBKEY_SIZE])
+{
+ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ const char *fw_name;
+
+ if (ecdsa_pub_key[0] == 0x04)
+ return 0;
+
+ fw_name = nxp_get_fw_name_from_chipid(hdev,
+ le16_to_cpu(device_info->chip_id),
+ le16_to_cpu(device_info->device_flags));
+ if (nxp_request_firmware(hdev, fw_name, NULL))
+ return -ENOENT;
+
+ nxp_process_fw_meta_data(hdev, nxpdev->fw);
+ release_firmware(nxpdev->fw);
+ memset(nxpdev->fw_name, 0, sizeof(nxpdev->fw_name));
+
+ if (memcmp(nxpdev->crypto.fw_uuid, device_info->uuid, 16) ||
+ nxpdev->crypto.ecdsa_public[0] != 0x04) {
+ bt_dev_err(hdev,
+ "UUID check failed while trying to read ECDSA public key from FW.");
+ return -EBADF;
+ }
+
+ memcpy(ecdsa_pub_key, nxpdev->crypto.ecdsa_public, 65);
+
+ return 0;
+}
+
static int nxp_generate_ecdh_public_key(struct crypto_kpp *tfm, u8 public_key[64])
{
DECLARE_CRYPTO_WAIT(result);
@@ -1971,6 +2048,320 @@ static int nxp_hkdf_derive_secret(u8 secret[32], const char *label, size_t label
output, SHA256_DIGEST_SIZE);
}
+/*
+ * The digital signature is computed over the concatenation of:
+ * - A string that consists of octet 32 (0x20) repeated 64 times
+ * - The context string
+ * - A single 0 byte which serves as the separator
+ * - The content to be signed
+ */
+static int nxp_handshake_sig_hash(const u8 transcript_hash[SHA256_DIGEST_SIZE],
+ const char *context, size_t context_len,
+ u8 output_hash[SHA256_DIGEST_SIZE])
+{
+ struct crypto_shash *tfm;
+ struct shash_desc *desc;
+ const u8 zero = 0;
+
+ tfm = crypto_alloc_shash("sha256", 0, 0);
+ if (IS_ERR(tfm))
+ return PTR_ERR(tfm);
+
+ desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL);
+ if (!desc) {
+ crypto_free_shash(tfm);
+ return -ENOMEM;
+ }
+
+ desc->tfm = tfm;
+
+ memset(output_hash, 0x20, SHA256_DIGEST_SIZE);
+
+ crypto_shash_init(desc);
+ /* 2x hash size = block size of 0x20 */
+ crypto_shash_update(desc, output_hash, SHA256_DIGEST_SIZE);
+ crypto_shash_update(desc, output_hash, SHA256_DIGEST_SIZE);
+
+ crypto_shash_update(desc, context, context_len);
+ crypto_shash_update(desc, &zero, sizeof(zero));
+
+ crypto_shash_update(desc, transcript_hash, SHA256_DIGEST_SIZE);
+ crypto_shash_final(desc, output_hash);
+
+ kfree(desc);
+ crypto_free_shash(tfm);
+ return 0;
+}
+
+
+static void nxp_aead_complete(void *req, int err)
+{
+ struct btnxpuart_crypto *crypto = req;
+
+ crypto->decrypt_result = err;
+ complete(&crypto->completion);
+}
+
+static int nxp_aes_gcm_decrypt(struct hci_dev *hdev, void *buf, size_t size,
+ u8 auth_tag[16], u8 key[AES_KEYSIZE_128],
+ u8 iv[GCM_AES_IV_SIZE])
+{
+ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ struct crypto_aead *tfm;
+ struct aead_request *req;
+ struct scatterlist src, dst;
+ struct nxp_tls_data_add aad = {
+ .version = NXP_TLS_VERSION,
+ .len = cpu_to_le16((u16)size)
+ };
+ u8 *ciphertext;
+ u8 *plaintext;
+ int ret = 0;
+
+ ciphertext = kzalloc(sizeof(aad) + size + NXP_ENC_AUTH_TAG_SIZE,
+ GFP_KERNEL);
+ if (!ciphertext)
+ return -ENOMEM;
+
+ plaintext = kzalloc(size + NXP_ENC_AUTH_TAG_SIZE, GFP_KERNEL);
+ if (!plaintext) {
+ ret = -ENOMEM;
+ goto free_ciphertext;
+ }
+
+ memcpy(ciphertext, &aad, sizeof(aad));
+ memcpy(ciphertext + sizeof(aad), buf, size);
+ memcpy(ciphertext + sizeof(aad) + size, auth_tag, NXP_ENC_AUTH_TAG_SIZE);
+
+ tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
+ if (IS_ERR(tfm)) {
+ ret = PTR_ERR(tfm);
+ goto free_plaintext;
+ }
+
+ crypto_aead_setkey(tfm, key, AES_KEYSIZE_128);
+ crypto_aead_setauthsize(tfm, NXP_ENC_AUTH_TAG_SIZE);
+
+ req = aead_request_alloc(tfm, GFP_KERNEL);
+ if (!req) {
+ ret = -ENOMEM;
+ goto free_tfm;
+ }
+
+ sg_init_one(&src, ciphertext, sizeof(aad) + size + NXP_ENC_AUTH_TAG_SIZE);
+ sg_init_one(&dst, plaintext, size + NXP_ENC_AUTH_TAG_SIZE);
+ init_completion(&nxpdev->crypto.completion);
+
+ aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ nxp_aead_complete, &nxpdev->crypto);
+ aead_request_set_crypt(req, &src, &dst, size + NXP_ENC_AUTH_TAG_SIZE, iv);
+ aead_request_set_ad(req, sizeof(aad));
+
+ ret = crypto_aead_decrypt(req);
+ if (ret == -EINPROGRESS || ret == -EBUSY) {
+ wait_for_completion(&nxpdev->crypto.completion);
+ ret = nxpdev->crypto.decrypt_result;
+ }
+ if (!ret)
+ memcpy(buf, plaintext + sizeof(aad), size);
+
+ aead_request_free(req);
+free_tfm:
+ crypto_free_aead(tfm);
+free_plaintext:
+ kfree(plaintext);
+free_ciphertext:
+ kfree(ciphertext);
+ return ret;
+}
+
+static int nxp_aes_gcm_encrypt(struct hci_dev *hdev, void *buf, size_t size, u8 auth_tag[16],
+ u8 key[AES_KEYSIZE_128], u8 iv[GCM_AES_IV_SIZE])
+{
+ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ struct crypto_aead *tfm;
+ struct aead_request *req;
+ struct scatterlist src, dst;
+ struct nxp_tls_data_add aad = {
+ .version = NXP_TLS_VERSION,
+ .len = cpu_to_le16((u16)size)
+ };
+ u8 *ciphertext;
+ u8 *plaintext;
+ int ret = 0;
+
+ ciphertext = kzalloc(sizeof(aad) + size + NXP_ENC_AUTH_TAG_SIZE,
+ GFP_KERNEL);
+ if (!ciphertext)
+ return -ENOMEM;
+
+ plaintext = kzalloc(size + NXP_ENC_AUTH_TAG_SIZE, GFP_KERNEL);
+ if (!plaintext) {
+ ret = -ENOMEM;
+ goto free_ciphertext;
+ }
+
+ memcpy(plaintext, &aad, sizeof(aad));
+ memcpy(plaintext + sizeof(aad), buf, size);
+
+ tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
+ if (IS_ERR(tfm)) {
+ ret = PTR_ERR(tfm);
+ goto free_plaintext;
+ }
+
+ crypto_aead_setkey(tfm, key, AES_KEYSIZE_128);
+ crypto_aead_setauthsize(tfm, NXP_ENC_AUTH_TAG_SIZE);
+
+ req = aead_request_alloc(tfm, GFP_KERNEL);
+ if (!req) {
+ ret = -ENOMEM;
+ goto free_tfm;
+ }
+
+ sg_init_one(&src, plaintext, size + NXP_ENC_AUTH_TAG_SIZE);
+ sg_init_one(&dst, ciphertext, sizeof(aad) + size + NXP_ENC_AUTH_TAG_SIZE);
+ init_completion(&nxpdev->crypto.completion);
+
+ aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ nxp_aead_complete, &nxpdev->crypto);
+ aead_request_set_crypt(req, &src, &dst, size, iv);
+ aead_request_set_ad(req, sizeof(aad));
+
+ ret = crypto_aead_encrypt(req);
+ if (ret == -EINPROGRESS || ret == -EBUSY) {
+ wait_for_completion(&nxpdev->crypto.completion);
+ ret = nxpdev->crypto.decrypt_result;
+ }
+ if (!ret) {
+ memcpy(buf, ciphertext + sizeof(aad), size);
+ memcpy(auth_tag, ciphertext + size + sizeof(aad), NXP_ENC_AUTH_TAG_SIZE);
+ }
+
+ aead_request_free(req);
+free_tfm:
+ crypto_free_aead(tfm);
+free_plaintext:
+ kfree(plaintext);
+free_ciphertext:
+ kfree(ciphertext);
+ return ret;
+}
+
+static int nxp_handshake_decrypt_verify(struct hci_dev *hdev, void *buf, size_t size,
+ u8 auth_tag[16],
+ u8 traffic_secret[SHA256_DIGEST_SIZE])
+{
+ u8 key[AES_KEYSIZE_128] = {0};
+ u8 iv[GCM_AES_IV_SIZE] = {0};
+
+ nxp_hkdf_expand_label(traffic_secret, NXP_TLS_KEYING_KEY_LABEL, NULL, 0,
+ key, AES_KEYSIZE_128);
+ nxp_hkdf_expand_label(traffic_secret, NXP_TLS_KEYING_IV_LABEL, NULL, 0,
+ iv, GCM_AES_IV_SIZE);
+
+ return nxp_aes_gcm_decrypt(hdev, buf, size, auth_tag, key, iv);
+}
+
+static int nxp_handshake_encrypt(struct hci_dev *hdev, void *buf,
+ size_t size, u8 auth_tag[16],
+ u8 traffic_secret[SHA256_DIGEST_SIZE])
+{
+ u8 key[AES_KEYSIZE_128] = {0};
+ u8 iv[GCM_AES_IV_SIZE] = {0};
+
+ nxp_hkdf_expand_label(traffic_secret, NXP_TLS_KEYING_KEY_LABEL, NULL,
+ 0, key, AES_KEYSIZE_128);
+ nxp_hkdf_expand_label(traffic_secret, NXP_TLS_KEYING_IV_LABEL, NULL,
+ 0, iv, GCM_AES_IV_SIZE);
+
+ return nxp_aes_gcm_encrypt(hdev, buf, size, auth_tag, key, iv);
+}
+
+static int nxp_p256_ecdsa_verify(const u8 sig[64], const u8 pub[65],
+ const u8 *hash, size_t hash_len)
+{
+ struct public_key_signature sig_info = {0};
+ struct public_key pub_key = {0};
+ int ret;
+
+ sig_info.s = (u8 *)sig;
+ sig_info.s_size = 64;
+ sig_info.digest = (u8 *)hash;
+ sig_info.digest_size = hash_len;
+ sig_info.pkey_algo = "ecdsa";
+ sig_info.hash_algo = "sha256";
+ sig_info.encoding = "p1363";
+
+ pub_key.key = (void *)pub;
+ pub_key.keylen = 65;
+ pub_key.algo = OID_id_ecPublicKey;
+ pub_key.key_is_private = false;
+ pub_key.pkey_algo = "ecdsa-nist-p256";
+ pub_key.id_type = NULL;
+
+ ret = public_key_verify_signature(&pub_key, &sig_info);
+ if (ret)
+ pr_err("ECDSA signature verification failed: %d\n", ret);
+
+ return ret;
+}
+
+static int nxp_device_hello_sig_verify(struct hci_dev *hdev, struct nxp_tls_device_hello *msg)
+{
+ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ u8 hash_sig[SHA256_DIGEST_SIZE];
+
+ nxp_handshake_sig_hash(nxpdev->crypto.handshake_h2_hash,
+ "D HS SIG", 8, hash_sig);
+ return nxp_p256_ecdsa_verify(msg->enc.device_handshake_sig.sig,
+ nxpdev->crypto.ecdsa_public,
+ hash_sig, SHA256_DIGEST_SIZE);
+}
+
+static int nxp_write_finished(struct hci_dev *hdev,
+ const u8 hs_traffic_secret[SHA256_DIGEST_SIZE],
+ u8 verify_data[SHA256_DIGEST_SIZE])
+{
+ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ u8 transcript_hash[SHA256_DIGEST_SIZE];
+ u8 finished_key[SHA256_DIGEST_SIZE];
+ int ret = 0;
+
+ ret = nxp_crypto_shash_final(nxpdev->crypto.tls_handshake_hash_desc,
+ transcript_hash);
+ if (ret)
+ return ret;
+
+ ret = nxp_hkdf_expand_label(hs_traffic_secret, NXP_TLS_FINISHED_LABEL,
+ NULL, 0, finished_key, sizeof(finished_key));
+ if (ret)
+ return ret;
+
+ nxp_hkdf_sha256_extract(finished_key, SHA256_DIGEST_SIZE, transcript_hash,
+ SHA256_DIGEST_SIZE, verify_data);
+
+ return 0;
+}
+
+static int nxp_verify_device_finished(struct hci_dev *hdev,
+ struct nxp_tls_device_hello *msg,
+ const u8 hs_traffic_secret[SHA256_DIGEST_SIZE])
+{
+ u8 verify_data[SHA256_DIGEST_SIZE] = {0};
+ int ret = 0;
+
+ ret = nxp_write_finished(hdev, hs_traffic_secret, verify_data);
+ if (ret)
+ return ret;
+
+ if (memcmp(verify_data, msg->enc.device_finished.verify_data,
+ SHA256_DIGEST_SIZE))
+ return -EBADMSG;
+
+ return 0;
+}
+
static int nxp_process_device_hello(struct hci_dev *hdev, struct nxp_tls_device_hello *msg)
{
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
@@ -2025,9 +2416,51 @@ static int nxp_process_device_hello(struct hci_dev *hdev, struct nxp_tls_device_
if (ret)
goto fail;
- /* TODO: Verify Signature in Device Hello using ECDSA Public Key
- * extracted from the FW metadata.
+ ret = nxp_handshake_decrypt_verify(hdev, &msg->enc, sizeof(msg->enc),
+ msg->auth_tag, hs_traffic_secret);
+ if (ret)
+ goto fail;
+
+ /*
+ * Verify ECDSA signature handshake_sig using Device's public key from FW metadata.
+ *
+ * This is the key point where Device authentication happens:
+ * - Host generates a random (HostHello.random)
+ * - Device signs the entire handshake (incl. Host's random) with its
+ * private key (DeviceHello.device_handshake_sig)
+ * - Host now verifies ECDSA signature generated by device using Device's
+ * public key
+ *
+ * Only the device that possesses the proper private key could sign the
+ * Host's random.
+ * If the device is an impostor and does not pose a valid private key,
+ * the handshake will fail at this point.
*/
+ ret = nxp_get_pub_key(hdev, &msg->enc.device_info, nxpdev->crypto.ecdsa_public);
+ if (ret)
+ goto fail;
+
+ ret = nxp_device_hello_sig_verify(hdev, msg);
+ if (ret)
+ goto fail;
+
+ ret = crypto_shash_update(nxpdev->crypto.tls_handshake_hash_desc,
+ (u8 *)&msg->enc,
+ DEVICE_HELLO_FINISHED_ENC_CUTOFF_POS);
+ if (ret)
+ goto fail;
+
+ ret = nxp_verify_device_finished(hdev, msg, hs_traffic_secret);
+ if (ret)
+ goto fail;
+
+ ret = crypto_shash_update(nxpdev->crypto.tls_handshake_hash_desc,
+ (u8 *)&msg->enc.device_finished,
+ sizeof(msg->enc.device_finished));
+ if (ret)
+ goto fail;
+
+ memset(hs_traffic_secret, 0, SHA256_DIGEST_SIZE);
fail:
memset(shared_secret, 0, 32);
@@ -2035,6 +2468,64 @@ static int nxp_process_device_hello(struct hci_dev *hdev, struct nxp_tls_device_
return ret;
}
+static int nxp_host_do_finished(struct hci_dev *hdev)
+{
+ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ union nxp_tls_host_finished_payload finished;
+ struct nxp_tls_host_finished *msg = &finished.host_finished;
+ u8 hs_traffic_secret[SHA256_DIGEST_SIZE];
+ struct sk_buff *skb;
+ u8 *status;
+ int ret = 0;
+
+ memset(msg, 0, sizeof(*msg));
+ nxp_tls_hdr_init(&msg->hdr, sizeof(*msg), NXP_TLS_HOST_FINISHED);
+
+ crypto_shash_update(nxpdev->crypto.tls_handshake_hash_desc,
+ (u8 *)msg, HOST_FINISHED_CUTOFF_POS);
+
+ ret = nxp_hkdf_derive_secret(nxpdev->crypto.handshake_secret,
+ NXP_TLS_HOST_HS_TS_LABEL,
+ nxpdev->crypto.handshake_h2_hash,
+ hs_traffic_secret);
+ if (ret)
+ return ret;
+
+ ret = nxp_write_finished(hdev, hs_traffic_secret,
+ msg->enc.host_finished.verify_data);
+ if (ret)
+ return ret;
+
+ crypto_shash_update(nxpdev->crypto.tls_handshake_hash_desc,
+ (u8 *)&msg->enc.host_finished, sizeof(msg->enc.host_finished));
+
+ nxp_handshake_encrypt(hdev, &msg->enc, sizeof(msg->enc),
+ msg->auth_tag, hs_traffic_secret);
+
+ finished.msg_type = 0x01;
+
+ skb = __hci_cmd_sync(hdev, HCI_NXP_SHI_ENCRYPT,
+ sizeof(finished), finished.buf,
+ HCI_CMD_TIMEOUT);
+ if (IS_ERR(skb)) {
+ bt_dev_err(hdev, "Host Finished error %ld", PTR_ERR(skb));
+ return PTR_ERR(skb);
+ }
+ status = skb_pull_data(skb, 1);
+ if (!status) {
+ ret = -EIO;
+ goto fail;
+ }
+ if (*status) {
+ ret = -EIO;
+ bt_dev_err(hdev, "Host Finished status error: %d", *status);
+ }
+
+fail:
+ kfree_skb(skb);
+ return ret;
+}
+
static int nxp_authenticate_device(struct hci_dev *hdev)
{
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
@@ -2085,10 +2576,13 @@ static int nxp_authenticate_device(struct hci_dev *hdev)
if (ret)
goto free_skb;
+ ret = nxp_host_do_finished(hdev);
+ if (ret)
+ goto free_skb;
+
/* TODO: Implement actual TLS handshake protocol
* This will include:
- * 1. Send Host Finish TLS message
- * 2. Master secret and traffic key derivation
+ * 1. Master secret and traffic key derivation
*/
free_skb:
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 08/11] Bluetooth: btnxpuart: Derive traffic keys from TLS 1.3 handshake
2026-01-13 7:47 [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Neeraj Sanjay Kale
` (6 preceding siblings ...)
2026-01-13 7:47 ` [PATCH v2 07/11] Bluetooth: btnxpuart: Add device authentication Neeraj Sanjay Kale
@ 2026-01-13 7:47 ` Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 09/11] Bluetooth: btnxpuart: Add command encryption for sensitive HCI commands Neeraj Sanjay Kale
` (3 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Neeraj Sanjay Kale @ 2026-01-13 7:47 UTC (permalink / raw)
To: marcel, luiz.dentz
Cc: amitkumar.karwar, neeraj.sanjaykale, sherry.sun, dmitrii.lebed,
linux-bluetooth, linux-kernel
This completes the TLS handshake implementation by adding master secret
derivation and traffic key generation. These traffic keys will be used
to encrypt/decrypt sensitive HCI commands, response and events.
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
---
drivers/bluetooth/btnxpuart.c | 88 +++++++++++++++++++++++++++++++++--
1 file changed, 84 insertions(+), 4 deletions(-)
diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index 9ed4cece7e42..cabed02e0964 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -206,6 +206,16 @@ enum bootloader_param_change {
changed
};
+struct nxp_tls_traffic_keys {
+ u8 h2d_secret[SHA256_DIGEST_SIZE];
+ u8 d2h_secret[SHA256_DIGEST_SIZE];
+ /* These keys below should be used for message encryption/decryption */
+ u8 h2d_iv[GCM_AES_IV_SIZE];
+ u8 h2d_key[AES_KEYSIZE_128];
+ u8 d2h_iv[GCM_AES_IV_SIZE];
+ u8 d2h_key[AES_KEYSIZE_128];
+};
+
struct btnxpuart_crypto {
struct crypto_shash *tls_handshake_hash_tfm;
struct shash_desc *tls_handshake_hash_desc;
@@ -215,8 +225,10 @@ struct btnxpuart_crypto {
u8 fw_uuid[NXP_FW_UUID_SIZE];
u8 handshake_h2_hash[SHA256_DIGEST_SIZE];
u8 handshake_secret[SHA256_DIGEST_SIZE];
+ u8 master_secret[SHA256_DIGEST_SIZE];
struct completion completion;
int decrypt_result;
+ struct nxp_tls_traffic_keys keys;
};
struct btnxpuart_dev {
@@ -416,7 +428,10 @@ union nxp_set_bd_addr_payload {
#define NXP_TLS_KEYING_IV_LABEL NXP_TLS_LABEL("iv")
#define NXP_TLS_KEYING_KEY_LABEL NXP_TLS_LABEL("key")
#define NXP_TLS_FINISHED_LABEL NXP_TLS_LABEL("finished")
+#define NXP_TLS_DERIVED_LABEL NXP_TLS_LABEL("derived")
#define NXP_TLS_HOST_HS_TS_LABEL NXP_TLS_LABEL("H HS TS")
+#define NXP_TLS_D_AP_TS_LABEL NXP_TLS_LABEL("D AP TS")
+#define NXP_TLS_H_AP_TS_LABEL NXP_TLS_LABEL("H AP TS")
enum nxp_tls_signature_algorithm {
NXP_TLS_ECDSA_SECP256R1_SHA256 = 0x0403,
@@ -2526,6 +2541,71 @@ static int nxp_host_do_finished(struct hci_dev *hdev)
return ret;
}
+static void nxp_handshake_derive_master_secret(u8 master_secret[SHA256_DIGEST_SIZE],
+ u8 handshake_secret[SHA256_DIGEST_SIZE])
+{
+ u8 zeros[SHA256_DIGEST_SIZE] = {0};
+ u8 dhs[SHA256_DIGEST_SIZE];
+
+ /* Derive intermediate secret */
+ nxp_hkdf_expand_label(handshake_secret, NXP_TLS_DERIVED_LABEL,
+ NULL, 0, dhs, sizeof(dhs));
+ /* Extract master secret from derived handshake secret */
+ nxp_hkdf_sha256_extract(dhs, SHA256_DIGEST_SIZE, zeros,
+ sizeof(zeros), master_secret);
+
+ memset(dhs, 0, sizeof(dhs));
+}
+
+static int nxp_handshake_derive_traffic_keys(struct hci_dev *hdev)
+{
+ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ struct nxp_tls_traffic_keys *keys = &nxpdev->crypto.keys;
+ u8 hash[SHA256_DIGEST_SIZE];
+ int ret = 0;
+
+ ret = crypto_shash_final(nxpdev->crypto.tls_handshake_hash_desc, hash);
+ if (ret)
+ return ret;
+
+ ret = nxp_hkdf_derive_secret(nxpdev->crypto.master_secret,
+ NXP_TLS_D_AP_TS_LABEL, hash, keys->d2h_secret);
+ if (ret)
+ return ret;
+
+ ret = nxp_hkdf_expand_label(keys->d2h_secret,
+ NXP_TLS_KEYING_KEY_LABEL, NULL, 0,
+ keys->d2h_key, AES_KEYSIZE_128);
+ if (ret)
+ return ret;
+
+ ret = nxp_hkdf_expand_label(keys->d2h_secret,
+ NXP_TLS_KEYING_IV_LABEL, NULL, 0,
+ keys->d2h_iv, GCM_AES_IV_SIZE);
+ if (ret)
+ return ret;
+
+ ret = nxp_hkdf_derive_secret(nxpdev->crypto.master_secret,
+ NXP_TLS_H_AP_TS_LABEL, hash, keys->h2d_secret);
+ if (ret)
+ return ret;
+
+ ret = nxp_hkdf_expand_label(keys->h2d_secret,
+ NXP_TLS_KEYING_KEY_LABEL, NULL, 0,
+ keys->h2d_key, AES_KEYSIZE_128);
+ if (ret)
+ return ret;
+
+ ret = nxp_hkdf_expand_label(keys->h2d_secret,
+ NXP_TLS_KEYING_IV_LABEL, NULL, 0,
+ keys->h2d_iv, GCM_AES_IV_SIZE);
+ if (ret)
+ return ret;
+
+ memset(hash, 0, sizeof(hash));
+ return ret;
+}
+
static int nxp_authenticate_device(struct hci_dev *hdev)
{
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
@@ -2580,10 +2660,10 @@ static int nxp_authenticate_device(struct hci_dev *hdev)
if (ret)
goto free_skb;
- /* TODO: Implement actual TLS handshake protocol
- * This will include:
- * 1. Master secret and traffic key derivation
- */
+ nxp_handshake_derive_master_secret(nxpdev->crypto.master_secret,
+ nxpdev->crypto.handshake_secret);
+
+ nxp_handshake_derive_traffic_keys(hdev);
free_skb:
kfree_skb(skb);
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 09/11] Bluetooth: btnxpuart: Add command encryption for sensitive HCI commands
2026-01-13 7:47 [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Neeraj Sanjay Kale
` (7 preceding siblings ...)
2026-01-13 7:47 ` [PATCH v2 08/11] Bluetooth: btnxpuart: Derive traffic keys from TLS 1.3 handshake Neeraj Sanjay Kale
@ 2026-01-13 7:47 ` Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 10/11] Bluetooth: btnxpuart: Add encrypted event handling Neeraj Sanjay Kale
` (2 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Neeraj Sanjay Kale @ 2026-01-13 7:47 UTC (permalink / raw)
To: marcel, luiz.dentz
Cc: amitkumar.karwar, neeraj.sanjaykale, sherry.sun, dmitrii.lebed,
linux-bluetooth, linux-kernel
This adds support for command encryption for sensitive HCI commands when
secure interface is enabled. This commands containt sensitive data such
as Link Key in plain text over UART lines.
AES-GCM encryption is used to encrypt sensitive commands using
encryption key and IV derived from traffic keys.
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
---
v2: Fix cocci warnings. (kernel test robot)
---
drivers/bluetooth/btnxpuart.c | 81 +++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index cabed02e0964..e2be9012ef58 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -159,6 +159,7 @@
#define NXP_FW_UUID_SIZE 16
#define NXP_FW_ECDH_PUBKEY_SIZE 64
#define NXP_FW_ECDSA_PUBKEY_SIZE 65
+#define NXP_MAX_ENCRYPT_CMD_LEN 256
struct ps_data {
u8 target_ps_mode; /* ps mode to be set */
@@ -226,6 +227,7 @@ struct btnxpuart_crypto {
u8 handshake_h2_hash[SHA256_DIGEST_SIZE];
u8 handshake_secret[SHA256_DIGEST_SIZE];
u8 master_secret[SHA256_DIGEST_SIZE];
+ u64 enc_seq_no;
struct completion completion;
int decrypt_result;
struct nxp_tls_traffic_keys keys;
@@ -2682,6 +2684,71 @@ static int nxp_authenticate_device(struct hci_dev *hdev)
return ret;
}
+static void nxp_data_calc_nonce(u8 iv[GCM_AES_IV_SIZE], u64 seq_no,
+ u8 nonce[GCM_AES_IV_SIZE])
+{
+ u64 tmp;
+
+ /* XOR sequence number with IV to create unique nonce */
+ memcpy(&tmp, iv, sizeof(tmp));
+ tmp ^= seq_no;
+ memcpy(nonce, &tmp, sizeof(tmp));
+ memcpy(nonce + sizeof(tmp), iv + sizeof(tmp),
+ GCM_AES_IV_SIZE - sizeof(tmp));
+}
+
+static struct sk_buff *nxp_crypto_encrypt_cmd(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ __le16 vendor_opcode = __cpu_to_le16(HCI_NXP_SHI_ENCRYPT);
+ u8 nonce[GCM_AES_IV_SIZE];
+ u8 tag[NXP_ENC_AUTH_TAG_SIZE];
+ u8 *enc_data;
+ u8 sub_opcode = 0x10;
+ int ret;
+ u32 plen, enc_data_len;
+ struct nxp_tls_traffic_keys *keys = &nxpdev->crypto.keys;
+
+ if (skb->len > NXP_MAX_ENCRYPT_CMD_LEN) {
+ bt_dev_err(hdev, "Invalid skb->len: %d", skb->len);
+ return skb;
+ }
+
+ nxp_data_calc_nonce(keys->h2d_iv, nxpdev->crypto.enc_seq_no, nonce);
+
+ enc_data_len = skb->len;
+ enc_data = kmemdup(skb->data, skb->len, GFP_KERNEL);
+ if (!enc_data)
+ return skb;
+
+ ret = nxp_aes_gcm_encrypt(hdev, enc_data, enc_data_len, tag,
+ keys->h2d_key, nonce);
+ if (ret) {
+ kfree(enc_data);
+ return skb;
+ }
+
+ kfree_skb(skb);
+
+ plen = enc_data_len + NXP_ENC_AUTH_TAG_SIZE + 1;
+ skb = bt_skb_alloc(plen, GFP_ATOMIC);
+ if (!skb) {
+ kfree(enc_data);
+ return ERR_PTR(-ENOMEM);
+ }
+ hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
+ skb_put_data(skb, &vendor_opcode, 2);
+ skb_put_data(skb, &plen, 1);
+ skb_put_data(skb, &sub_opcode, 1);
+ skb_put_data(skb, enc_data, enc_data_len);
+ skb_put_data(skb, tag, NXP_ENC_AUTH_TAG_SIZE);
+
+ nxpdev->crypto.enc_seq_no++;
+ kfree(enc_data);
+ return skb;
+}
+
/* NXP protocol */
static int nxp_setup(struct hci_dev *hdev)
{
@@ -2885,6 +2952,20 @@ static int nxp_enqueue(struct hci_dev *hdev, struct sk_buff *skb)
goto free_skb;
}
break;
+ case HCI_OP_LINK_KEY_REPLY:
+ case HCI_OP_LE_START_ENC:
+ case HCI_OP_LE_LTK_REPLY:
+ case HCI_OP_LE_ADD_TO_RESOLV_LIST:
+ if (nxpdev->secure_interface) {
+ /* Re-alloc skb and encrypt sensitive command
+ * and payload. Command complete event
+ * won't be encrypted.
+ */
+ skb = nxp_crypto_encrypt_cmd(hdev, skb);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+ }
+ break;
default:
break;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 10/11] Bluetooth: btnxpuart: Add encrypted event handling
2026-01-13 7:47 [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Neeraj Sanjay Kale
` (8 preceding siblings ...)
2026-01-13 7:47 ` [PATCH v2 09/11] Bluetooth: btnxpuart: Add command encryption for sensitive HCI commands Neeraj Sanjay Kale
@ 2026-01-13 7:47 ` Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 11/11] Bluetooth: btnxpuart: Select crypto algorithms for secure interface Neeraj Sanjay Kale
2026-01-13 15:00 ` [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Luiz Augusto von Dentz
11 siblings, 0 replies; 23+ messages in thread
From: Neeraj Sanjay Kale @ 2026-01-13 7:47 UTC (permalink / raw)
To: marcel, luiz.dentz
Cc: amitkumar.karwar, neeraj.sanjaykale, sherry.sun, dmitrii.lebed,
linux-bluetooth, linux-kernel
This adds support for receiving and decrypting vendor events from secure
NXP chip and forwarding the decrypted sensitive HCI events to the BT
stack.
The NXP BT chip encrypts the Link Key Notification event that is usually
sent in plaintext over UART lines.
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
---
drivers/bluetooth/btnxpuart.c | 99 ++++++++++++++++++++++++++++++++++-
1 file changed, 98 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index e2be9012ef58..115f727c2572 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -228,6 +228,7 @@ struct btnxpuart_crypto {
u8 handshake_secret[SHA256_DIGEST_SIZE];
u8 master_secret[SHA256_DIGEST_SIZE];
u64 enc_seq_no;
+ u64 dec_seq_no;
struct completion completion;
int decrypt_result;
struct nxp_tls_traffic_keys keys;
@@ -2749,6 +2750,102 @@ static struct sk_buff *nxp_crypto_encrypt_cmd(struct hci_dev *hdev,
return skb;
}
+static int nxp_crypto_event(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ int ciphertext_size;
+ u8 *ciphertext;
+ u8 aes_gcm_tag[NXP_ENC_AUTH_TAG_SIZE];
+ u8 nonce[GCM_AES_IV_SIZE];
+ int ret;
+ struct sk_buff *event_skb;
+ struct nxp_tls_traffic_keys *keys = &nxpdev->crypto.keys;
+
+ if (skb->len < NXP_ENC_AUTH_TAG_SIZE) {
+ bt_dev_err(hdev, "Encrypted event too short: %d", skb->len);
+ return -EINVAL;
+ }
+ ciphertext_size = skb->len - NXP_ENC_AUTH_TAG_SIZE;
+ ciphertext = kzalloc(ciphertext_size, GFP_KERNEL);
+ if (!ciphertext)
+ return -ENOMEM;
+
+ memcpy(ciphertext, skb->data, ciphertext_size);
+ memcpy(aes_gcm_tag, skb->data + ciphertext_size, NXP_ENC_AUTH_TAG_SIZE);
+
+ nxp_data_calc_nonce(keys->d2h_iv, nxpdev->crypto.dec_seq_no, nonce);
+
+ ret = nxp_aes_gcm_decrypt(hdev, ciphertext, ciphertext_size,
+ aes_gcm_tag, keys->d2h_key, nonce);
+ if (ret) {
+ kfree(ciphertext);
+ return ret;
+ }
+
+ event_skb = bt_skb_alloc(ciphertext_size, GFP_ATOMIC);
+ if (!event_skb) {
+ kfree(ciphertext);
+ return -ENOMEM;
+ }
+
+ hci_skb_pkt_type(event_skb) = HCI_EVENT_PKT;
+ skb_put_data(event_skb, ciphertext, ciphertext_size);
+
+ nxpdev->crypto.dec_seq_no++;
+
+ kfree(ciphertext);
+
+ /* Inject Decrypted Event to upper stack */
+ return hci_recv_frame(hdev, event_skb);
+}
+
+static int nxp_process_vendor_event(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+ struct hci_event_hdr *vendor_event_hdr;
+ u8 *vendor_sub_event;
+
+ vendor_event_hdr = (struct hci_event_hdr *)skb_pull_data(skb,
+ sizeof(*vendor_event_hdr));
+ if (!vendor_event_hdr)
+ goto free_skb;
+
+ if (!vendor_event_hdr->plen)
+ goto free_skb;
+
+ vendor_sub_event = skb_pull_data(skb, 1);
+ if (!vendor_sub_event)
+ goto free_skb;
+
+ switch (*vendor_sub_event) {
+ case 0x23:
+ break; // Power Save Enable/Disable vendor response. Can be ignored.
+ case 0xe3:
+ if (nxpdev->secure_interface)
+ nxp_crypto_event(hdev, skb);
+ else
+ bt_dev_warn(hdev, "Unexpected encrypted event");
+ break;
+ default:
+ bt_dev_err(hdev, "Unknown vendor event subtype: %d", *vendor_sub_event);
+ break;
+ }
+
+free_skb:
+ kfree_skb(skb);
+ return 0;
+}
+
+static int nxp_recv_event_frame(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ u8 event = hci_event_hdr(skb)->evt;
+
+ if (event == 0xff)
+ return nxp_process_vendor_event(hdev, skb);
+ else
+ return hci_recv_frame(hdev, skb);
+}
+
/* NXP protocol */
static int nxp_setup(struct hci_dev *hdev)
{
@@ -3076,7 +3173,7 @@ static int btnxpuart_flush(struct hci_dev *hdev)
static const struct h4_recv_pkt nxp_recv_pkts[] = {
{ H4_RECV_ACL, .recv = nxp_recv_acl_pkt },
{ H4_RECV_SCO, .recv = hci_recv_frame },
- { H4_RECV_EVENT, .recv = hci_recv_frame },
+ { H4_RECV_EVENT, .recv = nxp_recv_event_frame },
{ H4_RECV_ISO, .recv = hci_recv_frame },
{ NXP_RECV_CHIP_VER_V1, .recv = nxp_recv_chip_ver_v1 },
{ NXP_RECV_FW_REQ_V1, .recv = nxp_recv_fw_req_v1 },
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 11/11] Bluetooth: btnxpuart: Select crypto algorithms for secure interface
2026-01-13 7:47 [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Neeraj Sanjay Kale
` (9 preceding siblings ...)
2026-01-13 7:47 ` [PATCH v2 10/11] Bluetooth: btnxpuart: Add encrypted event handling Neeraj Sanjay Kale
@ 2026-01-13 7:47 ` Neeraj Sanjay Kale
2026-01-13 15:00 ` [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Luiz Augusto von Dentz
11 siblings, 0 replies; 23+ messages in thread
From: Neeraj Sanjay Kale @ 2026-01-13 7:47 UTC (permalink / raw)
To: marcel, luiz.dentz
Cc: amitkumar.karwar, neeraj.sanjaykale, sherry.sun, dmitrii.lebed,
linux-bluetooth, linux-kernel
This adds crypto dependencies (ECDSA, ECDH, AES-GCM, SHA256, HMAC)
needed for TLS-based secure host interface authentication and
encryption.
Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
---
drivers/bluetooth/Kconfig | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index c5d45cf91f88..ccbd2e13977e 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -493,6 +493,13 @@ config BT_NXPUART
select BT_HCIUART_H4
select CRC32
select CRC8
+ select CRYPTO
+ select CRYPTO_ECDSA
+ select CRYPTO_ECDH
+ select CRYPTO_AES
+ select CRYPTO_GCM
+ select CRYPTO_SHA256
+ select CRYPTO_HMAC
help
NXP is serial driver required for NXP Bluetooth
devices with UART interface.
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* RE: Bluetooth: btnxpuart: Add secure interface support for NXP chipsets
2026-01-13 7:47 ` [PATCH v2 01/11] Bluetooth: btnxpuart: Add firmware metadata parsing for secure interface Neeraj Sanjay Kale
@ 2026-01-13 8:46 ` bluez.test.bot
0 siblings, 0 replies; 23+ messages in thread
From: bluez.test.bot @ 2026-01-13 8:46 UTC (permalink / raw)
To: linux-bluetooth, neeraj.sanjaykale
[-- Attachment #1: Type: text/plain, Size: 2595 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1041603
---Test result---
Test Summary:
CheckPatch PENDING 0.46 seconds
GitLint PENDING 0.29 seconds
SubjectPrefix PASS 0.91 seconds
BuildKernel PASS 25.06 seconds
CheckAllWarning PASS 27.40 seconds
CheckSparse PASS 31.77 seconds
BuildKernel32 PASS 26.42 seconds
TestRunnerSetup PASS 547.48 seconds
TestRunner_l2cap-tester PASS 28.02 seconds
TestRunner_iso-tester PASS 99.03 seconds
TestRunner_bnep-tester PASS 8.37 seconds
TestRunner_mgmt-tester FAIL 122.75 seconds
TestRunner_rfcomm-tester PASS 10.62 seconds
TestRunner_sco-tester FAIL 15.84 seconds
TestRunner_ioctl-tester PASS 10.97 seconds
TestRunner_mesh-tester FAIL 13.42 seconds
TestRunner_smp-tester PASS 10.56 seconds
TestRunner_userchan-tester PASS 8.68 seconds
IncrementalBuild PENDING 0.65 seconds
Details
##############################
Test: CheckPatch - PENDING
Desc: Run checkpatch.pl script
Output:
##############################
Test: GitLint - PENDING
Desc: Run gitlint
Output:
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 494, Passed: 489 (99.0%), Failed: 1, Not Run: 4
Failed Test Cases
Read Exp Feature - Success Failed 0.107 seconds
##############################
Test: TestRunner_sco-tester - FAIL
Desc: Run sco-tester with test-runner
Output:
WARNING: possible circular locking dependency detected
BUG: sleeping function called from invalid context at net/core/sock.c:3782
Total: 30, Passed: 30 (100.0%), Failed: 0, Not Run: 0
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0
Failed Test Cases
Mesh - Send cancel - 1 Timed out 1.853 seconds
Mesh - Send cancel - 2 Timed out 1.996 seconds
##############################
Test: IncrementalBuild - PENDING
Desc: Incremental build with the patches in the series
Output:
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets
2026-01-13 7:47 [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Neeraj Sanjay Kale
` (10 preceding siblings ...)
2026-01-13 7:47 ` [PATCH v2 11/11] Bluetooth: btnxpuart: Select crypto algorithms for secure interface Neeraj Sanjay Kale
@ 2026-01-13 15:00 ` Luiz Augusto von Dentz
2026-01-13 18:15 ` Luiz Augusto von Dentz
2026-01-14 9:10 ` Neeraj Sanjay Kale
11 siblings, 2 replies; 23+ messages in thread
From: Luiz Augusto von Dentz @ 2026-01-13 15:00 UTC (permalink / raw)
To: Neeraj Sanjay Kale
Cc: marcel, amitkumar.karwar, sherry.sun, dmitrii.lebed,
linux-bluetooth, linux-kernel
Hi,
On Tue, Jan 13, 2026 at 2:46 AM Neeraj Sanjay Kale
<neeraj.sanjaykale@nxp.com> wrote:
>
> This patch series adds secure interface support for NXP Bluetooth chipsets
> to protect against UART-based attacks on Bluetooth security keys.
>
> Problem Statement:
> ==================
> Bluetooth UART drivers are vulnerable to physical attacks where adversaries
> can monitor UART TX/RX lines to extract sensitive cryptographic material.
> As demonstrated in research [1], attackers can capture H4 packets
> containing Link Keys, LTKs, and other pairing data transmitted in plaintext
> over UART.
>
> Once an attacker obtains these keys from UART traffic, they can:
> - Decrypt all Bluetooth communication for paired devices
> - Impersonate trusted devices
> - Perform man-in-the-middle attacks
>
> This vulnerability affects any Bluetooth implementation using UART
> transport, making physical access to UART lines equivalent to compromising
> all paired device security.
>
> Solution:
> =========
> Implement a TLS 1.3-inspired secure interface that:
> - Authenticates the chipset using ECDSA signature verification
> - Establishes shared encryption keys via ECDH key exchange
> - Encrypts sensitive HCI commands (Link Key Reply, LTK Reply, etc.) using
> AES-GCM
> - Decrypts encrypted vendor events from the chipset
>
> This ensures that even with full UART access, attackers cannot extract
> usable cryptographic keys from the communication channel.
>
> Implementation Overview:
> ========================
> The solution is implemented in 11 incremental patches:
>
> 1-2: Add firmware metadata parsing and version detection
> 3-4: Establish secure interface framework and crypto setup
> 5-7: Implement TLS handshake (Host Hello, Device Hello, authentication)
> 8: Derive application traffic keys for encryption/decryption
> 9-10: Add command encryption and event decryption support
> 11: Add required crypto algorithm dependencies
>
> The implementation automatically detects secure interface capability via
> firmware version strings and enables encryption only when needed. Legacy
> chipsets continue to work without modification.
>
> Security Properties:
> ===================
> - Chipset authentication prevents rogue device substitution
> - Forward secrecy through ephemeral ECDH key exchange
> - Authenticated encryption (AES-GCM) prevents tampering
> - Per-session keys limit exposure from key compromise
>
> Testing:
> ========
> Tested on AW693 chipsets with secure firmware. Verified that:
> - Authentication handshake completes successfully
> - Sensitive commands are encrypted before transmission
> - Encrypted events are properly decrypted
> - UART monitoring shows only encrypted payloads for sensitive operations
> - Legacy chipsets remain unaffected
>
> [1] "BLAP: Bluetooth Low Energy Attacks on Pairing" - DSN 2022
> https://netsec.ethz.ch/publications/papers/dsn22_blap.pdf
Ok, I start reading the document above but it says the problem is with
HCI itself though:
'We first present a link key extraction attack that exploits
the security flaw in the HCI dump, which records all data
passed through the HCI interface in a log file, including
link keys.'
It does say that it is passed to a log file though, maybe the
permission of the file is the problem then, either way this would be
UART expecific. We do require NET_ADMIN (aka. root) for accessing HCI
though, both for monitoring or generating HCI traffic (e.g.
HCI_USER_CHANNEL), so I don't believe these claims are valid with
respect to Linux since for collecting the logs with the likes of btmon
that will require root access, that said perhaps the -w option shall
limit the permission of the file to root only as well, in any case it
is not like btmon can be run by an attacker without root access, so it
beats me how Linux could be considered vulnerable here.
>
>
>
> Neeraj Sanjay Kale (11):
> Bluetooth: btnxpuart: Add firmware metadata parsing for secure
> interface
> Bluetooth: btnxpuart: Print FW version and enable chip specific
> features
> Bluetooth: btnxpuart: Add secure interface TLS authentication support
> Bluetooth: btnxpuart: Implement TLS authentication crypto framework
> Bluetooth: btnxpuart: Add TLS host hello handshake implementation
> Bluetooth: btnxpuart: Add TLS device hello processing
> Bluetooth: btnxpuart: Add device authentication
> Bluetooth: btnxpuart: Derive traffic keys from TLS 1.3 handshake
> Bluetooth: btnxpuart: Add command encryption for sensitive HCI
> commands
> Bluetooth: btnxpuart: Add encrypted event handling
> Bluetooth: btnxpuart: Select crypto algorithms for secure interface
>
> drivers/bluetooth/Kconfig | 7 +
> drivers/bluetooth/btnxpuart.c | 1442 ++++++++++++++++++++++++++++++++-
> 2 files changed, 1440 insertions(+), 9 deletions(-)
>
> --
> 2.43.0
>
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets
2026-01-13 15:00 ` [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Luiz Augusto von Dentz
@ 2026-01-13 18:15 ` Luiz Augusto von Dentz
2026-01-14 9:19 ` [EXT] " Neeraj Sanjay Kale
2026-01-14 9:10 ` Neeraj Sanjay Kale
1 sibling, 1 reply; 23+ messages in thread
From: Luiz Augusto von Dentz @ 2026-01-13 18:15 UTC (permalink / raw)
To: Neeraj Sanjay Kale
Cc: marcel, amitkumar.karwar, sherry.sun, dmitrii.lebed,
linux-bluetooth, linux-kernel
Hi,
On Tue, Jan 13, 2026 at 10:00 AM Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
>
> Hi,
>
> On Tue, Jan 13, 2026 at 2:46 AM Neeraj Sanjay Kale
> <neeraj.sanjaykale@nxp.com> wrote:
> >
> > This patch series adds secure interface support for NXP Bluetooth chipsets
> > to protect against UART-based attacks on Bluetooth security keys.
> >
> > Problem Statement:
> > ==================
> > Bluetooth UART drivers are vulnerable to physical attacks where adversaries
> > can monitor UART TX/RX lines to extract sensitive cryptographic material.
> > As demonstrated in research [1], attackers can capture H4 packets
> > containing Link Keys, LTKs, and other pairing data transmitted in plaintext
> > over UART.
> >
> > Once an attacker obtains these keys from UART traffic, they can:
> > - Decrypt all Bluetooth communication for paired devices
> > - Impersonate trusted devices
> > - Perform man-in-the-middle attacks
> >
> > This vulnerability affects any Bluetooth implementation using UART
> > transport, making physical access to UART lines equivalent to compromising
> > all paired device security.
> >
> > Solution:
> > =========
> > Implement a TLS 1.3-inspired secure interface that:
> > - Authenticates the chipset using ECDSA signature verification
> > - Establishes shared encryption keys via ECDH key exchange
> > - Encrypts sensitive HCI commands (Link Key Reply, LTK Reply, etc.) using
> > AES-GCM
> > - Decrypts encrypted vendor events from the chipset
> >
> > This ensures that even with full UART access, attackers cannot extract
> > usable cryptographic keys from the communication channel.
> >
> > Implementation Overview:
> > ========================
> > The solution is implemented in 11 incremental patches:
> >
> > 1-2: Add firmware metadata parsing and version detection
> > 3-4: Establish secure interface framework and crypto setup
> > 5-7: Implement TLS handshake (Host Hello, Device Hello, authentication)
> > 8: Derive application traffic keys for encryption/decryption
> > 9-10: Add command encryption and event decryption support
> > 11: Add required crypto algorithm dependencies
> >
> > The implementation automatically detects secure interface capability via
> > firmware version strings and enables encryption only when needed. Legacy
> > chipsets continue to work without modification.
> >
> > Security Properties:
> > ===================
> > - Chipset authentication prevents rogue device substitution
> > - Forward secrecy through ephemeral ECDH key exchange
> > - Authenticated encryption (AES-GCM) prevents tampering
> > - Per-session keys limit exposure from key compromise
> >
> > Testing:
> > ========
> > Tested on AW693 chipsets with secure firmware. Verified that:
> > - Authentication handshake completes successfully
> > - Sensitive commands are encrypted before transmission
> > - Encrypted events are properly decrypted
> > - UART monitoring shows only encrypted payloads for sensitive operations
> > - Legacy chipsets remain unaffected
> >
> > [1] "BLAP: Bluetooth Low Energy Attacks on Pairing" - DSN 2022
> > https://netsec.ethz.ch/publications/papers/dsn22_blap.pdf
>
> Ok, I start reading the document above but it says the problem is with
> HCI itself though:
>
> 'We first present a link key extraction attack that exploits
> the security flaw in the HCI dump, which records all data
> passed through the HCI interface in a log file, including
> link keys.'
>
> It does say that it is passed to a log file though, maybe the
> permission of the file is the problem then, either way this would be
> UART expecific. We do require NET_ADMIN (aka. root) for accessing HCI
> though, both for monitoring or generating HCI traffic (e.g.
> HCI_USER_CHANNEL), so I don't believe these claims are valid with
> respect to Linux since for collecting the logs with the likes of btmon
> that will require root access, that said perhaps the -w option shall
> limit the permission of the file to root only as well, in any case it
> is not like btmon can be run by an attacker without root access, so it
> beats me how Linux could be considered vulnerable here.
Just reading thru it says:
'Moreover, it is also straightforward to implement the
link key extraction attack in Linux OS by leveraging both USB
sniff and HCI dump log, because there are USB sniffing solu-
tions as well as the bluez-hcidump package. However, running
USB sniffing and bluez-hcidump, and accessing the bonding
information file in Linux require the superuser privilege. Thus,
the practicality of link key extraction in Linux depends on the
attacker’s affordable privilege.'
Anything is trivial if you have superuser privilege, so I don't think
we should consider Linux vulnerable just because someone thinks having
root access is something trivial to get, that in itself is the real
vulnerability if you ask me.
>
> >
> >
> >
> > Neeraj Sanjay Kale (11):
> > Bluetooth: btnxpuart: Add firmware metadata parsing for secure
> > interface
> > Bluetooth: btnxpuart: Print FW version and enable chip specific
> > features
> > Bluetooth: btnxpuart: Add secure interface TLS authentication support
> > Bluetooth: btnxpuart: Implement TLS authentication crypto framework
> > Bluetooth: btnxpuart: Add TLS host hello handshake implementation
> > Bluetooth: btnxpuart: Add TLS device hello processing
> > Bluetooth: btnxpuart: Add device authentication
> > Bluetooth: btnxpuart: Derive traffic keys from TLS 1.3 handshake
> > Bluetooth: btnxpuart: Add command encryption for sensitive HCI
> > commands
> > Bluetooth: btnxpuart: Add encrypted event handling
> > Bluetooth: btnxpuart: Select crypto algorithms for secure interface
> >
> > drivers/bluetooth/Kconfig | 7 +
> > drivers/bluetooth/btnxpuart.c | 1442 ++++++++++++++++++++++++++++++++-
> > 2 files changed, 1440 insertions(+), 9 deletions(-)
> >
> > --
> > 2.43.0
> >
>
>
> --
> Luiz Augusto von Dentz
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets
2026-01-13 15:00 ` [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Luiz Augusto von Dentz
2026-01-13 18:15 ` Luiz Augusto von Dentz
@ 2026-01-14 9:10 ` Neeraj Sanjay Kale
2026-01-21 19:21 ` Marcel Holtmann
1 sibling, 1 reply; 23+ messages in thread
From: Neeraj Sanjay Kale @ 2026-01-14 9:10 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: marcel@holtmann.org, Amitkumar Karwar, Sherry Sun, Dmitrii Lebed,
linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org,
Ethan Lo
Hi Luiz,
Thank you for taking a look at this patch series.
> On Tue, Jan 13, 2026 at 2:46 AM Neeraj Sanjay Kale
> <neeraj.sanjaykale@nxp.com> wrote:
> >
> > This patch series adds secure interface support for NXP Bluetooth
> > chipsets to protect against UART-based attacks on Bluetooth security keys.
> >
> > Problem Statement:
> > ==================
> > Bluetooth UART drivers are vulnerable to physical attacks where
> > adversaries can monitor UART TX/RX lines to extract sensitive cryptographic
> material.
> > As demonstrated in research [1], attackers can capture H4 packets
> > containing Link Keys, LTKs, and other pairing data transmitted in
> > plaintext over UART.
> >
> > Once an attacker obtains these keys from UART traffic, they can:
> > - Decrypt all Bluetooth communication for paired devices
> > - Impersonate trusted devices
> > - Perform man-in-the-middle attacks
> >
> > This vulnerability affects any Bluetooth implementation using UART
> > transport, making physical access to UART lines equivalent to
> > compromising all paired device security.
> >
> > Solution:
> > =========
> > Implement a TLS 1.3-inspired secure interface that:
> > - Authenticates the chipset using ECDSA signature verification
> > - Establishes shared encryption keys via ECDH key exchange
> > - Encrypts sensitive HCI commands (Link Key Reply, LTK Reply, etc.) using
> > AES-GCM
> > - Decrypts encrypted vendor events from the chipset
> >
> > This ensures that even with full UART access, attackers cannot extract
> > usable cryptographic keys from the communication channel.
> >
> > Implementation Overview:
> > ========================
> > The solution is implemented in 11 incremental patches:
> >
> > 1-2: Add firmware metadata parsing and version detection
> > 3-4: Establish secure interface framework and crypto setup
> > 5-7: Implement TLS handshake (Host Hello, Device Hello, authentication)
> > 8: Derive application traffic keys for encryption/decryption
> > 9-10: Add command encryption and event decryption support
> > 11: Add required crypto algorithm dependencies
> >
> > The implementation automatically detects secure interface capability
> > via firmware version strings and enables encryption only when needed.
> > Legacy chipsets continue to work without modification.
> >
> > Security Properties:
> > ===================
> > - Chipset authentication prevents rogue device substitution
> > - Forward secrecy through ephemeral ECDH key exchange
> > - Authenticated encryption (AES-GCM) prevents tampering
> > - Per-session keys limit exposure from key compromise
> >
> > Testing:
> > ========
> > Tested on AW693 chipsets with secure firmware. Verified that:
> > - Authentication handshake completes successfully
> > - Sensitive commands are encrypted before transmission
> > - Encrypted events are properly decrypted
> > - UART monitoring shows only encrypted payloads for sensitive
> > operations
> > - Legacy chipsets remain unaffected
> >
> > [1] "BLAP: Bluetooth Low Energy Attacks on Pairing" - DSN 2022
> >
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fnets
> >
> ec.ethz.ch%2Fpublications%2Fpapers%2Fdsn22_blap.pdf&data=05%7C02%7
> Cnee
> >
> raj.sanjaykale%40nxp.com%7C7e6471862d5d4d6b86bc08de52b47c29%7C686
> ea1d3
> >
> bc2b4c6fa92cd99c5c301635%7C0%7C0%7C639039132284844210%7CUnknow
> n%7CTWFp
> >
> bGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4z
> MiIsIk
> >
> FOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=HV0OjNPoq%2B
> P%2B07YW
> > WCtrrGUlmxWBamNWMwfrbkan7yc%3D&reserved=0
>
> Ok, I start reading the document above but it says the problem is with HCI
> itself though:
>
> 'We first present a link key extraction attack that exploits the security flaw in
> the HCI dump, which records all data passed through the HCI interface in a log
> file, including link keys.'
>
> It does say that it is passed to a log file though, maybe the permission of the
> file is the problem then, either way this would be UART expecific. We do
> require NET_ADMIN (aka. root) for accessing HCI though, both for monitoring
> or generating HCI traffic (e.g.
> HCI_USER_CHANNEL), so I don't believe these claims are valid with respect to
> Linux since for collecting the logs with the likes of btmon that will require root
> access, that said perhaps the -w option shall limit the permission of the file to
> root only as well, in any case it is not like btmon can be run by an attacker
> without root access, so it beats me how Linux could be considered vulnerable
> here.
The DSN’22 BLAP paper shows link‑key extraction from HCI dump logs (e.g., btmon)—a logging issue, not a Linux privilege bypass. Our threat model is different: physical sniffing of the H4 UART lines (common on M.2 Key‑E and bring‑up boards) where the link‑key exchange transits in plaintext. This series addresses that risk by encrypting the link‑key request/response (and related vendor events) over UART, so keys aren’t recoverable even with full wire access.
This is intended to help meet EU RED 2022/30 privacy/network‑protection essentials (Art. 3(3)(e),(d)) via “communicate securely” controls (ETSI EN 303 645) and aligns with the CRA Annex I requirement to protect confidentiality of transmitted data.
With the changes in this patch series (auth handshake + AEAD protection for sensitive HCI commands/events on UART), the AW693x/AW692x/IW693x/IW623x chips are SESIP3‑certified with Physical Attacker Resistance, TrustCB ID SESIP‑2500101‑01 (DEKRA; issued 2025‑12‑17, valid until 2027‑12‑16).
The certificate is available at: https://trustcb.com/iot/sesip/sesip-certificates/ with Cert. ID: SESIP-2500101-01
Please let me know if you have any further concerns.
Thanks,
Neeraj
^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [EXT] Re: [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets
2026-01-13 18:15 ` Luiz Augusto von Dentz
@ 2026-01-14 9:19 ` Neeraj Sanjay Kale
2026-01-14 14:45 ` Luiz Augusto von Dentz
0 siblings, 1 reply; 23+ messages in thread
From: Neeraj Sanjay Kale @ 2026-01-14 9:19 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: marcel@holtmann.org, Amitkumar Karwar, Sherry Sun, Dmitrii Lebed,
linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org,
Ethan Lo
Hi Luiz,
> > On Tue, Jan 13, 2026 at 2:46 AM Neeraj Sanjay Kale
> > <neeraj.sanjaykale@nxp.com> wrote:
> > >
> > > This patch series adds secure interface support for NXP Bluetooth
> > > chipsets to protect against UART-based attacks on Bluetooth security keys.
> > >
> > > Problem Statement:
> > > ==================
> > > Bluetooth UART drivers are vulnerable to physical attacks where
> > > adversaries can monitor UART TX/RX lines to extract sensitive
> cryptographic material.
> > > As demonstrated in research [1], attackers can capture H4 packets
> > > containing Link Keys, LTKs, and other pairing data transmitted in
> > > plaintext over UART.
> > >
> > > Once an attacker obtains these keys from UART traffic, they can:
> > > - Decrypt all Bluetooth communication for paired devices
> > > - Impersonate trusted devices
> > > - Perform man-in-the-middle attacks
> > >
> > > This vulnerability affects any Bluetooth implementation using UART
> > > transport, making physical access to UART lines equivalent to
> > > compromising all paired device security.
> > >
> > > Solution:
> > > =========
> > > Implement a TLS 1.3-inspired secure interface that:
> > > - Authenticates the chipset using ECDSA signature verification
> > > - Establishes shared encryption keys via ECDH key exchange
> > > - Encrypts sensitive HCI commands (Link Key Reply, LTK Reply, etc.) using
> > > AES-GCM
> > > - Decrypts encrypted vendor events from the chipset
> > >
> > > This ensures that even with full UART access, attackers cannot
> > > extract usable cryptographic keys from the communication channel.
> > >
> > > Implementation Overview:
> > > ========================
> > > The solution is implemented in 11 incremental patches:
> > >
> > > 1-2: Add firmware metadata parsing and version detection
> > > 3-4: Establish secure interface framework and crypto setup
> > > 5-7: Implement TLS handshake (Host Hello, Device Hello, authentication)
> > > 8: Derive application traffic keys for encryption/decryption
> > > 9-10: Add command encryption and event decryption support
> > > 11: Add required crypto algorithm dependencies
> > >
> > > The implementation automatically detects secure interface capability
> > > via firmware version strings and enables encryption only when
> > > needed. Legacy chipsets continue to work without modification.
> > >
> > > Security Properties:
> > > ===================
> > > - Chipset authentication prevents rogue device substitution
> > > - Forward secrecy through ephemeral ECDH key exchange
> > > - Authenticated encryption (AES-GCM) prevents tampering
> > > - Per-session keys limit exposure from key compromise
> > >
> > > Testing:
> > > ========
> > > Tested on AW693 chipsets with secure firmware. Verified that:
> > > - Authentication handshake completes successfully
> > > - Sensitive commands are encrypted before transmission
> > > - Encrypted events are properly decrypted
> > > - UART monitoring shows only encrypted payloads for sensitive
> > > operations
> > > - Legacy chipsets remain unaffected
> > >
> > > [1] "BLAP: Bluetooth Low Energy Attacks on Pairing" - DSN 2022
> > >
> > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fne
> > >
> tsec.ethz.ch%2Fpublications%2Fpapers%2Fdsn22_blap.pdf&data=05%7C02%
> 7
> > >
> Cneeraj.sanjaykale%40nxp.com%7C0e6161848dee43987e5a08de52cfc89c%7
> C68
> > >
> 6ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C639039249553069390%7C
> Unknow
> > >
> n%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIl
> AiOiJX
> > >
> aW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=j%2
> FQoD6
> > > BOhlNZQxaq4%2FEgfZaZMKNqNTwc5wgjWV7lQNc%3D&reserved=0
> >
> > Ok, I start reading the document above but it says the problem is with
> > HCI itself though:
> >
> > 'We first present a link key extraction attack that exploits the
> > security flaw in the HCI dump, which records all data passed through
> > the HCI interface in a log file, including link keys.'
> >
> > It does say that it is passed to a log file though, maybe the
> > permission of the file is the problem then, either way this would be
> > UART expecific. We do require NET_ADMIN (aka. root) for accessing HCI
> > though, both for monitoring or generating HCI traffic (e.g.
> > HCI_USER_CHANNEL), so I don't believe these claims are valid with
> > respect to Linux since for collecting the logs with the likes of btmon
> > that will require root access, that said perhaps the -w option shall
> > limit the permission of the file to root only as well, in any case it
> > is not like btmon can be run by an attacker without root access, so it
> > beats me how Linux could be considered vulnerable here.
>
> Just reading thru it says:
>
> 'Moreover, it is also straightforward to implement the link key extraction
> attack in Linux OS by leveraging both USB sniff and HCI dump log, because
> there are USB sniffing solu- tions as well as the bluez-hcidump package.
> However, running USB sniffing and bluez-hcidump, and accessing the bonding
> information file in Linux require the superuser privilege. Thus, the practicality
> of link key extraction in Linux depends on the attacker’s affordable privilege.'
>
> Anything is trivial if you have superuser privilege, so I don't think we should
> consider Linux vulnerable just because someone thinks having root access is
> something trivial to get, that in itself is the real vulnerability if you ask me.
Agree — the BLAP attack’s Linux path requires superuser for USB/HCI logging, so we’re not claiming an unprivileged Linux issue. Our series targets a different, OS‑independent risk: "physical sniffing of plaintext link‑key exchanges" on H4 UART (common on M.2 Key‑E bring‑up paths), which an attacker can tap without host permissions — hence we encrypt those HCI messages. The use of stolen keys to decrypt on‑air traffic is described in the BLAP; we’re removing the key‑extraction vector from the UART bus.
Thanks,
Neeraj
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [EXT] Re: [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets
2026-01-14 9:19 ` [EXT] " Neeraj Sanjay Kale
@ 2026-01-14 14:45 ` Luiz Augusto von Dentz
2026-01-16 9:49 ` Neeraj Sanjay Kale
0 siblings, 1 reply; 23+ messages in thread
From: Luiz Augusto von Dentz @ 2026-01-14 14:45 UTC (permalink / raw)
To: Neeraj Sanjay Kale
Cc: marcel@holtmann.org, Amitkumar Karwar, Sherry Sun, Dmitrii Lebed,
linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org,
Ethan Lo
Hi Neeraj,
On Wed, Jan 14, 2026 at 4:19 AM Neeraj Sanjay Kale
<neeraj.sanjaykale@nxp.com> wrote:
>
> Hi Luiz,
>
> > > On Tue, Jan 13, 2026 at 2:46 AM Neeraj Sanjay Kale
> > > <neeraj.sanjaykale@nxp.com> wrote:
> > > >
> > > > This patch series adds secure interface support for NXP Bluetooth
> > > > chipsets to protect against UART-based attacks on Bluetooth security keys.
> > > >
> > > > Problem Statement:
> > > > ==================
> > > > Bluetooth UART drivers are vulnerable to physical attacks where
> > > > adversaries can monitor UART TX/RX lines to extract sensitive
> > cryptographic material.
> > > > As demonstrated in research [1], attackers can capture H4 packets
> > > > containing Link Keys, LTKs, and other pairing data transmitted in
> > > > plaintext over UART.
> > > >
> > > > Once an attacker obtains these keys from UART traffic, they can:
> > > > - Decrypt all Bluetooth communication for paired devices
> > > > - Impersonate trusted devices
> > > > - Perform man-in-the-middle attacks
> > > >
> > > > This vulnerability affects any Bluetooth implementation using UART
> > > > transport, making physical access to UART lines equivalent to
> > > > compromising all paired device security.
> > > >
> > > > Solution:
> > > > =========
> > > > Implement a TLS 1.3-inspired secure interface that:
> > > > - Authenticates the chipset using ECDSA signature verification
> > > > - Establishes shared encryption keys via ECDH key exchange
> > > > - Encrypts sensitive HCI commands (Link Key Reply, LTK Reply, etc.) using
> > > > AES-GCM
> > > > - Decrypts encrypted vendor events from the chipset
> > > >
> > > > This ensures that even with full UART access, attackers cannot
> > > > extract usable cryptographic keys from the communication channel.
> > > >
> > > > Implementation Overview:
> > > > ========================
> > > > The solution is implemented in 11 incremental patches:
> > > >
> > > > 1-2: Add firmware metadata parsing and version detection
> > > > 3-4: Establish secure interface framework and crypto setup
> > > > 5-7: Implement TLS handshake (Host Hello, Device Hello, authentication)
> > > > 8: Derive application traffic keys for encryption/decryption
> > > > 9-10: Add command encryption and event decryption support
> > > > 11: Add required crypto algorithm dependencies
> > > >
> > > > The implementation automatically detects secure interface capability
> > > > via firmware version strings and enables encryption only when
> > > > needed. Legacy chipsets continue to work without modification.
> > > >
> > > > Security Properties:
> > > > ===================
> > > > - Chipset authentication prevents rogue device substitution
> > > > - Forward secrecy through ephemeral ECDH key exchange
> > > > - Authenticated encryption (AES-GCM) prevents tampering
> > > > - Per-session keys limit exposure from key compromise
> > > >
> > > > Testing:
> > > > ========
> > > > Tested on AW693 chipsets with secure firmware. Verified that:
> > > > - Authentication handshake completes successfully
> > > > - Sensitive commands are encrypted before transmission
> > > > - Encrypted events are properly decrypted
> > > > - UART monitoring shows only encrypted payloads for sensitive
> > > > operations
> > > > - Legacy chipsets remain unaffected
> > > >
> > > > [1] "BLAP: Bluetooth Low Energy Attacks on Pairing" - DSN 2022
> > > >
> > > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fne
> > > >
> > tsec.ethz.ch%2Fpublications%2Fpapers%2Fdsn22_blap.pdf&data=05%7C02%
> > 7
> > > >
> > Cneeraj.sanjaykale%40nxp.com%7C0e6161848dee43987e5a08de52cfc89c%7
> > C68
> > > >
> > 6ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C639039249553069390%7C
> > Unknow
> > > >
> > n%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIl
> > AiOiJX
> > > >
> > aW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=j%2
> > FQoD6
> > > > BOhlNZQxaq4%2FEgfZaZMKNqNTwc5wgjWV7lQNc%3D&reserved=0
> > >
> > > Ok, I start reading the document above but it says the problem is with
> > > HCI itself though:
> > >
> > > 'We first present a link key extraction attack that exploits the
> > > security flaw in the HCI dump, which records all data passed through
> > > the HCI interface in a log file, including link keys.'
> > >
> > > It does say that it is passed to a log file though, maybe the
> > > permission of the file is the problem then, either way this would be
> > > UART expecific. We do require NET_ADMIN (aka. root) for accessing HCI
> > > though, both for monitoring or generating HCI traffic (e.g.
> > > HCI_USER_CHANNEL), so I don't believe these claims are valid with
> > > respect to Linux since for collecting the logs with the likes of btmon
> > > that will require root access, that said perhaps the -w option shall
> > > limit the permission of the file to root only as well, in any case it
> > > is not like btmon can be run by an attacker without root access, so it
> > > beats me how Linux could be considered vulnerable here.
> >
> > Just reading thru it says:
> >
> > 'Moreover, it is also straightforward to implement the link key extraction
> > attack in Linux OS by leveraging both USB sniff and HCI dump log, because
> > there are USB sniffing solu- tions as well as the bluez-hcidump package.
> > However, running USB sniffing and bluez-hcidump, and accessing the bonding
> > information file in Linux require the superuser privilege. Thus, the practicality
> > of link key extraction in Linux depends on the attacker’s affordable privilege.'
> >
> > Anything is trivial if you have superuser privilege, so I don't think we should
> > consider Linux vulnerable just because someone thinks having root access is
> > something trivial to get, that in itself is the real vulnerability if you ask me.
>
> Agree — the BLAP attack’s Linux path requires superuser for USB/HCI logging, so we’re not claiming an unprivileged Linux issue. Our series targets a different, OS‑independent risk: "physical sniffing of plaintext link‑key exchanges" on H4 UART (common on M.2 Key‑E bring‑up paths), which an attacker can tap without host permissions — hence we encrypt those HCI messages. The use of stolen keys to decrypt on‑air traffic is described in the BLAP; we’re removing the key‑extraction vector from the UART bus.
Alright, but you shouldn't have mentioned BLAP, what you describing is
physical sniffing/wire tapping, BLAP is about accessing the HCI logs
which doesn't really apply to the former, so instead of using BLAP as
example would simply just mentioned the EU/ETSI requirements and SESIP
certification.
> Thanks,
> Neeraj
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets
2026-01-14 14:45 ` Luiz Augusto von Dentz
@ 2026-01-16 9:49 ` Neeraj Sanjay Kale
0 siblings, 0 replies; 23+ messages in thread
From: Neeraj Sanjay Kale @ 2026-01-16 9:49 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: marcel@holtmann.org, Amitkumar Karwar, Sherry Sun, Dmitrii Lebed,
linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org,
Ethan Lo
Hi Luiz,
> > > > On Tue, Jan 13, 2026 at 2:46 AM Neeraj Sanjay Kale
> > > > <neeraj.sanjaykale@nxp.com> wrote:
> > > > >
> > > > > This patch series adds secure interface support for NXP
> > > > > Bluetooth chipsets to protect against UART-based attacks on Bluetooth
> security keys.
> > > > >
> > > > > Problem Statement:
> > > > > ==================
> > > > > Bluetooth UART drivers are vulnerable to physical attacks where
> > > > > adversaries can monitor UART TX/RX lines to extract sensitive
> > > cryptographic material.
> > > > > As demonstrated in research [1], attackers can capture H4
> > > > > packets containing Link Keys, LTKs, and other pairing data
> > > > > transmitted in plaintext over UART.
> > > > >
> > > > > Once an attacker obtains these keys from UART traffic, they can:
> > > > > - Decrypt all Bluetooth communication for paired devices
> > > > > - Impersonate trusted devices
> > > > > - Perform man-in-the-middle attacks
> > > > >
> > > > > This vulnerability affects any Bluetooth implementation using
> > > > > UART transport, making physical access to UART lines equivalent
> > > > > to compromising all paired device security.
> > > > >
> > > > > Solution:
> > > > > =========
> > > > > Implement a TLS 1.3-inspired secure interface that:
> > > > > - Authenticates the chipset using ECDSA signature verification
> > > > > - Establishes shared encryption keys via ECDH key exchange
> > > > > - Encrypts sensitive HCI commands (Link Key Reply, LTK Reply, etc.)
> using
> > > > > AES-GCM
> > > > > - Decrypts encrypted vendor events from the chipset
> > > > >
> > > > > This ensures that even with full UART access, attackers cannot
> > > > > extract usable cryptographic keys from the communication channel.
> > > > >
> > > > > Implementation Overview:
> > > > > ========================
> > > > > The solution is implemented in 11 incremental patches:
> > > > >
> > > > > 1-2: Add firmware metadata parsing and version detection
> > > > > 3-4: Establish secure interface framework and crypto setup
> > > > > 5-7: Implement TLS handshake (Host Hello, Device Hello,
> authentication)
> > > > > 8: Derive application traffic keys for encryption/decryption
> > > > > 9-10: Add command encryption and event decryption support
> > > > > 11: Add required crypto algorithm dependencies
> > > > >
> > > > > The implementation automatically detects secure interface
> > > > > capability via firmware version strings and enables encryption
> > > > > only when needed. Legacy chipsets continue to work without
> modification.
> > > > >
> > > > > Security Properties:
> > > > > ===================
> > > > > - Chipset authentication prevents rogue device substitution
> > > > > - Forward secrecy through ephemeral ECDH key exchange
> > > > > - Authenticated encryption (AES-GCM) prevents tampering
> > > > > - Per-session keys limit exposure from key compromise
> > > > >
> > > > > Testing:
> > > > > ========
> > > > > Tested on AW693 chipsets with secure firmware. Verified that:
> > > > > - Authentication handshake completes successfully
> > > > > - Sensitive commands are encrypted before transmission
> > > > > - Encrypted events are properly decrypted
> > > > > - UART monitoring shows only encrypted payloads for sensitive
> > > > > operations
> > > > > - Legacy chipsets remain unaffected
> > > > >
> > > > > [1] "BLAP: Bluetooth Low Energy Attacks on Pairing" - DSN 2022
> > > > >
> > > > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%
> > > > >
> 2Fne%2F&data=05%7C02%7Cneeraj.sanjaykale%40nxp.com%7C390bb750d15
> > > > >
> a4644c34308de537b8b5c%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C
> 0
> > > > > %7C639039987267659582%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0
> eU1hcGkiOn
> > > > >
> RydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIj
> > > > >
> oyfQ%3D%3D%7C0%7C%7C%7C&sdata=rO%2FfOGzdeKteEkh796TfRlQ%2FdU
> oDgS
> > > > > INTP2K6qIBNY0%3D&reserved=0
> > > > >
> > >
> tsec.ethz.ch%2Fpublications%2Fpapers%2Fdsn22_blap.pdf&data=05%7C02%
> > > 7
> > > > >
> > >
> Cneeraj.sanjaykale%40nxp.com%7C0e6161848dee43987e5a08de52cfc89c%7
> > > C68
> > > > >
> > >
> 6ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C639039249553069390%7C
> > > Unknow
> > > > >
> > >
> n%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIl
> > > AiOiJX
> > > > >
> > >
> aW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=j%2
> > > FQoD6
> > > > > BOhlNZQxaq4%2FEgfZaZMKNqNTwc5wgjWV7lQNc%3D&reserved=0
> > > >
> > > > Ok, I start reading the document above but it says the problem is
> > > > with HCI itself though:
> > > >
> > > > 'We first present a link key extraction attack that exploits the
> > > > security flaw in the HCI dump, which records all data passed
> > > > through the HCI interface in a log file, including link keys.'
> > > >
> > > > It does say that it is passed to a log file though, maybe the
> > > > permission of the file is the problem then, either way this would
> > > > be UART expecific. We do require NET_ADMIN (aka. root) for
> > > > accessing HCI though, both for monitoring or generating HCI traffic (e.g.
> > > > HCI_USER_CHANNEL), so I don't believe these claims are valid with
> > > > respect to Linux since for collecting the logs with the likes of
> > > > btmon that will require root access, that said perhaps the -w
> > > > option shall limit the permission of the file to root only as
> > > > well, in any case it is not like btmon can be run by an attacker
> > > > without root access, so it beats me how Linux could be considered
> vulnerable here.
> > >
> > > Just reading thru it says:
> > >
> > > 'Moreover, it is also straightforward to implement the link key
> > > extraction attack in Linux OS by leveraging both USB sniff and HCI
> > > dump log, because there are USB sniffing solu- tions as well as the bluez-
> hcidump package.
> > > However, running USB sniffing and bluez-hcidump, and accessing the
> > > bonding information file in Linux require the superuser privilege.
> > > Thus, the practicality of link key extraction in Linux depends on the
> attacker’s affordable privilege.'
> > >
> > > Anything is trivial if you have superuser privilege, so I don't
> > > think we should consider Linux vulnerable just because someone
> > > thinks having root access is something trivial to get, that in itself is the real
> vulnerability if you ask me.
> >
> > Agree — the BLAP attack’s Linux path requires superuser for USB/HCI
> logging, so we’re not claiming an unprivileged Linux issue. Our series targets a
> different, OS‑independent risk: "physical sniffing of plaintext link‑key
> exchanges" on H4 UART (common on M.2 Key‑E bring‑up paths), which an
> attacker can tap without host permissions — hence we encrypt those HCI
> messages. The use of stolen keys to decrypt on‑air traffic is described in the
> BLAP; we’re removing the key‑extraction vector from the UART bus.
>
> Alright, but you shouldn't have mentioned BLAP, what you describing is
> physical sniffing/wire tapping, BLAP is about accessing the HCI logs which
> doesn't really apply to the former, so instead of using BLAP as example would
> simply just mentioned the EU/ETSI requirements and SESIP certification.
I will surely change the content of the cover letter in v3 patch series.
Thanks,
Neeraj
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 07/11] Bluetooth: btnxpuart: Add device authentication
2026-01-13 7:47 ` [PATCH v2 07/11] Bluetooth: btnxpuart: Add device authentication Neeraj Sanjay Kale
@ 2026-01-21 19:19 ` Marcel Holtmann
0 siblings, 0 replies; 23+ messages in thread
From: Marcel Holtmann @ 2026-01-21 19:19 UTC (permalink / raw)
To: Neeraj Sanjay Kale
Cc: luiz.dentz, amitkumar.karwar, sherry.sun, dmitrii.lebed,
linux-bluetooth, linux-kernel
Hi Neeraj,
> This implements secure device authentication during TLS 1.3-like
> handshake with ECDSA signature verification.
>
> The authentication flow:
> - Derive handshake traffic secret from ECDH shared secret
> - Decrypt device hello encrypted section using AES-GCM with traffic secret
> - Extract ECDSA public key from firmware metadata for verification
where is the storage of the private key?
And where are the firmware files? When looking this up I saw that NXP has not updated linux-firmware for a long time. The current driver references firmware files that are not contributed to linux-firmware. That is not ok.
> - Verify device handshake signature to authenticate device identity
> - Validate device finished message using calculated verify data
> - Clear handshake traffic secret after successful authentication
>
> This ensures only devices with valid private keys can complete the
> handshake.
>
> Key components added:
> - AES-GCM encrypt/decrypt with traffic secret derived keys
> - ECDSA P-256 signature verification using kernel crypto API
> - X9.62 to P1363 signature format conversion
> - TLS 1.3 finished message verification
> - Secure memory cleanup of cryptographic material
Why not just use HPKE here? Seems a lot simpler than trying to emulate TLS 1.3.
Regards
Marcel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets
2026-01-14 9:10 ` Neeraj Sanjay Kale
@ 2026-01-21 19:21 ` Marcel Holtmann
0 siblings, 0 replies; 23+ messages in thread
From: Marcel Holtmann @ 2026-01-21 19:21 UTC (permalink / raw)
To: Neeraj Sanjay Kale
Cc: Luiz Augusto von Dentz, Amitkumar Karwar, Sherry Sun,
Dmitrii Lebed, linux-bluetooth@vger.kernel.org,
linux-kernel@vger.kernel.org, Ethan Lo
Hi Neeraj,
>>> This patch series adds secure interface support for NXP Bluetooth
>>> chipsets to protect against UART-based attacks on Bluetooth security keys.
>>>
>>> Problem Statement:
>>> ==================
>>> Bluetooth UART drivers are vulnerable to physical attacks where
>>> adversaries can monitor UART TX/RX lines to extract sensitive cryptographic
>> material.
>>> As demonstrated in research [1], attackers can capture H4 packets
>>> containing Link Keys, LTKs, and other pairing data transmitted in
>>> plaintext over UART.
>>>
>>> Once an attacker obtains these keys from UART traffic, they can:
>>> - Decrypt all Bluetooth communication for paired devices
>>> - Impersonate trusted devices
>>> - Perform man-in-the-middle attacks
>>>
>>> This vulnerability affects any Bluetooth implementation using UART
>>> transport, making physical access to UART lines equivalent to
>>> compromising all paired device security.
>>>
>>> Solution:
>>> =========
>>> Implement a TLS 1.3-inspired secure interface that:
>>> - Authenticates the chipset using ECDSA signature verification
>>> - Establishes shared encryption keys via ECDH key exchange
>>> - Encrypts sensitive HCI commands (Link Key Reply, LTK Reply, etc.) using
>>> AES-GCM
>>> - Decrypts encrypted vendor events from the chipset
>>>
>>> This ensures that even with full UART access, attackers cannot extract
>>> usable cryptographic keys from the communication channel.
>>>
>>> Implementation Overview:
>>> ========================
>>> The solution is implemented in 11 incremental patches:
>>>
>>> 1-2: Add firmware metadata parsing and version detection
>>> 3-4: Establish secure interface framework and crypto setup
>>> 5-7: Implement TLS handshake (Host Hello, Device Hello, authentication)
>>> 8: Derive application traffic keys for encryption/decryption
>>> 9-10: Add command encryption and event decryption support
>>> 11: Add required crypto algorithm dependencies
>>>
>>> The implementation automatically detects secure interface capability
>>> via firmware version strings and enables encryption only when needed.
>>> Legacy chipsets continue to work without modification.
>>>
>>> Security Properties:
>>> ===================
>>> - Chipset authentication prevents rogue device substitution
>>> - Forward secrecy through ephemeral ECDH key exchange
>>> - Authenticated encryption (AES-GCM) prevents tampering
>>> - Per-session keys limit exposure from key compromise
>>>
>>> Testing:
>>> ========
>>> Tested on AW693 chipsets with secure firmware. Verified that:
>>> - Authentication handshake completes successfully
>>> - Sensitive commands are encrypted before transmission
>>> - Encrypted events are properly decrypted
>>> - UART monitoring shows only encrypted payloads for sensitive
>>> operations
>>> - Legacy chipsets remain unaffected
>>>
>>> [1] "BLAP: Bluetooth Low Energy Attacks on Pairing" - DSN 2022
>>>
>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fnets
>>>
>> ec.ethz.ch%2Fpublications%2Fpapers%2Fdsn22_blap.pdf&data=05%7C02%7
>> Cnee
>>>
>> raj.sanjaykale%40nxp.com%7C7e6471862d5d4d6b86bc08de52b47c29%7C686
>> ea1d3
>>>
>> bc2b4c6fa92cd99c5c301635%7C0%7C0%7C639039132284844210%7CUnknow
>> n%7CTWFp
>>>
>> bGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4z
>> MiIsIk
>>>
>> FOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=HV0OjNPoq%2B
>> P%2B07YW
>>> WCtrrGUlmxWBamNWMwfrbkan7yc%3D&reserved=0
>>
>> Ok, I start reading the document above but it says the problem is with HCI
>> itself though:
>>
>> 'We first present a link key extraction attack that exploits the security flaw in
>> the HCI dump, which records all data passed through the HCI interface in a log
>> file, including link keys.'
>>
>> It does say that it is passed to a log file though, maybe the permission of the
>> file is the problem then, either way this would be UART expecific. We do
>> require NET_ADMIN (aka. root) for accessing HCI though, both for monitoring
>> or generating HCI traffic (e.g.
>> HCI_USER_CHANNEL), so I don't believe these claims are valid with respect to
>> Linux since for collecting the logs with the likes of btmon that will require root
>> access, that said perhaps the -w option shall limit the permission of the file to
>> root only as well, in any case it is not like btmon can be run by an attacker
>> without root access, so it beats me how Linux could be considered vulnerable
>> here.
> The DSN’22 BLAP paper shows link‑key extraction from HCI dump logs (e.g., btmon)—a logging issue, not a Linux privilege bypass. Our threat model is different: physical sniffing of the H4 UART lines (common on M.2 Key‑E and bring‑up boards) where the link‑key exchange transits in plaintext. This series addresses that risk by encrypting the link‑key request/response (and related vendor events) over UART, so keys aren’t recoverable even with full wire access.
but you are not protecting SMP. I think this should be an all-or-nothing approach.
Regards
Marcel
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2026-01-21 19:28 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-13 7:47 [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 01/11] Bluetooth: btnxpuart: Add firmware metadata parsing for secure interface Neeraj Sanjay Kale
2026-01-13 8:46 ` Bluetooth: btnxpuart: Add secure interface support for NXP chipsets bluez.test.bot
2026-01-13 7:47 ` [PATCH v2 02/11] Bluetooth: btnxpuart: Print FW version and enable chip specific features Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 03/11] Bluetooth: btnxpuart: Add secure interface TLS authentication support Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 04/11] Bluetooth: btnxpuart: Implement TLS authentication crypto framework Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 05/11] Bluetooth: btnxpuart: Add TLS host hello handshake implementation Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 06/11] Bluetooth: btnxpuart: Add TLS device hello processing Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 07/11] Bluetooth: btnxpuart: Add device authentication Neeraj Sanjay Kale
2026-01-21 19:19 ` Marcel Holtmann
2026-01-13 7:47 ` [PATCH v2 08/11] Bluetooth: btnxpuart: Derive traffic keys from TLS 1.3 handshake Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 09/11] Bluetooth: btnxpuart: Add command encryption for sensitive HCI commands Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 10/11] Bluetooth: btnxpuart: Add encrypted event handling Neeraj Sanjay Kale
2026-01-13 7:47 ` [PATCH v2 11/11] Bluetooth: btnxpuart: Select crypto algorithms for secure interface Neeraj Sanjay Kale
2026-01-13 15:00 ` [RESEND PATCH v2 00/11] Bluetooth: btnxpuart: Add secure interface support for NXP chipsets Luiz Augusto von Dentz
2026-01-13 18:15 ` Luiz Augusto von Dentz
2026-01-14 9:19 ` [EXT] " Neeraj Sanjay Kale
2026-01-14 14:45 ` Luiz Augusto von Dentz
2026-01-16 9:49 ` Neeraj Sanjay Kale
2026-01-14 9:10 ` Neeraj Sanjay Kale
2026-01-21 19:21 ` Marcel Holtmann
-- strict thread matches above, loose matches on Subject: below --
2025-11-28 9:14 [PATCH v2 01/11] Bluetooth: btnxpuart: Add firmware metadata parsing for secure interface Neeraj Sanjay Kale
2025-11-28 10:02 ` Bluetooth: btnxpuart: Add secure interface support for NXP chipsets bluez.test.bot
2025-11-18 14:20 [PATCH v1 01/11] Bluetooth: btnxpuart: Add firmware metadata parsing for secure interface Neeraj Sanjay Kale
2025-11-18 15:07 ` Bluetooth: btnxpuart: Add secure interface support for NXP chipsets bluez.test.bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox