.. _GAP-bond-manager-and-le-secure-connections:

GAP Bond Manager and LE Secure Connections
------------------------------------------

.. attention::
    The |DEVICEHIGH| platform is still under development and some of the features
    mentioned on this page might not be available yet.
    Make sure to review the release notes of the |SDK| for a complete overview
    of the features currently supported.

The GAP Bond Manager (GAPBondMgr) is a configurable module that offloads most of the Pairing &
Bonding security mechanisms associated with the Security Manager (SM) protocol from the application.
The GAPBongMgr executes in the protocol stack task's context. :numref:`GAP-bond-manager-terminology` lists the terminology.

.. _GAP-bond-manager-terminology:
.. table:: GAP Bond Manager Terminology

    +----------------------+-----------------------------------------------------------------------+
    |     **Term**         |     **Description**                                                   |
    +----------------------+-----------------------------------------------------------------------+
    |     Pairing          |     The process of generating & exchanging keys. Not to be confused   |
    |                      |     with forming or establishing a BLE connection between two devices.|
    +----------------------+-----------------------------------------------------------------------+
    |     Encryption       |     Data is encrypted after pairing, or re-encryption (a subsequent   |
    |                      |     connection where keys are looked up from non-volatile memory).    |
    +----------------------+-----------------------------------------------------------------------+
    |     Association      |     The pairing method used based on the I/O Capabilities of both     |
    |                      |     devices. For LE devices, Just Works, Numeric Comparison,          |
    |                      |     Passkey Entry and Out-Of-Band are supported.                      |
    +----------------------+-----------------------------------------------------------------------+
    |     Authentication   |     The pairing process using an association method that supports     |
    |                      |     MITM (Man in the Middle) protection.                              |
    +----------------------+-----------------------------------------------------------------------+
    |     Bonding          |     Storing the keys generated during the pairing process in          |
    |                      |     non-volatile memory to use for the next encryption sequence.      |
    +----------------------+-----------------------------------------------------------------------+
    |     Authorization    |     An additional application level verification in addition to       |
    |                      |     authentication.                                                   |
    +----------------------+-----------------------------------------------------------------------+
    |     OOB              |     Out of Band. Pairing keys are not exchanged over the air, but     |
    |                      |     rather over some other sources such as serial port or NFC. This   |
    |                      |     provides MITM protection.                                         |
    +----------------------+-----------------------------------------------------------------------+
    |     MITM             |     Man in the Middle protection. MITM provides authentication        |
    |                      |     during the pairing process which helps prevent a malicious        |
    |                      |     attacker from impersonating the peer device during the key        |
    |                      |     exchange.                                                         |
    +----------------------+-----------------------------------------------------------------------+
    |     Just Works       |     Unauthenticated pairing association method where keys are         |
    |                      |     exchanged without MITM protection.                                |
    +----------------------+-----------------------------------------------------------------------+



The general process that the GAPBondMgr uses is as follows:

1. The pairing process: exchange keys through the methods described in
:ref:`selection_of_pairing_method`.

2. The encryption process: Encrypt the link using keys Step 1.

3. The bonding process: store keys in secure flash (Non-Volatile memory).

4. Reconnecting: Use the keys stored in Non-Volatile memory to encrypt the link.

.. tip::
   Performing all of these steps is not necessary. For example,
   two devices may choose to pair but not bond.

Security Modes in a Bluetooth LE Connection
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The Generic Access Protocol (GAP) layer defines two security modes, along with
several security levels per mode.

**Security Mode 1** enforces security by means of encryption, and contains
four levels:

    * Level 1: No Security (No authentication and no encryption)
    * Level 2: Unauthenticated pairing with encryption
    * Level 3: Authenticated pairing with AES-CCM encryption
    * Level 4: Authenticated LE Secure Connections pairing with encryption
      using Elliptic Curve Diffie-Hellman P-256 (ECDH) and AES-CCM encryption.

**Security Mode 2** enforces security by means of data signing, and contains
two levels:

   * Level 1: Unauthenticated pairing with data signing
   * Level 2: Authenticated pairing with data signing

A connection is always established in Security Mode 1, level 1 and can later
be upgraded to any other security level.
The pairing method chosen determines the actual security mode and level
achievable. As discussed in :ref:`selection_of_pairing_method`, the pairing
method is selected based on the capabilities of the devices in the connection.

When configured to do so, the |STACK| allows to achieve all the security modes
and levels presented, including security mode 1 level 4.

Additional details regarding this topic can be found in [Vol 3], Part C,
section §10 of the |CORESPEC|.

.. _selection_of_pairing_method:

Selection of Pairing Method
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Bluetooth Core Specification Version 4.2 added support for the *LE Secure Connections*
feature to enable additional strength to the BLE pairing process. For a detailed
description of the algorithms used for *LE Secure Connections*, see the
**Security Architecture** section ([Vol 1], Part A, Section 5.1) of the |CORESPEC|.
The previous pairing methods used in the Bluetooth Core Specification Versions 4.1
and 4.0 are still available, and are now defined as *LE Legacy Pairing*.
The main difference is that *Secure Connection* uses Elliptic Curve Diffie-Hellman (ECDH)
cryptography, while LE Legacy Pairing does not.

There are four types of pairing methods which are referred to as "Association Models" in the core
specification. Each pairing method is described in detail
in :ref:`GAPBondMgr_examples_for_different_pairing_modes`.

-  Just Works (LE Secure Connections or LE Legacy)

-  Passkey Entry (LE Secure Connections or LE Legacy)

-  Numeric Comparison (LE Secure Connections)

-  Out Of Band (LE Secure Connections or LE Legacy)

Which pairing method is selected, and whether or not pairing will succeed
depends on the following parameters from both peer devices during the pairing process:

- Out Of Band (OOB) set / not set

- Man In The Middle (MITM) set / not set

- Input/Output (IO) Capabilities

- LE Secure Connections supported / not supported

The GAPBondMgr parameters, as they map to the table parameters below are listed
here. For more information on these parameters, see :ref:`ble_api_reference`
(GAPBondMgr section).

-  :ble_api:`GAPBOND_OOB_ENABLED`: Out of band (OOB) set / not set

-  :ble_api:`GAPBOND_MITM_PROTECTION`: Man in the middle (MITM) set / not set

-  :ble_api:`GAPBOND_IO_CAPABILITIES`: Input/Output (IO) Capabilities

-  :ble_api:`GAPBOND_SECURE_CONNECTION`: LE Secure connections supported / not
   supported

   Beyond what the |CORESPEC| defines, this parameter also affects whether or not
   pairing succeeds, as described in :ref:`ble_api_reference` (GAPBondMgr
   section).

The tables below are from the **Selecting Key Generation Method** section
([Vol 3], Part H, Section 2.3.5.1) of the |CORESPEC|. Use these tables to
determine which pairing mode is selected for any set of parameters.

If both devices support LE Secure Connections, use
:numref:`gappbondmgr_secur_connection_parameters` to decide upon the next step.

.. _gappbondmgr_secur_connection_parameters:
.. table:: GAPBondMgr parameters when LE Secure Connections is supported by both devices
	
    +---------------------------+---------------------+-----------------------+---------------------+------------------------+
    |                           | Initiator OOB Set   | Initiator OOB Not Set | Initiator MITM Set  | Initiator MITM Not Set |
    +===========================+=====================+=======================+=====================+========================+
    | **Responder OOB Set**     | Use OOB             | Use OOB               |                                              |
    +---------------------------+---------------------+-----------------------+                                              |
    | **Responder OOB Not Set** | Use OOB             | Check MITM            |                                              |
    +---------------------------+---------------------+-----------------------+---------------------+------------------------+
    | **Responder MITN Set**    |                                             | Use IO Capabilities | Use IO Capabilities    |
    +---------------------------+                                             +---------------------+------------------------+
    | **Responder MITN Not Set**|                                             | Use IO Capabilities | Use Just Works         |
    +---------------------------+---------------------------------------------+---------------------+------------------------+

If at least one device does **not** support LE Secure Connections, use
:numref:`gappbondmgr_no_secur_connection_parameters` to decide upon the next step.

.. _gappbondmgr_no_secur_connection_parameters:
.. table:: GAPBondMgr parameters when LE Secure Connections is **not** supported by one or both devices.

    +---------------------------+---------------------+-----------------------+---------------------+------------------------+
    |                           | Initiator OOB Set   | Initiator OOB Not Set | Initiator MITM Set  | Initiator MITM Not Set |
    +===========================+=====================+=======================+=====================+========================+
    | **Responder OOB Set**     | Use OOB             | Check MITM            |                                              |
    +---------------------------+---------------------+-----------------------+                                              |
    | **Responder OOB Not Set** | Check MITM          | Check MITM            |                                              |
    +---------------------------+---------------------+-----------------------+---------------------+------------------------+
    | **Responder MITN Set**    |                                             | Use IO Capabilities | Use IO Capabilities    |
    +---------------------------+                                             +---------------------+------------------------+
    | **Responder MITN Not Set**|                                             | Use IO Capabilities | Use Just Works         |
    +---------------------------+---------------------------------------------+---------------------+------------------------+

If, based on one of the previous tables, IO capabilities are to be used to
determine the association model, use :numref:`gappbondmgr_io_capabilities_parameters`

.. _gappbondmgr_io_capabilities_parameters:
.. table:: GAPBondMgr parameters with IO capabilities

    +----------------------+------------------------------------------------------------------------------------------------------------------------------------------+
    |                      |                                                                 Initiator                                                                |
    |                      +-----------------------------+-----------------------------+-----------------------------+------------------+-----------------------------+
    | Responder            | Display Only                | Display YesNo               | Keyboard Only               | NoInput NoOutput | Keyboard Display            |
    +======================+=============================+=============================+=============================+==================+=============================+
    | **Display Only**     | Just Works                  | Just Works                  | Passkey Entry:              | Just Works       | Passkey Entry:              |
    |                      | Unauthenticated             | Unauthenticated             | Responder displays,         | Unauthenticated  | Responder displays,         |
    |                      |                             |                             | Initiator inputs            |                  | Initiator inputs            |
    |                      |                             |                             | Authenticated               |                  | Authenticated               |
    +----------------------+-----------------------------+-----------------------------+-----------------------------+------------------+-----------------------------+
    | **Display YesNo**    | Just Works                  | Just Works                  | Passkey Entry:              | Just Works       | Passkey Entry               |
    |                      | Unauthenticated             | (For LE Legacy Pairing)     | Responder displays,         | Unauthenticated  | (For LE Legacy Pairing)     |
    |                      |                             | Unauthenticated             | Initiator inputs            |                  | Responder displays          |
    |                      |                             |                             | Authenticated               |                  | Initiator inputs            |
    |                      |                             |                             |                             |                  | Authenticated               |
    |                      |                             +-----------------------------+                             |                  +-----------------------------+
    |                      |                             | Numeric Comparison          |                             |                  | Numeric Comparison          |
    |                      |                             | (For LE Secure Connections) |                             |                  | (For LE Secure Connections) |
    |                      |                             | Authenticated               |                             |                  | Authenticated               |
    +----------------------+-----------------------------+-----------------------------+-----------------------------+------------------+-----------------------------+
    | **Keyboard Only**    | Passkey Entry:              | Passkey Entry:              | Passkey Entry:              | Just Works       | Passkey Entry:              |
    |                      | Initiator displays,         | Initiator displays,         | Initiator displays,         | Unauthenticated  | Initiator displays,         |
    |                      | Responder inputs            | Responder inputs            | Responder inputs            |                  | Responder inputs            |
    |                      | Authenticated               | Authenticated               | Authenticated               |                  | Authenticated               |
    +----------------------+-----------------------------+-----------------------------+-----------------------------+------------------+-----------------------------+
    | **NoInput NoOutput** | Just Works                  | Just Works                  | Just Works                  | Just Works       | Just Works                  |
    |                      | Unauthenticated             | Unauthenticated             | Unauthenticated             | Unauthenticated  | Unauthenticated             |
    +----------------------+-----------------------------+-----------------------------+-----------------------------+------------------+-----------------------------+
    | **Keyboard Display** | Passkey Entry:              | Passkey Entry               | Passkey Entry:              | Just Works       | Passkey Entry               |
    |                      | Initiator displays,         | (For LE Legacy Pairing)     | Responder displays,         | Unauthenticated  | (For LE Legacy Pairing)     |
    |                      | Responder inputs            | Initiator displays          | Initiator inputs            |                  | Initiator displays          |
    |                      | Authenticated               | Responder inputs            | Authenticated               |                  | Responder inputs            |
    |                      |                             | Authenticated               |                             |                  | Authenticated               |
    |                      |                             +-----------------------------+                             |                  +-----------------------------+
    |                      |                             | Numeric Comparison          |                             |                  | Numeric Comparison          |
    |                      |                             | (For LE Secure Connections) |                             |                  | (For LE Secure Connections) |
    |                      |                             | Authenticated               |                             |                  | Authenticated               |
    +----------------------+-----------------------------+-----------------------------+-----------------------------+------------------+-----------------------------+

Using GAPBondMgr
^^^^^^^^^^^^^^^^

This section describes what the application must do to configure, start, and use
the GAPBondMgr. The GAPBondMgr is defined in ``gapbondmgr.c`` and ``gapbondmgr.h``.
:ref:`ble_api_reference` (GAPBondMgr section) describes the full API including
commands, configurable parameters, events, and callbacks.

The GAPBondMgr is enabled by default using SysConfig in all BLE5-Stack projects,
with the exception of ``host_test``. The following steps are provided for
reference.

The general steps to use the GAPBondMgr module are as follows:

1. Configure the stack to include GAPBondMgr functionality by defining the
following in ``build_config.opt`` in the project:

   -  ``-DGAP_BOND_MGR``

  .. note::
     GAPBondMgr is included by default using sysConfig tool in most of the examples
     except host_test. Thus step 1 is only applicable for host_test example.

2. If using LE Secure Connections, the PDU size must be >= 69. This can be set by
defining the following preprocessor symbol in the application
project: ``MAX_PDU_SIZE=69``. 

  .. note::
     MAX_PDU_SIZE is set to 69 by default using sysConfig tool in most of the examples
     except host_test. This step is only applicable for host_test example.

3. Configure the GAPBondMgr by initializing its parameters as desired. GAPBondMgr
configuration parameters are not persistent and must be configured after the device
is reset. See :ref:`ble_api_reference` (GAPBondMgr section) for a complete list of
parameters with functionality described. There are examples of this for the various
pairing/bonding modes in :ref:`GAPBondMgr_examples_for_different_pairing_modes`.

4. Register application callbacks with the GAPBondMgr, so that the application
can communicate with the GAPBondMgr and be notified of events.

  .. code-block:: c
    :caption: **ble\_stack\_api.c** bleStack_initGapBond - Initialize GapBondMgr

    // Start Bond Manager and register callback
    VOID GAPBondMgr_Register((gapBondCBs_t *)bleApp_bondMgrCBs);

Here ``bleApp_bondMgrCBs`` is defined as a structure containing the
GAPBondMgr Callbacks. A passcode callback function is mandatory.

  .. code-block:: c
    :caption: **bleapputil\_init.c** Register callback

    // GAP Bond Manager Callbacks
    gapBondCBs_t BLEAppUtil_bondMgrCBs =
    {
        BLEAppUtil_passcodeCB, // Passcode callback
        BLEAppUtil_pairStateCB // Pairing/Bonding state Callback
    };

The above excerpt comes from the Basic BLE framework. It is not recommended to
modify this file but rather to register for an application callback using the
provided framework. In short, take a look at this excerpt from ``app_pairing.c``
that defines an EventHandler function using the BLEAppUtil framework.

  .. code-block:: C

    BLEAppUtil_EventHandler_t pairingPasscodeHandler =
    {
        .handlerType    = BLEAPPUTIL_PASSCODE_TYPE,
        .pEventHandler  = Pairing_passcodeHandler
    };

    BLEAppUtil_EventHandler_t PairingPairStateHandler =
    {
        .handlerType    = BLEAPPUTIL_PAIR_STATE_TYPE,
        .pEventHandler  = Pairing_pairStateHandler,
        .eventMask      = BLEAPPUTIL_PAIRING_STATE_STARTED |
                          BLEAPPUTIL_PAIRING_STATE_COMPLETE |
                          BLEAPPUTIL_PAIRING_STATE_ENCRYPTED |
                          BLEAPPUTIL_PAIRING_STATE_BOND_SAVED,
    };

5. Once the GAPBondMgr is configured, it operates mostly autonomously from the
perspective of the application. When a connection is established, the GAPBondMgr
manages pairing and bonding depending on the configuration parameters set
during initialization. It also communicates with the application as needed
through the defined callbacks.

A few parameters can be set and functions can be called asynchronously at any time from
the application. See :ref:`ble_api_reference` (GAPBondMgr section) for more
information.

Most communication between the GAPBondMgr and the application at this point
occurs through the callbacks which were registered in Step 4.
:numref:`gapbondmgr_flow_diagram` is a flow diagram example of the GAPBondMgr
notifying the application that pairing has been completed. The same method
occurs for various other events and will be expanded upon in the following section.

.. _gapbondmgr_flow_diagram:
.. uml::
  :caption: GapBondMgr Callback Example.
  :align: center

  @startuml
    participant Application
    participant BLEAppUtil as "BLE Application Framework"
    participant Gapbondmgr as "GAPBondMgr"
    participant BLEStack as "BLE Stack"

    BLEStack -> Gapbondmgr : GAP_AUTHENTICATION_\nCOMPLETE_EVENT
    Gapbondmgr -> BLEAppUtil : Pairing state callback
    BLEAppUtil -> BLEAppUtil : BLEAppUtil_pairStateCB
    rnote over "BLEAppUtil"
      BLEAPPUTIL_EVT_PAIRING_STATE_CB
    end note
    BLEAppUtil -> BLEAppUtil: BLEAppUtil_processPairStateMsg
    rnote over "Application"
      BLEAPPUTIL_PAIR_STATE_TYPE
    end note
    BLEAppUtil -> Application: PairingPairStateHandler
    rnote over "Application"
      BLEAPPUTIL_PAIRING_STATE_COMPLETE
    end note

  @enduml


.. _GAPBondMgr_examples_for_different_pairing_modes:

GAPBondMgr Examples for Different Pairing Methods
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This section provides message diagrams for the types of security
that can be implemented. These modes assume acceptable I/O
capabilities are available for the security mode, and that the
selection of whether or not to support LE Secure Connections allows for
the pairing method. See the :ref:`selection_of_pairing_method` on how these
parameters affect pairing. These examples only consider the pairing aspect.
Bonding can be added to each type of pairing in the same manner and
is shown in the next section.

.. caution::
   The code snippets here are not complete functioning
   examples, and are only intended for illustration purposes.

.. warning::
   It is not allowed to set MITM to TRUE while IO capability is
   set to GAPBOND_IO_CAP_NO_INPUT_NO_OUTPUT since these two conflict
   each other.


Disabling Pairing
"""""""""""""""""

With pairing mode set to ``GAPBOND_PAIRING_MODE_NO_PAIRING``, the |STACK|
automatically rejects any attempt at pairing.
Configure the GAPBondMgr as follows to disable pairing:

.. code-block:: c

    // Pairing is not allowed
    uint8_t pairMode = GAPBOND_PAIRING_MODE_NO_PAIRING;
    GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);

Enabling Pairing
""""""""""""""""

To start or allow the pairing process after a connection is formed, the GAPBondMgr can be
configured to automatically request pairing or wait for pairing request from a
peer device. The actual behavior depends on the device's GAP role (Central or Peripheral)
and the setting of the GAPBondMgr pairing mode (``GAPBOND_PAIRING_MODE``).

To initiate the pairing process on Peripheral role devices, ``GAPBOND_PAIRING_MODE_INITIATE`` will
send a Slave Security Request shortly after the GAPBondMgr is informed that the connection is formed.
For Central role devices, ``GAPBOND_PAIRING_MODE_INITIATE`` will send a Pairing Request or request
the Link Layer to encrypt the link if the device has previously paired/bonded:

.. code-block:: c

    // Initiate pairing request
    uint8_t pairMode = GAPBOND_PAIRING_MODE_INITIATE;
    GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);


The Peripheral can be configured to wait for a *Pairing Request* from the Central when the pairing mode
is set to ``GAPBOND_PAIRING_MODE_WAIT_FOR_REQ``. When this pairing mode is selected, the GAPBondMgr will
automatically respond with a *Pairing Response* based on other GAPBondMgr configured parameters.

.. code-block:: c

    // Wait for a pairing request
    uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
    GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);


.. tip:: When pairing with smartphone Central devices, it is recommended to use ``GAPBOND_PAIRING_MODE_WAIT_FOR_REQ``
         as undefined behavior may occur when a Slave Security Request is sent by the Peripheral. Both iOS
         and Android will initiate pairing when the peripheral responds with an *Insufficient Authentication* error
         response when a GATT secure characteristic is accessed.

Pairing can also be enabled by utilizing :ble_api:`GAPBondMgr_Pair`. This API can be used to start the pairing 
process when pairing is not started automatically by the GAPBondMgr. An example use case of this API is to be 
able to start pairing from the application. This API can also be used to re-pair after initial pairing has 
occurred. An example use case of this is if pairing requirements have changed and need to be updated. See 
:ref:`ble_api_reference` GAPBondMgr section for more information on the function. 

.. code-block:: c

  bStatus_t stat = GAPBondMgr_Pair(connHandle);

.. _lesc-intro:

Bond Failure
""""""""""""
Bonding failure actions are executed after an unsuccessful bonding attempt. 
The actions can be set using the ``GAPBOND_BOND_FAIL_ACTION`` parameter. 
For instance, if you want to initiate pairing directly after a bond failure, set the 
``GAPBOND_BOND_FAIL_ACTION`` action to ``GAPBOND_FAIL_INITIATE_PAIRING``. 

.. code-block:: C

  uint8_t gapbondFailure = GAPBOND_FAIL_INITIATE_PAIRING;
  GAPBondMgr_SetParameter(GAPBOND_BOND_FAIL_ACTION, sizeof(uint8_t), &gapbondFailure);

The bonding failure actions that are available are listed below. 

-  :ble_api:`GAPBOND_FAIL_INITIATE_PAIRING`: Initiate pairing after an unsuccessful bonding attempt.

-  :ble_api:`GAPBOND_FAIL_NO_ACTION`: No action is taken after an unsuccessful bonding attempt. 

-  :ble_api:`GAPBOND_FAIL_TERMINATE_ERASE_BONDS`: Terminate link and erases all existing bonds after an unsuccessful bonding attempt. 

-  :ble_api:`GAPBOND_FAIL_TERMINATE_ERASE_SINGLE_BOND`: Terminate link and erases the failed bond after an unsuccessful bonding attempt. 

-  :ble_api:`GAPBOND_FAIL_TERMINATE_LINK`: Terminate the link after an unsuccessful bonding attempt. 

.. warning::
    Using ``GAPBOND_FAIL_INITIATE_PAIRING`` action can start a loop in software when in a central role, 
    and can lead to a PIN/Key missing result when in a peripheral role, as there is no defined packet for 
    bonding failure between peers.

The ``GAPBOND_BOND_FAIL_ACTION`` defaults to ``GAPBOND_FAIL_TERMINATE_ERASE_SINGLE_BOND`` action. Refer 
to :ref:`ble_api_reference` GAPBondMgr section for more information on the different actions. 

LE Secure Connections
"""""""""""""""""""""

LE Secure Connections is enabled by default in |STACK|. If you don't want to use
LE Secure Connections, set the ``GAPBOND_SECURE_CONNECTION`` variable
to ``GAPBOND_SECURE_CONNECTION_NONE`` during the GAPBondMgr initialization.

.. code-block:: c

  uint8_t gapbondSecure = GAPBOND_SECURE_CONNECTION_NONE;
  GAPBondMgr_SetParameter(GAPBOND_SECURE_CONNECTION, sizeof(uint8_t), &gapbondSecure);

It is important when trying to decipher over-the-air sniffer logs with LE Secure
Connections enabled, you need to use a specific "debug" key as defined by Vol 3
Part H section 2.3.5.6.1 of the |CORESPEC|. In the |STACK|, this key is
enabled using SysConfig, by checking 'ECC Debug Keys' under BLE, Bond Manager (see 
:ref:`bond_manager_configurations`).
When either the initiating or non-initiating device uses this specific debug
key, it enables over-the-air sniffer equipment that supports LE Secure Connections to
determine the :term:`LTK` and therefore monitor/decrypt encrypted traffic throughout
the connection.

LESC Limitations & Recommendations
""""""""""""""""""""""""""""""""""

LE Secure Connections uses an ECDH public-private key pair as part of the
pairing process. See :ref:`selection_of_pairing_method` and the *LE Secure
Connections Pairing Phase 2* section of the |CORESPEC| for more information
about how these keys and how they are used in the pairing process.

To summarize, as part of LESC pairing Phase 1 each device will generate its own
ECDH public-private key pair. As part of LESC pairing Phase 2 each device will
compute the Diffie-Hellman (DH) Key based on the public keys that are exchanged.

ECC public-private and DH key generation is implemented by the ECDH
driver for the Private Key Accelerator (PKA) on the |DEVICE|. These
routines are **blocking** by nature and take around **136.5ms** to execute.
During LESC pairing, the ECDH driver will be accessed twice by the link
layer (LL) once to generate the public/private key pair and again to generate
the DH key. This means the stack OSAL tasks will be blocked for
around **136.5ms** twice during pairing. However, the user application task
will be able to run at this time.

Because of this, TI recommends the following when using LESC:

    - Supervision timeout >= **140ms**

To alleviate the amount of blocking required, the user application can
generate the public-private key pair ahead of the pairing process, or it can
define when the keys should be recycled by using the following parameters of
the GapBondMgr. These options are mutually exclusive, as generation of keys
by the application bypasses the recycle parameter. To truly minimize the
affect of ECC on the BLE connection, perform ECC before any connections
are established.

- :ble_api:`GAPBOND_ECC_KEYS`
- :ble_api:`GAPBOND_ECCKEY_REGEN_POLICY`

.. _authentication-pairing-only:

Authentication Pairing Only
"""""""""""""""""""""""""""
For users that want the pairing method results in a key generation that provides 
Authenticated MITM protection only, they can achieve that by doing the following. 

.. code-block:: c

  uint8_t ioCap = GAPBOND_IO_CAP_KEYBOARD_DISPLAY;
  uint8_t mitm = TRUE;
  uint8_t authenPairingOnly = TRUE;
  
  // Only certain combinations of IO capability will result
  // authenticad pairing mode. Here we use GAPBOND_IO_CAP_KEYBOARD_DISPLAY
  // as code example to make sure whichever IO capability other than NoInput
  // NoOutput the peer device has will result in an authenticated link
  GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);

  // For authenticated pairing, MITM has to be set to TRUE
  GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof (uint8_t), &mitm);

  // Enable authentication only pairing
  GAPBondMgr_SetParameter( GAPBOND_AUTHEN_PAIRING_ONLY, sizeof (uint8_t), &authenPairingOnly);

Upon setting `GAPBOND_AUTHEN_PAIRING_ONLY` to true, if the peer device's IO
capability can not result in authenticated link, the |STACK| will 
reject the pairing and return error code `SMP_PAIRING_FAILED_AUTH_REQ`.

.. _gap_authentication_only_fig:
.. uml::
  :caption: Authentication Only Pairing.
  :align: center

   @startuml

    participant Application
    participant BLEAppUtil as "BLE Application Framework"
    participant Gapbondmgr as "GAPBondMgr"
    participant BLEStack as "BLE Stack"

    BLEStack -> Gapbondmgr : GAP_LINK_ESTABLISHED_EVENT
    Gapbondmgr -> BLEStack : GAPBondMgr_LinkEst()
    Gapbondmgr -> BLEStack : GAP_Authenticate()
    BLEStack -->] : Pairing req
    Gapbondmgr -> BLEAppUtil : BLEAppUtil_pairStateCB
    BLEAppUtil -> Application : PairingPairStateHandler
    rnote over Application
    BLEAPPUTIL_PAIRING_
    STATE_STARTED
    end note
    BLEStack <--] : Pairing rsp
      rnote over BLEStack
        Base on the IO capability, MITM, OOB setting of both devices,
        STACK needs to sort out whether this results to Just Work pairing.
      end note

    group if the pairing method (Just Work) can not fulfill Authentication MITM protection
    
      BLEStack -->] : End pairing
      BLEStack -> Gapbondmgr : GAP_AUTHENTICATION_\nCOMPLETE_EVENT
      Gapbondmgr -> BLEAppUtil : BLEAppUtil_pairStateCB
      BLEAppUtil -> Application: PairingPairStateHandler
      rnote over Application
        BLEAPPUTIL_PAIRING_STATE_COMPLETE
        SMP_PAIRING_FAILED_AUTH_REQ
      end note
    end 
  @enduml

For more information regarding which pairing mode results authenticated link, 
please refer :numref:`gappbondmgr_io_capabilities_parameters`

Just Works Pairing
""""""""""""""""""

Just Works pairing allows encryption without authentication 
and is vulnerable to MITM attacks. Just Works pairing can be LE
Legacy or LE Secure Connections pairing. The GAPBondMgr does not need any
additional input from the application for Just Works pairing.
Configure the GAPBondMgr for Just Works pairing as follows.

.. code-block:: c

  uint8_t mitm = FALSE;
  GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof (uint8_t), &mitm);

:numref:`gap_justworks_fig` describes the interaction between the GAPBondMgr and
the application for Just Works pairing. As shown, the application receives
a ``GAPBOND_PAIRING_STATE_STARTED`` event once the pairing request has been sent,
and a ``GAPBOND_PAIRING_STATE_COMPLETE`` event once the pairing process has been
completed. At this time, the link is encrypted.

.. _gap_justworks_fig:
.. uml::
  :caption: Just Works Pairing.
  :align: center

   @startuml

    participant Application
    participant BLEAppUtil as "BLE Application Framework"
    participant Gapbondmgr as "GAPBondMgr"
    participant BLEStack as "BLE Stack"

    BLEStack -> Gapbondmgr : GAP_LINK_ESTABLISHED_EVENT
    Gapbondmgr -> BLEStack : GAPBondMgr_LinkEst()
    Gapbondmgr -> BLEStack : GAP_Authenticate()
    BLEStack -->] : Pairing req
    Gapbondmgr -> BLEAppUtil : BLEAppUtil_pairStateCB
    BLEAppUtil -> Application : PairingPairStateHandler
    rnote over Application
    BLEAPPUTIL_PAIRING_
    STATE_STARTED
    end note

    BLEStack -->] : Encryption req
    BLEStack <--] : Encryption rsp
    BLEStack -> Gapbondmgr : GAP_AUTHENTICATION_\nCOMPLETE_EVENT
    Gapbondmgr -> BLEAppUtil : BLEAppUtil_pairStateCB
    BLEAppUtil -> Application: PairingPairStateHandler
    rnote over Application
      BLEAPPUTIL_PAIRING_
      STATE_COMPLETE
    end note
  @enduml

Passcode Entry
""""""""""""""

Passkey entry is a type of authenticated pairing that can prevent man in the
middle (MITM) attacks. It can be used with either LE Legacy pairing or Secure
Connections pairing. In this pairing method, one device displays a 6-digit
passcode, and the other device enters the passcode. As described in
:ref:`selection_of_pairing_method`, the IO capabilities decide which device
performs which role. The passcode callback registered with the GAPBondMgr when
it was started is used to enter or display the passcode. The following is an
example of initiating Passcode Entry pairing where the passcode is displayed.

1. Define passcode callback

.. _gapbondmgr_define_passcode_cb:
.. code-block:: c
  :caption: Define passcode callback.

    BLEAppUtil_EventHandler_t pairingPasscodeHandler =
    {
        .handlerType    = BLEAPPUTIL_PASSCODE_TYPE,
        .pEventHandler  = Pairing_passcodeHandler
    };

    /*********************************************************************
    * @fn      Pairing_passcodeHandler
    *
    * @brief   The purpose of this function is to handle passcode data
    *          that rise from the GAPBondMgr and were registered
    *          in @ref BLEAppUtil_RegisterGAPEvent
    *
    * @param   pMsgData - pointer to message data.
    *
    * @return  none
    */
    void Pairing_passcodeHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData)
    {
        BLEAppUtil_PasscodeData_t *pData = (BLEAppUtil_PasscodeData_t *)pMsgData;

        // Send passcode response
        GAPBondMgr_PasscodeRsp(pData->connHandle, SUCCESS, B_APP_DEFAULT_PASSCODE);
    }


2. Configure GAPBondMgr

.. code-block:: c
  :caption: Configure GAPBondMgr for MITM.

  uint8_t pairMode = GAPBOND_PAIRING_MODE_INITIATE;
  uint8_t mitm = TRUE;
  GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);
  GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm);

3. Process passcode callback and send the response to the stack.

.. _gapbondmgr_process_passcode:
.. code-block:: c
  :caption: Process passcode and send the response.

  //! BLE Default Passcode
  #define B_APP_DEFAULT_PASSCODE                    123456

  void Pairing_passcodeHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData)
  {
      BLEAppUtil_PasscodeData_t *pData = (BLEAppUtil_PasscodeData_t *)pMsgData;

    // Display passcode to user
    if(pData->uiOutputs)
    {
        Display_printf(dispHandle, dispIndex, 0, "#%5d    Passcode: %d", dispIndex, B_APP_DEFAULT_PASSCODE); dispIndex++;
    }

    // Send passcode response
    GAPBondMgr_PasscodeRsp(connHandle , SUCCESS, B_APP_DEFAULT_PASSCODE);
  }

Depending on the ``uiInputs`` and ``uiOutputs`` returned from the GAPBondMgr,
the passcode must either be entered or displayed. The passcode is
then sent to the GAPBondMgr using :ble_api:`GAPBondMgr_PasscodeRsp`, so that
pairing can continue. In this case, the password is statically set to 123456.
In a real product, the password will likely be randomly generated, and the
device must expose a way for the user to enter the passcode, then send it to the
GAPBondMgr using :ble_api:`GAPBondMgr_PasscodeRsp`. An example interaction
between the GAPBondMgr and the application is shown in
:numref:`gapbondmgr_exchange_passcode`.

.. _gapbondmgr_exchange_passcode:
.. uml::
  :caption: Interaction Between the GAPBondMgr and the Application when exchanging a passcode.
  :align: center

   @startuml
    participant Application
    participant BLEAppUtil as "BLE Application Framework"
    participant Gapbondmgr as "GAPBondMgr"
    participant BLEStack as "BLE Stack"

    BLEStack -> Gapbondmgr : GAP_LINK_ESTABLISHED_EVENT
    Gapbondmgr -> BLEStack : GAPBondMgr_LinkEst()
    Gapbondmgr -> BLEStack : GAP_Authenticate()
    BLEStack -->] : Pairing req

    Gapbondmgr -> BLEAppUtil : BLEAppUtil_pairStateCB
    rnote over "BLEAppUtil"
      BLEAPPUTIL_EVT_PAIRING_STATE_CB
    end note
    BLEAppUtil -> BLEAppUtil: BLEAppUtil_processPairStateMsg
    rnote over "Application"
      BLEAPPUTIL_PAIR_STATE_TYPE
    end note
    BLEAppUtil -> Application: PairingPairStateHandler
    rnote over "Application"
      BLEAPPUTIL_PAIRING_STATE_STARTED
    end note

    BLEStack -> Gapbondmgr : GAP_PASSKEY_NEEDED_\nEVENT
    Gapbondmgr -> BLEAppUtil: BLEAppUtil_passcodeCB
    BLEAppUtil -> Application: Pairing_passcodeHandler
    [--> Application : Enter or display\npasscode
    Application -> Gapbondmgr : GAPBondMgr_PasscodeRsp()
    Gapbondmgr -> BLEStack : GAP_PasscodeUpdate()
    BLEStack -->] : Encryption req
    BLEStack <--] : Encryption rsp
    BLEStack -> Gapbondmgr : GAP_AUTHENTICATION_\nCOMPLETE_EVENT
    Gapbondmgr -> BLEAppUtil: BLEAppUtil_pairStateCB
    BLEAppUtil -> Application : PairingPairStateHandler

    rnote over Application
    BLEAPPUTIL_PAIRING_
    STATE_COMPLETE
    end note
  @enduml


Numeric Comparison
""""""""""""""""""

Numeric comparison is a type of authenticated pairing that protects
from MITM attacks. It is only possible as a LE Secure Connections
pairing; not LE legacy. For numeric comparison pairing, both devices
display a 6-digit code. Each device must then indicate, through a
button press or some other Yes-No input, whether the codes match.
The passcode callback registered with the GAPBondMgr when it was
started is used to display the 6-digit code. The following is an
example of initiating Numeric Comparison pairing where the passcode
is displayed. The IO capabilities must be set appropriately to
select numeric comparison (that is, Display/Yes-No on both sides).

1. Define passcode callback to display code.

.. _gapbondmgr_define_passcode:
.. code-block:: c
  :caption: Define passcode callback to display code.
  :linenos:

  BLEAppUtil_EventHandler_t pairingPasscodeHandler =
  {
      .handlerType    = BLEAPPUTIL_PASSCODE_TYPE,
      .pEventHandler  = Pairing_passcodeHandler
  };

  /*********************************************************************
  * @fn      Pairing_passcodeHandler
  *
  * @brief   The purpose of this function is to handle passcode data
  *          that rise from the GAPBondMgr and were registered
  *          in @ref BLEAppUtil_RegisterGAPEvent
  *
  * @param   pMsgData - pointer to message data.
  *
  * @return  none
  */
  void Pairing_passcodeHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData)
  {
      BLEAppUtil_PasscodeData_t *pData = (BLEAppUtil_PasscodeData_t *)pMsgData;

      // Send passcode response
      GAPBondMgr_PasscodeRsp(pData->connHandle, SUCCESS, B_APP_DEFAULT_PASSCODE);
  }

2. Configure GAPBondMgr

.. _gapbondmgr_authenticate_configure:
.. code-block:: c
  :caption: Configure GAPBondMgr For LE Secure Connections + Authentication.
  :linenos:

  uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
  uint8_t scMode = GAPBOND_SECURE_CONNECTION_ONLY;
  uint8_t mitm = TRUE;
  uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_YES_NO;

  GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
  GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);
  GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm);
  GAPBondMgr_SetParameter(GAPBOND_SECURE_CONNECTION, sizeof(uint8_t), &scMode);

3. Process passcode callback and display code.

.. _gapbondmgr_authenticate_process:
.. code-block:: c
  :caption: Process passcode callback and display code.
  :linenos:

  void Pairing_passcodeHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData)
  {
      BLEAppUtil_PasscodeData_t *pData = (BLEAppUtil_PasscodeData_t *)pMsgData;

    // Display passcode to user
    if(pData->uiOutputs)
    {
        Display_printf(dispHandle, dispIndex, 0, "#%5d    Passcode: %d", dispIndex, B_APP_DEFAULT_PASSCODE); dispIndex++;
    }

    // Send passcode response
    GAPBondMgr_PasscodeRsp(connHandle , SUCCESS, B_APP_DEFAULT_PASSCODE);
  }

4. Accept Yes-No input from user and send response to GAPBondMgr.

.. _gapbondmgr_authenticate_accept:
.. code-block:: c
  :caption: Accept Yes-No input from user and send response to GAPBondMgr.
  :linenos:

  //example of "Yes" input via button press
  if (btn-pressed) 
  {
    //Send response to indicate that code matches
    GAPBondMgr_PasscodeRsp(connHandle, SUCCESS, TRUE);
    return;
  }

In this case, the third parameter of GAPBondMgr\_PasscodeRsp, which
usually accepts a passcode, is overloaded to send TRUE to the stack to
indicate that the codes match and to continue with pairing. The process of 
numeric comparison is illustrated in :numref:`numeric_comparison_fig`

.. _numeric_comparison_fig:
.. uml::
  :caption: Numeric Comparison.
  :align: center

   @startuml
    participant Application
    participant BLEAppUtil as "BLE Application Framework"
    participant Gapbondmgr as "GAPBondMgr"
    participant BLEStack as "BLE Stack"

    BLEStack -> Gapbondmgr : GAP_LINK_ESTABLISHED_EVENT
    Gapbondmgr -> BLEStack : GAPBondMgr_LinkEst()
    Gapbondmgr -> BLEStack : GAP_Authenticate()
    BLEStack -->] : Pairing req

    Gapbondmgr -> BLEAppUtil : BLEAppUtil_pairStateCB
    rnote over "BLEAppUtil"
      BLEAPPUTIL_EVT_PAIRING_STATE_CB
    end note
    BLEAppUtil -> BLEAppUtil: BLEAppUtil_processPairStateMsg
    rnote over "Application"
      BLEAPPUTIL_PAIR_STATE_TYPE
    end note
    BLEAppUtil -> Application: PairingPairStateHandler
    rnote over "Application"
      BLEAPPUTIL_PAIRING_STATE_STARTED
    end note

    BLEStack -> Gapbondmgr : GAP_PASSKEY_NEEDED_\nEVENT
    Gapbondmgr -> BLEAppUtil: BLEAppUtil_passcodeCB
    BLEAppUtil -> Application: Pairing_passcodeHandler
    [<-- Application : Display code
    [--> Application : Codes match

    Application -> Gapbondmgr : GAPBondMgr_PasscodeRsp()
    Gapbondmgr -> BLEStack : GAP_PasscodeUpdate()

    BLEStack -->] : Encryption req
    BLEStack <--] : Encryption rsp
    BLEStack -> Gapbondmgr : GAP_AUTHENTICATION_\nCOMPLETE_EVENT
    Gapbondmgr -> BLEAppUtil: BLEAppUtil_pairStateCB
    BLEAppUtil -> Application : PairingPairStateHandler

    rnote over Application
    BLEAPPUTIL_PAIRING_
    STATE_COMPLETE
    end note
  @enduml

Out of Band Pairing
"""""""""""""""""""

Out of Band is a feature that allows two devices to send authentication 
information over a communication channel that is out of the band of the device, 
e.g. by NFC. The purpose is to allow two devices with no input or output 
capabilities to create an authenticated pairing. This happens by sending three 
authentication parameters: device address, random number and confirm value.

The main purpose of OOB authentication is to protect against MITM attacks. The 
idea is to generate a key on one device. (This can be the initiator or the 
responder.) Then the OOB data is communicated to the other device by some other 
means of communication than Bluetooth LE protocol. 

The OOB data is generated at runtime. This can be done using elliptic-curve 
cryptography (ECC) or not. In this example we will use ECC to generate a key. To 
generate OOB data with a central application follow these 
steps:

1. Create gapBondOOBData_t variables, one for the local OOB data and one for the 
   remote device's data:

  .. code-block:: c

    // This is needed for the device that generates OOB data
    gapBondOOBData_t localOobData;
    // This is needed to store the OOB data this device receives
    gapBondOOBData_t remoteOobData;

2. Define the pair state callback

  .. code-block:: c
    :linenos:

    BLEAppUtil_EventHandler_t PairingPairStateHandler =
    {
        .handlerType    = BLEAPPUTIL_PAIR_STATE_TYPE,
        .pEventHandler  = Pairing_pairStateHandler,
        .eventMask      = BLEAPPUTIL_PAIRING_STATE_STARTED |
                          BLEAPPUTIL_PAIRING_STATE_COMPLETE |
                          BLEAPPUTIL_PAIRING_STATE_ENCRYPTED |
                          BLEAPPUTIL_PAIRING_STATE_BOND_SAVED |
                          BLEAPPUTIL_GENERATE_ECC_DONE //This modification is required below
    };

3. To generate OOB data with ECC keys, you need to call :ble_api:`GAPBondMgr_GenerateEccKeys` 
   prior to :ble_api:`GAPBondMgr_SCGetLocalOOBParameters`. 
   After calling :ble_api:`GAPBondMgr_GenerateEccKeys`, once the ECC keys are ready, 
   the |STACK| will send :c:type:`GAPBOND_GENERATE_ECC_DONE` 
   event to application and the event should be processed under pair state callback.

   Then application can call :ble_api:`GAPBondMgr_SCGetLocalOOBParameters` to obtain
   OOB data which is generated using the ECC Keys. The OOB data can then be extracted. 
   The example code below illustrate how to extract the OOB data.

   .. warning::
       The :ble_api:`GAPBondMgr_GenerateEccKeys` and :ble_api:`GAPBondMgr_SCGetLocalOOBParameters` 
       can be called either before and after the connection is established. 
       But **these need to be called before the pairing started**.
       In this case, we call both functions before the connection is established.

   .. code-block:: c
     :caption: **App_StackInitDoneHandler** Generate ECC keys.
     :linenos:
     
     // Generate ECC Keys
     GAPBondMgr_GenerateEccKeys();


   .. code-block:: c
     :caption: **app_pairing.c:: Pairing_pairStateHandler:: BLEAPPUTIL_GENERATE_ECC_DONE:** Generate OOB data after ECC keys are ready.
     :linenos:

     /*********************************************************************
     * @fn      Pairing_pairStateHandler
     *
     * @brief   The purpose of this function is to handle pairing state
     *          events that rise from the GAPBondMgr and were registered
     *          in @ref BLEAppUtil_RegisterGAPEvent
     *
     * @param   event - message event.
     * @param   pMsgData - pointer to message data.
     *
     * @return  none
     */
     void Pairing_pairStateHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData)
     {
         BLEAppUtil_PairStateData_t *pairStateMsg = (BLEAppUtil_PairStateData_t *)pMsgData;
         switch(event)
         {
           //.
           //.
           //.
             case BLEAPPUTIL_GENERATE_ECC_DONE:
             {
               if(pairStateMsg->status == SUCCESS)
               {
                 GAPBondMgr_SCGetLocalOOBParameters(&localOobData);
                 uint8_t i;
                 for (i = 0; i < KEYLEN; i++)
                 {
                     Display_printf(dispHandle, dispIndex, 0,"#%5d    OOB data confirm[%d]: %d", dispIndex, i, localOobData.confirm[i]); dispIndex++;
                     Display_printf(dispHandle, dispIndex, 0,"#%5d    OOB data rand[%d]: %d", dispIndex, i, localOobData.rand[i]); dispIndex++;
                 }
               }
               break;
             }
             default:
             {
                 break;
             }
         }
     }
  
   .. note::
      If :ble_api:`GAPBondMgr_GenerateEccKeys` is not called before :ble_api:`GAPBondMgr_SCGetLocalOOBParameters`,
      the OOB data will be generated without ECC.

4. After the OOB data is generated, the device needs to send it over to the peer device
   using any other medium for example NFC or wired solutions(E.g. UART, SPI, LIN, CAN...etc).
   The device which has received the OOB data (not the one that generated it) 
   should set the GAPBOND_OOB_ENABLED parameter to true. If both devices have 
   generated and shared their OOB data both should set the flag. In this case we 
   will only set the flag on the peripheral device.

   .. code-block:: c
   
     uint8_t oobEnabled = TRUE;
   
     GAPBondMgr_SetParameter(GAPBOND_OOB_ENABLED, sizeof(uint8_t), &oobEnabled);

5. Perform OOB communication, i.e. communicate the data in localOobData to the 
   responder device. For simplicity, in this example the central device will 
   display the data thus it can be hard coded on the peripheral device. 

  .. code-block:: c
    :caption: **App_StackInitDoneHandler** The OOB data is hard coded on the peripheral device.
    :linenos:

    uint8_t oobEnabled = TRUE;
    GAPBondMgr_SetParameter(GAPBOND_OOB_ENABLED, sizeof(uint8_t), &oobEnabled);
    remoteOobData.confirm[0] = 204;
    remoteOobData.confirm[1] = 29;
    remoteOobData.confirm[2] = 240;
    remoteOobData.confirm[3] = 154;
    remoteOobData.confirm[4] = 141;
    remoteOobData.confirm[5] = 40;
    remoteOobData.confirm[6] = 132;
    remoteOobData.confirm[7] = 41;
    remoteOobData.confirm[8] = 156;
    remoteOobData.confirm[9] = 106;
    remoteOobData.confirm[10] = 91;
    remoteOobData.confirm[11] = 230;
    remoteOobData.confirm[12] = 11;
    remoteOobData.confirm[13] = 88;
    remoteOobData.confirm[14] = 117;
    remoteOobData.confirm[15] = 104;
    remoteOobData.rand[0] = 56;
    remoteOobData.rand[1] = 242;
    remoteOobData.rand[2] = 38;
    remoteOobData.rand[3] = 152;
    remoteOobData.rand[4] = 189;
    remoteOobData.rand[5] = 78;
    remoteOobData.rand[6] = 164;
    remoteOobData.rand[7] = 36;
    remoteOobData.rand[8] = 153;
    remoteOobData.rand[9] = 82;
    remoteOobData.rand[10] = 167;
    remoteOobData.rand[11] = 190;
    remoteOobData.rand[12] = 140;
    remoteOobData.rand[13] = 235;
    remoteOobData.rand[14] = 207;
    remoteOobData.rand[15] = 93;
    GAPBondMgr_SCSetRemoteOOBParameters(&remoteOobData, 1);

The process of aforementioned OOB pairing example is 
illustrated in :numref:`oob_pairing_fig` For simplicity, the BLEAppUtil
framework layer is not shown. Remember to use the application defined callbacks
inside ``app_pairing.c`` as shown in the above sections.

.. _oob_pairing_fig:
.. uml::
  :caption: Out of Band Pairing
  :align: center

  @startuml

      participant cen_app as "Central\nApplication"
      participant cen_gapbondmgr as "Central\nGapbondmgr"
      participant cen_blestack as "Central\nBLE-Stack"

      participant per_blestack as "Peripheral\nBLE-Stack"
      participant per_gapbondmgr as "Peripheral\nGapbondmgr"
      participant per_app as "Peripheral\nApplication"

      cen_app -> cen_gapbondmgr : Generate ECC keys
      cen_gapbondmgr -> cen_blestack : Generate ECC keys

      ==ECC Keys are ready ==
      cen_gapbondmgr -> cen_app : Pairing state callback
      rnote over cen_app
        GAPBOND_GENERATE_
        ECC_DONE
      end note

      cen_app -> cen_gapbondmgr : Get local OOB parameters
      cen_gapbondmgr -> cen_blestack : Compute confirm and rand values
      cen_app -> per_app : Sending OOB data through either NFC or other wired protocol

      == Once peripheral receives OOB data ==
      per_app -> per_app : Set GAPBOND_OOB_ENABLED to true

      == After connection has established ==

      cen_gapbondmgr -> cen_blestack : GAPBondMgr_LinkEst()
      cen_gapbondmgr -> cen_blestack : GAP_Authenticate()
      cen_blestack --> per_blestack : Pairing req
      per_blestack --> cen_blestack : Pairing rsp
      cen_gapbondmgr -> cen_app : Pairing state callback

      rnote over cen_app
      GAPBOND_PAIRING_
      STATE_STARTED
      end note
      
      per_gapbondmgr -> per_app : Pairing state callback
      rnote over per_app
      GAPBOND_PAIRING_
      STATE_STARTED
      end note

      cen_blestack --> per_blestack : Encryption req
      cen_blestack <-- per_blestack : Encryption rsp
      cen_blestack -> cen_gapbondmgr : GAP_AUTHENTICATION_\nCOMPLETE_EVENT
      cen_gapbondmgr -> cen_app : Pairing state callback
      per_blestack -> per_gapbondmgr : GAP_AUTHENTICATION_\nCOMPLETE_EVENT
      per_gapbondmgr -> per_app : Pairing state callback
      rnote over cen_app
        GAPBOND_PAIRING_
        STATE_COMPLETE
      end note

      rnote over per_app
        GAPBOND_PAIRING_
        STATE_COMPLETE
      end note
  @enduml


GAPBondMgr Examples for Manipulating Bonding 
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

GAPBondMgr offers various functions to help users to:

#. Enable bonding
#. Extract bonding information
#. Import bonding information to NV

Enable Bonding
""""""""""""""

Bonding can enabled or disabled for any type of pairing through the
``GAPBOND_BONDING_ENABLED`` parameter, and occurs after the pairing
process is complete. To enable bonding, configure the GAPBondMgr as
follows:

.. code-block:: c

  uint8_t bonding = TRUE;
  GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding);

With bonding enabled, the GAPBondMgr stores the long-term key
transferred during the pairing process to NV. See :ref:`gapbondmgr_and_snv`
for more information. After this is completed, the application is notified
through the :c:type:`GAPBOND_PAIRING_STATE_COMPLETE` event.
:c:type:`GAPBOND_PAIRING_STATE_BOND_SAVED` is only passed to the application
pair state callback when initially connecting, pairing, and bonding. For
future connections to a bonded device, the security keys are loaded from
NV, thus skipping the pairing process. In this case, only
:c:type:`GAPBOND_PAIRING_STATE_BONDED` is passed to the application pair state
callback. This is illustrated in :numref:`gapbondmgr_example_bonding`

.. _gapbondmgr_example_bonding:
.. uml::
  :caption: GAPBondMgr Example With Bonding Enabled.
  :align: center

   @startuml

    participant Application
    participant Gapbondmgr as "GAPBondMgr"
    participant BLEStack as "BLE Stack"

    BLEStack -> Gapbondmgr : GAP_LINK_ESTABLISHED_EVENT
    Gapbondmgr -> BLEStack : GAPBondMgr_LinkEst()
    Gapbondmgr -> BLEStack : GAP_Authenticate
    BLEStack -->] : Pairing req
    Gapbondmgr -> Application : Pairing state callback
    rnote over Application
    GAPBOND_PAIRING_
    STATE_STARTED
    end note

    == This section will vary depending on the pairing type.\nSee above examples for more information. ==

    BLEStack -->] : Encryption req
    BLEStack <--] : Encryption rsp
    BLEStack -> Gapbondmgr : GAP_AUTHENTICATION_\nCOMPLETE_EVENT

    rnote over Gapbondmgr
    Save bond info in NV
    end note

    Gapbondmgr -> Application : Pairing state callback
    rnote over Application
    GAPBOND_PAIRING_
    STATE_COMPLETE
    end note

    rnote over Application
    GAPBOND_PAIRING_
    STATE_BOND_SAVED
    end note

    == Eventually the connection may be terminated and re-established. ==

    BLEStack -> Gapbondmgr : GAP_LINK_ESTABLISHED_EVENT
    Gapbondmgr -> BLEStack : GAPBondMgr_LinkEst()

    rnote over Gapbondmgr
    Read bond info from NV.
    end note

    Gapbondmgr -> BLEStack : GAP_Bond()
    BLEStack -->] : Encryption req
    BLEStack <--] : Encryption rsp
    BLEStack -> Gapbondmgr : GAP_BOND_COMPLETE_\nEVENT
    Gapbondmgr -> Application : Pairing state callback
    rnote over Application
    GAPBOND_PAIRING_
    STATE_BONDED
    end note


  @enduml 
.. _extract_bonding_information: 

Extract Bonding Information
"""""""""""""""""""""""""""

After bonding, the local device can extract the bonding information
saved in NV using :ble_api:`GapBondMgr_readBondFromNV`. To successfully 
extract the bonding information, the application can choose to read by index or by 
address. If read by using address, the application will need to input the
peer device's address type and the peer device's address. Those information
are provided from the |STACK| to the application when the link is established.

Following are the code snippet to extract the aforementioned parameters.

.. code-block:: c
    :caption: **app_peripheral.c:: BLEAPPUTIL_LINK_ESTABLISHED_EVENT** Extract peer device address and address type.
    :linenos:

    // LOCAL VARIABLES

    // Array to save peer device's address
    static uint8_t peerDeviceAddr[B_ADDR_LEN];
    
    // enum to store peer device's address type
    static GAP_Peer_Addr_Types_t pPeerAddrType;

    void Peripheral_GAPConnEventHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData)
    {
        switch(event)
        {
            case BLEAPPUTIL_LINK_ESTABLISHED_EVENT:
            {
                gapEstLinkReqEvent_t *gapEstMsg = (gapEstLinkReqEvent_t *)pMsgData;

                if(gapEstMsg->connRole == BLEAPPUTIL_PERIPHERAL_ROLE)
                {
                  //...
                  //...
                  if (gapEstMsg->hdr.status == SUCCESS)
                  {
                      // Copy Peer's addr
                      memcpy(peerDeviceAddr, gapEstMsg->devAddr, B_ADDR_LEN);

                      // Copy Peer's addrType
                      pPeerAddrType = (GAP_Peer_Addr_Types_t)(gapEstMsg->devAddrType & MASK_ADDRTYPE_ID);
                  }
                //...
                //...
                }
            }
            break;
          //...
          //...


Once extracted the needed parameters, we can call :ble_api:`GapBondMgr_readBondFromNV`
to extract the bonding information.

.. code-block:: c
    :caption: Extract bonding information
    :linenos:

    // Parameters needed for storing bonding information.
    static gapBondNvRecord_t* pSavedBondRec;
    static uint8_t pIdentifier;
    static uint8_t readMode;

    uint8_t readStatus = FAILURE;
    readStatus = GapBondMgr_readBondFromNV(readMode,
                                           pIdentifier,
                                           pPeerAddrType,
                                           pSavedBondRec);
    if (readStatus == SUCCESS)
    {
        // If read success, then export the data
        // Here we will print it out for later use.
        // For the print, we added the following defines
        // Please consider your own example and modify as needed
        Display_printf(dispHandle, dispIndex, 0, "#%5d    Peer Device Addr = [0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x];", dispIndex,
                        pSavedBondRec->pBondRec->addr[0],
                        pSavedBondRec->pBondRec->addr[1],
                        pSavedBondRec->pBondRec->addr[2],
                        pSavedBondRec->pBondRec->addr[3],
                        pSavedBondRec->pBondRec->addr[4],
                        pSavedBondRec->pBondRec->addr[5]); dispIndex++;

        Display_printf(dispHandle, dispIndex, 0, "#%5d    Peer Device AddrType = 0x%02x; stateFlag = 0x%02x;", dispIndex, pSavedBondRec->pBondRec->addrType, pSavedBondRec->pBondRec->stateFlags); dispIndex++;
        Display_printf(dispHandle, dispIndex, 0, "#%5d    Peer Device AddrType = 0x%02x; stateFlag = 0x%02x;", dispIndex, pSavedBondRec->pBondRec->addrType, pSavedBondRec->pBondRec->stateFlags); dispIndex++;
        Display_printf(dispHandle, dispIndex, 0, "#%5d    Local Device eDiv = 0x%02x; keySize = 0x%02x;", dispIndex, pSavedBondRec->pLocalLtk->div, pSavedBondRec->pLocalLtk->keySize); dispIndex++;
        Display_printf(dispHandle, dispIndex, 0, "#%5d    Peer Device SignCount = 0x%08x;", dispIndex, pSavedBondRec->pSignCount); dispIndex++;
    }
    break;



Import Bonding Information
""""""""""""""""""""""""""

The bond import feature is useful when for example, there are multiple 
Bluetooth LE devices as peripheral and one mobile phone as central, 
and you would like the phone to go through
the pairing process only once but is able to establish an encrypted link 
with any other peripheral nodes. 

The following content illustrates such usecase.

.. note :: 
    Here we assume device A and device B have the same secondary address.
    The device address can be configured by either using :ble_api:`HCI_EXT_SetBDADDRCmd`
    or through SysConfig tool --> Device Configuration --> Configure BLE Address.

After extracting bonding information from device A and transfer the information
to device B, we can then add those information into NV for device B by using
:ble_api:`gapBondMgrImportBond`.

.. code-block:: c
    :caption: **App_StackInitDoneHandler** Import bonding information
    :linenos:

    // Make sure the device B has the same BD address as device A
    // For example, if the device A's address is the following
    // Then use HCI_EXT_SetBDADDRCmd to change the device B's address
    uint8_t bondImportTestAddr[B_ADDR_LEN] = {0x12, 0x34, 0x45, 0xFE, 0xCA, 0x98};
    // Change device's address
    HCI_EXT_SetBDADDRCmd(bondImportTestAddr);

    // Import Bond here
    // Hardcode the bonding information from the printout
    pSavedBondRec.addr[0] = 0xf5;
    pSavedBondRec.addr[1] = 0xda;
    pSavedBondRec.addr[2] = 0x31;
    pSavedBondRec.addr[3] = 0xb0;
    pSavedBondRec.addr[4] = 0x6f;
    pSavedBondRec.addr[5] = 0x80;

    pSavedBondRec.addrType = PEER_ADDRTYPE_PUBLIC_OR_PUBLIC_ID;
    pSavedBondRec.stateFlags = 0x1c;

    pLocalLtk.LTK[0]= 0xa8;
    pLocalLtk.LTK[1]= 0x82;
    pLocalLtk.LTK[2]= 0x09;
    pLocalLtk.LTK[3]= 0x19;
    pLocalLtk.LTK[4]= 0x65;
    pLocalLtk.LTK[5]= 0x01;
    pLocalLtk.LTK[6]= 0xbc;
    pLocalLtk.LTK[7]= 0x58;
    pLocalLtk.LTK[8]= 0x49;
    pLocalLtk.LTK[9]= 0x28;
    pLocalLtk.LTK[10]= 0x31;
    pLocalLtk.LTK[11]= 0xac;
    pLocalLtk.LTK[12]= 0x6c;
    pLocalLtk.LTK[13]= 0x50;
    pLocalLtk.LTK[14]= 0x6f;
    pLocalLtk.LTK[15]= 0xd2;

    pLocalLtk.div = 0;
    pLocalLtk.keySize = 0x10;

    pPeerLtk.div = 0;
    pPeerLtk.keySize = 0;
    uint8_t i;
    for (i = 0; i < B_RANDOM_NUM_SIZE; i++)
    {
        pLocalLtk.rand[i] = 0;
        pPeerLtk.rand[i] = 0;
    }

    for (i = 0; i < KEYLEN; i++)
    {
        pPeerIRK[i] = 0;
        pPeerLtk.LTK[i] = 0;
    }

    pPeerSRK[0]= 0xab;
    pPeerSRK[1]= 0x31;
    pPeerSRK[2]= 0x78;
    pPeerSRK[3]= 0xe5;
    pPeerSRK[4]= 0x5a;
    pPeerSRK[5]= 0x33;
    pPeerSRK[6]= 0xf6;
    pPeerSRK[7]= 0xe9;
    pPeerSRK[8]= 0x1b;
    pPeerSRK[9]= 0x80;
    pPeerSRK[10]= 0xeb;
    pPeerSRK[11]= 0xae;
    pPeerSRK[12]= 0x25;
    pPeerSRK[13]= 0xd4;
    pPeerSRK[14]= 0x1d;
    pPeerSRK[15]= 0x19;

    pPeerSignCount = 0;
    charCfg.attrHandle = 0xffff;
    charCfg.value = 0xff;

    gapBondMgrImportBond(&pSavedBondRec,
                        &pLocalLtk,
                        &pPeerLtk,
                        pPeerIRK,
                        pPeerSRK,
                        pPeerSignCount,
                        &charCfg);

The bonding import can be called at anytime, but for the demo purpose,
we added the code under application_init. Therefore when device B connects
with the central device that has paired with device A, the link between 
device B and central will be encrypted without going through the
pairing process again.

:numref:`gapbondmgr_example_extract_import_bond` illustrates the whole process of
enable bonding, extract bonding information and import bonding
information.

.. _gapbondmgr_example_extract_import_bond:
.. uml::
  :caption: GAPBondMgr Example With Extracting and Importing Bonding Information.
  :align: center

  @startuml

    participant perA as "Peripheral A"
    participant cen as "Central"
    participant perB as "Peripheral B"

    cen --> perA : GAP_LINK_ESTABLISHED_EVENT
    cen --> perA : Pairing Req
    perA --> cen : Pairing Rsp

    == Depending on the combination of pairing req and pairing rsp, a type of pairing\nwill be selected. See above examples for more information. ==

    cen -> cen : Pairing state callback
    rnote over cen
      GAPBOND_PAIRING_
      STATE_STARTED
    end note

    perA -> perA : Pairing state callback
    rnote over perA
      GAPBOND_PAIRING_
      STATE_STARTED
    end note

    cen --> perA : Encryption req
    perA --> cen : Encryption rsp

    ...
    ... Both central and peripheral A will save the bond info in NV ...
    ...

    
    rnote over cen
      GAPBOND_PAIRING_
      STATE_COMPLETE
    end note

    rnote over perA
      GAPBOND_PAIRING_
      STATE_COMPLETE
    end note

    rnote over cen
      GAPBOND_PAIRING_
      STATE_BOND_SAVED
    end note

    rnote over perA
      GAPBOND_PAIRING_
      STATE_BOND_SAVED
    end note

    perA -> perA : Extract bonding information\nusing GapBondMgr_readBondFromNV

    ...
    ... Central can now terminate the link with Peripheral A ...
    ...
    
    perA -> perB : Transfer the bonding information through other wired/wireless protocols.\nFor example: LIN, CAN or SPI...etc

    perB -> perB : Save the bonding information to NV \nby using gapBondMgrImportBond
    cen --> perB : GAP_LINK_ESTABLISHED_EVENT

    cen --> perB : Encryption req
    perB --> cen : Encryption rsp

    ...
    ... Now the central and Peripheral B has an encrypted link \nwithout going through pairing process ...
    ...

  @enduml


.. _gapbondmgr_and_snv:

GAPBondMgr and NV
^^^^^^^^^^^^^^^^^

The following components comprise one bonding entry:

1. **Bond Record:** this consists of the peer's address, address type,
privacy reconnection address, and state flags. This comprises 8
bytes and is defined as such:

.. code-block:: c

    // Structure of NV data for the connected device's address information
    typedef struct
    {
      /**
      * Peer's address
      *
      * If identity information exists for this bond, this will be an
      * identity address
      */
      uint8_t               addr[B_ADDR_LEN];
      /**
      * Peer's address type
      */
      GAP_Peer_Addr_Types_t addrType;
      /**
      * State flags of bond
      *
      * @ref GAP_BONDED_STATE_FLAGS
      */
      uint8_t               stateFlags;
    } gapBondRec_t;

2. **Client Characteristic Configurations (CCC):** the amount of CCCs stored
in each entry are set by the ``GAP_CHAR_CFG_MAX`` define. This is
set to 4 by default. Each CCC is comprised of 4-bytes and is
defined as follows:

.. code-block:: c

  // Structure of NV data for the connected device's characteristic configuration
  typedef struct
  {
    uint16 attrHandle;  // attribute handle
    uint8  value;       // attribute value for this device
  } gapBondCharCfg_t;

3. **Local Long Term Key (LTK) info:** this stores the local device's
encryption information. This comprises 28 bytes and is composed
as such:

.. code-block:: c

  typedef struct
  {
    uint8   LTK[KEYLEN];              // Long Term Key (LTK)
    uint16  div;  //lint -e754        // LTK eDiv
    uint8   rand[B_RANDOM_NUM_SIZE];  // LTK random number
    uint8   keySize;                  // LTK key size
  } gapBondLTK_t;

4. **Peer Device Long Term Key Info:** this stores the peer
device's encryption information. This is also a gapBondLTK\_t and
comprises 28 bytes.

5. **Peer Device Identity Resolving Key (IRK):** this stores the :term:`IRK`
generated during pairing. This is a 16-byte array.

6. **Peer Device Connection Signature Resolving Key (CSRK):** 
this stores the :term:`CSRK` generated during pairing. This is a 16-byte array.

7. **Peer Device Sign counter:** this stores the sign counter generated
during pairing. This is a 4-byte word.
