Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to configure a passkey for central and for peripheral.

Hi there,

I cannot find a good example of one central and one peripheral, where they use a passkey between them, with one of them, the peripheral, is where the user type the pass key, and the central is the one that displays the passkey to be typed.

The documentation seems to be a bit hidden too, if I would try to write it from scratch.

I am using nRF52832, s132.

Regards

Parents
  • Hi.

    For the peripheral side, you can look at the Glucose Application example (examples\ble_peripheral\ble_app_gls).

    For the central side, you have to do some modifications for a central example, for example the  GATT Service Server Example Application (examples\ble_central\ble_app_gatts)

    Here is a diff file with the changes you have to make to that example:

    diff --git a/examples/ble_central/ble_app_gatts/main.c b/examples/ble_central/ble_app_gatts/main.c
    index 7d5022d..34e769c 100644
    --- a/examples/ble_central/ble_app_gatts/main.c
    +++ b/examples/ble_central/ble_app_gatts/main.c
    @@ -85,10 +85,10 @@
     #define APP_SOC_OBSERVER_PRIO     1                                /**< Applications' SoC observer priority. You shouldn't need to modify this value. */
     
     #define SEC_PARAM_BOND            1                                /**< Perform bonding. */
    -#define SEC_PARAM_MITM            0                                /**< Man In The Middle protection not required. */
    +#define SEC_PARAM_MITM            1                                /**< Man In The Middle protection not required. */
     #define SEC_PARAM_LESC            0                                /**< LE Secure Connections not enabled. */
     #define SEC_PARAM_KEYPRESS        0                                /**< Keypress notifications not enabled. */
    -#define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_NONE             /**< No I/O capabilities. */
    +#define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_KEYBOARD_ONLY    /**< No I/O capabilities. */
     #define SEC_PARAM_OOB             0                                /**< Out Of Band data not available. */
     #define SEC_PARAM_MIN_KEY_SIZE    7                                /**< Minimum encryption key size. */
     #define SEC_PARAM_MAX_KEY_SIZE    16                               /**< Maximum encryption key size. */
    @@ -293,6 +293,19 @@ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
                                                  BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                 APP_ERROR_CHECK(err_code);
             } break;
    +        
    +        case BLE_GAP_EVT_AUTH_KEY_REQUEST:
    +        {
    +          
    +          NRF_LOG_DEBUG("GAP Passkey request.");
    +          uint8_t passkey[] = "000000"; 
    +          if (p_gap_evt->params.auth_key_request.key_type == BLE_GAP_AUTH_KEY_TYPE_PASSKEY)
    +          {
    +              err_code = sd_ble_gap_auth_key_reply(p_gap_evt->conn_handle, BLE_GAP_AUTH_KEY_TYPE_PASSKEY, passkey);
    +              APP_ERROR_CHECK(err_code);
    +          }
    +          
    +        } break;
     
             default:
                 break;
    diff --git a/examples/ble_central/ble_app_gatts/pca10040/s132/config/sdk_config.h b/examples/ble_central/ble_app_gatts/pca10040/s132/config/sdk_config.h
    index c48d10b..96949d4 100644
    --- a/examples/ble_central/ble_app_gatts/pca10040/s132/config/sdk_config.h
    +++ b/examples/ble_central/ble_app_gatts/pca10040/s132/config/sdk_config.h
    @@ -7434,7 +7434,7 @@
     // <e> NRF_LOG_BACKEND_RTT_ENABLED - nrf_log_backend_rtt - Log RTT backend
     //==========================================================
     #ifndef NRF_LOG_BACKEND_RTT_ENABLED
    -#define NRF_LOG_BACKEND_RTT_ENABLED 0
    +#define NRF_LOG_BACKEND_RTT_ENABLED 1
     #endif
     // <o> NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE - Size of buffer for partially processed strings. 
     // <i> Size of the buffer is a trade-off between RAM usage and processing.
    @@ -7467,7 +7467,7 @@
     // <e> NRF_LOG_BACKEND_UART_ENABLED - nrf_log_backend_uart - Log UART backend
     //==========================================================
     #ifndef NRF_LOG_BACKEND_UART_ENABLED
    -#define NRF_LOG_BACKEND_UART_ENABLED 1
    +#define NRF_LOG_BACKEND_UART_ENABLED 0
     #endif
     // <o> NRF_LOG_BACKEND_UART_TX_PIN - UART TX pin 
     #ifndef NRF_LOG_BACKEND_UART_TX_PIN
    diff --git a/examples/ble_peripheral/ble_app_gatts_c/main.c b/examples/ble_peripheral/ble_app_gatts_c/main.c
    index ebd2823..74a8a9c 100644
    --- a/examples/ble_peripheral/ble_app_gatts_c/main.c
    +++ b/examples/ble_peripheral/ble_app_gatts_c/main.c
    @@ -147,6 +147,7 @@ static void gap_params_init(void)
         ret_code_t              err_code;
         ble_gap_conn_params_t   gap_conn_params;
         ble_gap_conn_sec_mode_t sec_mode;
    +    ble_opt_t               ble_opt;
     
         BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
     
    @@ -164,6 +165,11 @@ static void gap_params_init(void)
     
         err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
         APP_ERROR_CHECK(err_code);
    +
    +    ble_opt.gap_opt.passkey.p_passkey = "000000";
    +
    +    err_code = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &ble_opt);
    +    APP_ERROR_CHECK(err_code);
     }
     
     
    diff --git a/examples/ble_peripheral/ble_app_gatts_c/pca10040/s132/config/sdk_config.h b/examples/ble_peripheral/ble_app_gatts_c/pca10040/s132/config/sdk_config.h
    index 93b1b15..efe405d 100644
    --- a/examples/ble_peripheral/ble_app_gatts_c/pca10040/s132/config/sdk_config.h
    +++ b/examples/ble_peripheral/ble_app_gatts_c/pca10040/s132/config/sdk_config.h
    @@ -90,7 +90,7 @@
     // <4=> BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY 
     
     #ifndef SEC_PARAM_IO_CAPABILITIES
    -#define SEC_PARAM_IO_CAPABILITIES 3
    +#define SEC_PARAM_IO_CAPABILITIES 0
     #endif
     
     // <o> SEC_PARAM_MAX_KEY_SIZE - Maximum encryption key size in octets between SEC_PARAM_MIN_KEY_SIZE and 16.  <0-16> 
    @@ -111,7 +111,7 @@
      
     
     #ifndef SEC_PARAM_MITM
    -#define SEC_PARAM_MITM 0
    +#define SEC_PARAM_MITM 1
     #endif
     
     // <q> SEC_PARAM_OOB  - Out Of Band data not available or not
    @@ -7419,7 +7419,7 @@
     // <e> NRF_LOG_BACKEND_RTT_ENABLED - nrf_log_backend_rtt - Log RTT backend
     //==========================================================
     #ifndef NRF_LOG_BACKEND_RTT_ENABLED
    -#define NRF_LOG_BACKEND_RTT_ENABLED 0
    +#define NRF_LOG_BACKEND_RTT_ENABLED 1
     #endif
     // <o> NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE - Size of buffer for partially processed strings. 
     // <i> Size of the buffer is a trade-off between RAM usage and processing.
    @@ -7452,7 +7452,7 @@
     // <e> NRF_LOG_BACKEND_UART_ENABLED - nrf_log_backend_uart - Log UART backend
     //==========================================================
     #ifndef NRF_LOG_BACKEND_UART_ENABLED
    -#define NRF_LOG_BACKEND_UART_ENABLED 1
    +#define NRF_LOG_BACKEND_UART_ENABLED 0
     #endif
     // <o> NRF_LOG_BACKEND_UART_TX_PIN - UART TX pin 
     #ifndef NRF_LOG_BACKEND_UART_TX_PIN
    

    Best regards,

    Andreas

  • Hi Andreas,

    Thanks for the information.

    I have yet a few questions...

    Right, so if I understand your diff right, the peripheral is the one that has a preconfigured passkey, and the central is the one that is asked about it.

    Can it be the other way around at all, or does it always work like that?

    Looking at the only example that seems to use XXX_WITH_MITM is the multirole in central and peripheral. The interactive does it too, but for an autonomous example, the multirole seems the only one.

    Isn't the MITM needed for a passkey, or the passkey can be used without it but then it is just a way to ensure you pair to the right device, but no MITM protection?

    I believe I have seen some examples in the forum of explicit checks for the mitm config in the peer manager SEC_SUCCEEDED event, disconnecting if it is not set.

    Is that the right way to enforce the MITM usage, or does the PM ensure that some other way?

    If I have a peripheral that supports MITM and one that does not, can they both be paired to a central?

    I see that the multirole seems to run ble_lesc_init, which seesm to be required for MITM.... should that be run in both central and peripheral?

    Regards

  • Hi.

    David Fernandez said:
    Right, so if I understand your diff right, the peripheral is the one that has a preconfigured passkey, and the central is the one that is asked about it.

     Sorry about this, I see that the diff file now might be a bit confusing

    The central has a "preconfigured passkey", on line 27:

    "+          uint8_t passkey[] = "000000"; "

    From line 60:

    "diff --git a/examples/ble_peripheral/ble_app_gatts_c/main.c b/examples/ble_peripheral/ble_app_gatts_c/main.c"

    The peripheral side and a hardcoded passkey is set up, note that this is another project (ble_app_gls lets you write the passkey as an input on the peripheral side).

    David Fernandez said:
    Isn't the MITM needed for a passkey, or the passkey can be used without it but then it is just a way to ensure you pair to the right device, but no MITM protection?

     Passkey is a form of MITM protection. But only using passkey is not safe, as the passkey has no encryption when it is transmitted over the air, and for that you need LESC.

     

    David Fernandez said:

    I believe I have seen some examples in the forum of explicit checks for the mitm config in the peer manager SEC_SUCCEEDED event, disconnecting if it is not set.

    Is that the right way to enforce the MITM usage, or does the PM ensure that some other way?

    The Peer manager is created and used for handling pairing and bonding, so you can use it if you like. They should do the same job, but it might be less work for you using the Peer manager.

    David Fernandez said:
    If I have a peripheral that supports MITM and one that does not, can they both be paired to a central?

     Yes, they can. You can have support for MITM and not demand that each device that connects should use MITM.

     

    David Fernandez said:
    I see that the multirole seems to run ble_lesc_init, which seesm to be required for MITM.... should that be run in both central and peripheral?

    Yes. in the multirole example this is done through pm_init() -> sm_init() --> nrf_ble_lesc_init()

    Best regards,

    Andreas

Reply
  • Hi.

    David Fernandez said:
    Right, so if I understand your diff right, the peripheral is the one that has a preconfigured passkey, and the central is the one that is asked about it.

     Sorry about this, I see that the diff file now might be a bit confusing

    The central has a "preconfigured passkey", on line 27:

    "+          uint8_t passkey[] = "000000"; "

    From line 60:

    "diff --git a/examples/ble_peripheral/ble_app_gatts_c/main.c b/examples/ble_peripheral/ble_app_gatts_c/main.c"

    The peripheral side and a hardcoded passkey is set up, note that this is another project (ble_app_gls lets you write the passkey as an input on the peripheral side).

    David Fernandez said:
    Isn't the MITM needed for a passkey, or the passkey can be used without it but then it is just a way to ensure you pair to the right device, but no MITM protection?

     Passkey is a form of MITM protection. But only using passkey is not safe, as the passkey has no encryption when it is transmitted over the air, and for that you need LESC.

     

    David Fernandez said:

    I believe I have seen some examples in the forum of explicit checks for the mitm config in the peer manager SEC_SUCCEEDED event, disconnecting if it is not set.

    Is that the right way to enforce the MITM usage, or does the PM ensure that some other way?

    The Peer manager is created and used for handling pairing and bonding, so you can use it if you like. They should do the same job, but it might be less work for you using the Peer manager.

    David Fernandez said:
    If I have a peripheral that supports MITM and one that does not, can they both be paired to a central?

     Yes, they can. You can have support for MITM and not demand that each device that connects should use MITM.

     

    David Fernandez said:
    I see that the multirole seems to run ble_lesc_init, which seesm to be required for MITM.... should that be run in both central and peripheral?

    Yes. in the multirole example this is done through pm_init() -> sm_init() --> nrf_ble_lesc_init()

    Best regards,

    Andreas

Children
Related