public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ v1 2/6] doc/btmon: Add SMP pairing flow documentation
Date: Tue, 10 Mar 2026 13:11:15 -0400	[thread overview]
Message-ID: <20260310171126.342447-2-luiz.dentz@gmail.com> (raw)
In-Reply-To: <20260310171126.342447-1-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Add comprehensive SMP pairing documentation covering:

- Pairing Phases 1-3: Feature exchange (IO capabilities, auth
  requirements, key distribution), authentication for both Secure
  Connections (public key, DHKey check) and Legacy pairing
  (confirm/random only), and key distribution (IRK, LTK, CSRK).

- Pairing Failure: Failure reason code table (0x01-0x0e) with
  diagnostic meanings for each code.

- Automating Pairing Analysis: grep patterns for identifying pairing
  attempts, detecting SC vs Legacy, finding failures, and correlating
  with encryption.

- Updated Automated Trace Analysis: Added pairing/security check step
  in the recommended workflow, SMP cross-reference in connection
  lifecycle patterns, and pairing failure debugging scenario.
---
 doc/btmon.rst | 280 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 275 insertions(+), 5 deletions(-)

diff --git a/doc/btmon.rst b/doc/btmon.rst
index f769a7af6e8b..bddbd07d3c35 100644
--- a/doc/btmon.rst
+++ b/doc/btmon.rst
@@ -1129,6 +1129,254 @@ The CCC descriptor at handle 0x000d belongs to the Service Changed
 characteristic (0x000c), because it falls between that value handle
 and the next characteristic declaration at 0x000e.
 
+
+SMP PAIRING FLOW
+================
+
+The Security Manager Protocol (SMP) handles pairing, key generation,
+and key distribution between Bluetooth devices. SMP traffic appears
+inside L2CAP on fixed CID 0x0006 (LE) or CID 0x0007 (BR/EDR). btmon
+decodes all SMP operations automatically.
+
+Pairing Phases
+--------------
+
+SMP pairing proceeds in three phases. Each phase produces a distinct
+pattern in the btmon output.
+
+**Phase 1: Feature Exchange**
+
+Pairing begins when one device sends a Security Request (peripheral)
+or the host initiates pairing directly. The initiator sends a Pairing
+Request and the responder replies with a Pairing Response::
+
+    > ACL Data RX: Handle 2048 flags 0x02 dlen 11       #497 [hci0] 0.026107
+          SMP: Pairing Request (0x01) len 6
+            IO capability: NoInputNoOutput (0x03)
+            OOB data: Authentication data not present (0x00)
+            Authentication requirement: Bonding, MITM, SC, CT2 (0x2d)
+            Max encryption key size: 16
+            Initiator key distribution: IdKey Sign (0x06)
+            Responder key distribution: IdKey Sign (0x06)
+
+    < ACL Data TX: Handle 2048 flags 0x00 dlen 11       #499 [hci0] 0.026894
+          SMP: Pairing Response (0x02) len 6
+            IO capability: KeyboardDisplay (0x04)
+            OOB data: Authentication data not present (0x00)
+            Authentication requirement: Bonding, SC, CT2 (0x29)
+            Max encryption key size: 16
+            Initiator key distribution: IdKey (0x02)
+            Responder key distribution: IdKey (0x02)
+
+Key fields to check:
+
+- **Authentication requirement** -- The ``SC`` flag indicates Secure
+  Connections. Its absence means Legacy Pairing.
+- **IO capability** -- Determines the association model (Just Works,
+  Passkey Entry, Numeric Comparison, OOB).
+- **Key distribution** -- Which keys each side will send after
+  encryption is established. ``IdKey`` = Identity Resolving Key (IRK),
+  ``EncKey`` = Long Term Key (legacy only), ``Sign`` = CSRK.
+
+**Phase 2: Authentication (Secure Connections)**
+
+For Secure Connections pairing (``SC`` flag set), both devices exchange
+public keys, then perform confirm/random value exchange::
+
+    > ACL Data RX: Handle 2048 flags 0x02 dlen 69       #501 [hci0] 0.098224
+          SMP: Pairing Public Key (0x0c) len 64
+            X: 1a2b3c4d...
+            Y: 5e6f7a8b...
+
+    < ACL Data TX: Handle 2048 flags 0x00 dlen 69       #503 [hci0] 0.148556
+          SMP: Pairing Public Key (0x0c) len 64
+            X: 9c8d7e6f...
+            Y: 0a1b2c3d...
+
+    < ACL Data TX: Handle 2048 flags 0x00 dlen 21       #505 [hci0] 0.149003
+          SMP: Pairing Confirm (0x03) len 16
+            Confirm value: a1b2c3d4e5f6...
+
+    > ACL Data RX: Handle 2048 flags 0x02 dlen 21       #507 [hci0] 0.212884
+          SMP: Pairing Random (0x04) len 16
+            Random value: 1122334455...
+
+    < ACL Data TX: Handle 2048 flags 0x00 dlen 21       #509 [hci0] 0.213100
+          SMP: Pairing Random (0x04) len 16
+            Random value: 6677889900...
+
+    > ACL Data RX: Handle 2048 flags 0x02 dlen 21       #511 [hci0] 0.278003
+          SMP: Pairing DHKey Check (0x0d) len 16
+            E: aabbccddee...
+
+    < ACL Data TX: Handle 2048 flags 0x00 dlen 21       #513 [hci0] 0.278450
+          SMP: Pairing DHKey Check (0x0d) len 16
+            E: ffeeddccbb...
+
+After DHKey Check, the initiator starts encryption at the HCI level::
+
+    < HCI Command: LE Start Encryption (0x08|0x0019) plen 28  #515 [hci0] 0.279002
+    > HCI Event: Encryption Change (0x08) plen 4              #517 [hci0] 0.342556
+          Status: Success (0x00)
+          Handle: 2048
+          Encryption: Enabled with AES-CCM (0x01)
+
+**Phase 2: Authentication (Legacy Pairing)**
+
+Legacy pairing (no ``SC`` flag) skips the Public Key and DHKey Check
+exchanges. Only Confirm and Random values are exchanged::
+
+    < ACL Data TX: Handle 2048 flags 0x00 dlen 21       #501 [hci0] 0.098224
+          SMP: Pairing Confirm (0x03) len 16
+            Confirm value: ...
+
+    > ACL Data RX: Handle 2048 flags 0x02 dlen 21       #503 [hci0] 0.162556
+          SMP: Pairing Confirm (0x03) len 16
+            Confirm value: ...
+
+    < ACL Data TX: Handle 2048 flags 0x00 dlen 21       #505 [hci0] 0.163003
+          SMP: Pairing Random (0x04) len 16
+            Random value: ...
+
+    > ACL Data RX: Handle 2048 flags 0x02 dlen 21       #507 [hci0] 0.228884
+          SMP: Pairing Random (0x04) len 16
+            Random value: ...
+
+**Phase 3: Key Distribution**
+
+After encryption is established, each device distributes keys as
+negotiated in Phase 1::
+
+    > ACL Data RX: Handle 2048 flags 0x02 dlen 21       #519 [hci0] 0.343002
+          SMP: Identity Information (0x08) len 16
+            Identity resolving key: 00112233445566778899aabbccddeeff
+
+    > ACL Data RX: Handle 2048 flags 0x02 dlen 12       #521 [hci0] 0.343556
+          SMP: Identity Address Information (0x09) len 7
+            Address type: Public (0x00)
+            Address: 00:11:22:33:44:55
+
+The Identity Address Information reveals the device's true public or
+static random address (as opposed to a Resolvable Private Address used
+during connection).
+
+For Legacy Pairing, LTK distribution also appears::
+
+    > ACL Data RX: Handle 2048 flags 0x02 dlen 21       #519 [hci0] 0.343002
+          SMP: Encryption Information (0x06) len 16
+            Long term key: 00112233...
+
+    > ACL Data RX: Handle 2048 flags 0x02 dlen 15       #521 [hci0] 0.343556
+          SMP: Central Identification (0x07) len 10
+            EDIV: 0x1234
+            Rand: 0x0123456789abcdef
+
+Pairing Failure
+---------------
+
+When pairing fails, one device sends a Pairing Failed PDU::
+
+    > ACL Data RX: Handle 2048 flags 0x02 dlen 6        #505 [hci0] 0.213002
+          SMP: Pairing Failed (0x05) len 1
+            Reason: Authentication requirements (0x03)
+
+SMP failure reasons:
+
+.. list-table::
+   :header-rows: 1
+   :widths: 8 35 57
+
+   * - Code
+     - Reason
+     - Diagnostic Meaning
+   * - 0x01
+     - Passkey Entry Failed
+     - User cancelled or entered wrong passkey
+   * - 0x02
+     - OOB Not Available
+     - OOB data expected but not provided
+   * - 0x03
+     - Authentication Requirements
+     - Devices cannot agree on security level (e.g.,
+       one requires MITM but IO caps only allow Just Works)
+   * - 0x04
+     - Confirm Value Failed
+     - Cryptographic check failed; possible MITM attack
+   * - 0x05
+     - Pairing Not Supported
+     - Remote does not support pairing
+   * - 0x06
+     - Encryption Key Size
+     - Cannot agree on key size
+   * - 0x07
+     - Command Not Supported
+     - Received unrecognized SMP command
+   * - 0x08
+     - Unspecified Reason
+     - Generic failure
+   * - 0x09
+     - Repeated Attempts
+     - Pairing rate-limited; wait before retry
+   * - 0x0a
+     - Invalid Parameters
+     - Invalid fields in SMP command
+   * - 0x0b
+     - DHKey Check Failed
+     - ECDH key agreement failed (SC only)
+   * - 0x0c
+     - Numeric Comparison Failed
+     - User rejected numeric comparison
+   * - 0x0d
+     - BR/EDR Pairing In Progress
+     - Classic pairing already active
+   * - 0x0e
+     - Cross-Transport Key Derivation Not Allowed
+     - CTKD rejected by policy
+
+Automating Pairing Analysis
+----------------------------
+
+**Identify all pairing attempts**::
+
+    grep -n "Pairing Request\|Pairing Response\|Pairing Failed\|Pairing Public Key\|DHKey Check" output.txt
+
+**Check pairing method (Secure Connections vs Legacy)**:
+
+- If ``Pairing Public Key`` appears between Request/Response and
+  Confirm: Secure Connections.
+- If only Confirm/Random follow Request/Response: Legacy Pairing.
+- Check the ``Authentication requirement`` line for the ``SC`` flag.
+
+**Detect pairing failures**::
+
+    grep -n "Pairing Failed" output.txt
+
+**Correlate pairing with encryption**:
+
+After successful pairing, expect ``Encryption Change`` with
+``Status: Success``. Search for::
+
+    grep -n "Encryption Change\|Encryption:" output.txt
+
+**Identify re-pairing on reconnect**:
+
+Reconnections to a bonded device should show ``Encryption Change``
+without SMP traffic (using stored keys). If SMP Pairing Request
+appears on reconnection, the bond was lost on one side.
+
+**Full pairing diagnosis pattern**:
+
+1. Find ``Pairing Request`` -- note the handle, IO capabilities,
+   auth requirements
+2. Find ``Pairing Response`` -- compare IO capabilities to determine
+   association model
+3. Check for ``Pairing Failed`` -- if present, the reason code
+   identifies the failure
+4. Check for ``Encryption Change`` with ``Status: Success`` -- confirms
+   pairing completed
+5. Check for ``Identity Address Information`` -- reveals the device's
+   true address
+
 EXAMPLES
 ========
 
@@ -1186,17 +1434,23 @@ Recommended Workflow
        grep -n "Disconnect Complete" output.txt
 
    Then examine the lines following each match for the ``Reason:``
-   field.
+   field. See `HCI ERROR AND DISCONNECT REASON CODES`_ for
+   interpretation.
 
-5. **Identify LE Audio**: Search for ASCS and CIS activity::
+5. **Check pairing/security**: Search for SMP activity (see
+   `SMP PAIRING FLOW`_)::
+
+       grep -n "Pairing Request\|Pairing Response\|Pairing Failed\|Encryption Change" output.txt
+
+6. **Identify LE Audio**: Search for ASCS and CIS activity::
 
        grep -n "ASE Control Point\|CIG Parameters\|Create Connected Isochronous\|CIS Established\|Setup ISO Data Path" output.txt
 
-6. **Check for errors**: Search for non-success status codes::
+7. **Check for errors**: Search for non-success status codes::
 
        grep -n "Status:" output.txt | grep -v "Success"
 
-7. **Extract GATT discovery**: Filter the GATT service/characteristic
+8. **Extract GATT discovery**: Filter the GATT service/characteristic
    discovery traffic (see `RECONSTRUCTING A GATT DATABASE FROM SNOOP
    TRACES`_)::
 
@@ -1223,7 +1477,8 @@ pattern in the trace:
 2. ``LE Connection Update Complete`` -- connection parameters changed
    (may occur zero or more times)
 3. ``Encryption Change`` -- link encrypted (may show encryption
-   algorithm)
+   algorithm). See `SMP PAIRING FLOW`_ for the SMP exchange that
+   precedes this.
 4. ACL Data with ATT/SMP/L2CAP -- service discovery and data exchange
 5. ``Disconnect Complete`` -- connection ended, check Reason field
 
@@ -1238,6 +1493,21 @@ For LE Audio connections, additional steps appear between 3 and 5:
 - ``Disconnect Complete`` on CIS handle (stream ended)
 - ``LE Remove CIG`` (group removed)
 
+Common Debugging Scenarios
+---------------------------
+
+**Pairing failure diagnosis**:
+
+1. Find ``Pairing Request`` -- note IO capabilities and auth
+   requirements
+2. Find ``Pairing Response`` -- compare to determine association model
+3. If ``Pairing Failed`` appears, the reason code identifies the
+   failure (see `SMP PAIRING FLOW`_)
+4. If ``Encryption Change`` shows ``Status: Success``, pairing
+   succeeded
+5. If no SMP traffic on reconnect but ``Encryption Change`` fails,
+   the bond was lost on one side
+
 Vendor-Specific Events
 ----------------------
 
-- 
2.53.0


  reply	other threads:[~2026-03-10 17:11 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-10 17:11 [PATCH BlueZ v1 1/6] doc/btmon: Add GATT database reconstruction guide Luiz Augusto von Dentz
2026-03-10 17:11 ` Luiz Augusto von Dentz [this message]
2026-03-10 17:11 ` [PATCH BlueZ v1 3/6] doc/btmon: Add L2CAP channel tracking documentation Luiz Augusto von Dentz
2026-03-10 17:11 ` [PATCH BlueZ v1 4/6] doc/btmon: Add LE Audio protocol flow documentation Luiz Augusto von Dentz
2026-03-10 17:11 ` [PATCH BlueZ v1 5/6] doc/btmon: Add protocol error codes documentation Luiz Augusto von Dentz
2026-03-10 17:11 ` [PATCH BlueZ v1 6/6] doc/btmon: Add advertising and scanning documentation Luiz Augusto von Dentz
2026-03-10 18:14 ` [BlueZ,v1,1/6] doc/btmon: Add GATT database reconstruction guide bluez.test.bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260310171126.342447-2-luiz.dentz@gmail.com \
    --to=luiz.dentz@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox