This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Static Passkey, using and testing

Hi,

I am using nRF51822, S130, SDK12.

Now trying to add a level of security with a static passkey, I have done the following adaptation to my code -

Added to void gap_params_init(void)

uint8_t passkey[] = STATIC_PASSKEY;
m_static_pin_option.gap_opt.passkey.p_passkey = passkey; //gap_opt
err_code = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &m_static_pin_option);
APP_ERROR_CHECK(err_code);

#define STATIC_PASSKEY "123456" /**< Static pin. */

#define SEC_PARAM_BOND 1 /**< Perform bonding. */
#define SEC_PARAM_MITM 0 /**< 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_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. */

Further adjustments to code described below..

I am using nRF Connect on my mobile phone and pygatt on my PC (using BlueGiga) to test my application, 

So far strangely pygatt works just fine although I have not configured the PASSKEY on my pygatt application and also, as far as I read it does not support security,

The nRF Connect however fails to connect. 

I would like to know 

1. If I have configured the softdevice correctly to support static passkey, and if not , what should I do - or - where can I find example for my SDK, softdevice configuration

2. Why is the pygatt working and the nRF Connect not

3. where in the nRF Connect mobile app does one configure the static passkey

4. Is there another recommended to test my secure application with.

Thanks!

------------------------------------------------------

Other adaptation to my code -

Added to main() the command:

peer_manager_init(erase_bonds);

Added to main.c the following routines

/**@brief Function for starting advertising.
*/
static void advertising_start(void)
{
uint32_t err_code = ble_advertising_start(BLE_ADV_MODE_FAST);

APP_ERROR_CHECK(err_code);
}

/**@brief Function for handling Peer Manager events.
*
* @param[in] p_evt Peer Manager event.
*/
static void pm_evt_handler(pm_evt_t const * p_evt)
{
ret_code_t err_code;

switch (p_evt->evt_id)
{
case PM_EVT_BONDED_PEER_CONNECTED:
{
app_trace_log("Connected to a previously bonded device.\r\n");
} break;

case PM_EVT_CONN_SEC_SUCCEEDED:
{
app_trace_log("Connection secured. Role: %d. conn_handle: %d, Procedure: %d\r\n",
ble_conn_state_role(p_evt->conn_handle),
p_evt->conn_handle,
p_evt->params.conn_sec_succeeded.procedure);
} break;

case PM_EVT_CONN_SEC_FAILED:
{
/* Often, when securing fails, it shouldn't be restarted, for security reasons.
* Other times, it can be restarted directly.
* Sometimes it can be restarted, but only after changing some Security Parameters.
* Sometimes, it cannot be restarted until the link is disconnected and reconnected.
* Sometimes it is impossible, to secure the link, or the peer device does not support it.
* How to handle this error is highly application dependent. */
} break;

case PM_EVT_CONN_SEC_CONFIG_REQ:
{
// Reject pairing request from an already bonded peer.
pm_conn_sec_config_t conn_sec_config = {.allow_repairing = false};
pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
} break;

case PM_EVT_STORAGE_FULL:
{
// Run garbage collection on the flash.
err_code = fds_gc();
if (err_code == FDS_ERR_BUSY || err_code == FDS_ERR_NO_SPACE_IN_QUEUES)
{
// Retry.
}
else
{
APP_ERROR_CHECK(err_code);
}
} break;

case PM_EVT_PEERS_DELETE_SUCCEEDED:
{
advertising_start();
} break;

case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED:
{
// The local database has likely changed, send service changed indications.
pm_local_database_has_changed();
} break;

case PM_EVT_PEER_DATA_UPDATE_FAILED:
{
// Assert.
APP_ERROR_CHECK(p_evt->params.peer_data_update_failed.error);
} break;

case PM_EVT_PEER_DELETE_FAILED:
{
// Assert.
APP_ERROR_CHECK(p_evt->params.peer_delete_failed.error);
} break;

case PM_EVT_PEERS_DELETE_FAILED:
{
// Assert.
APP_ERROR_CHECK(p_evt->params.peers_delete_failed_evt.error);
} break;

case PM_EVT_ERROR_UNEXPECTED:
{
// Assert.
APP_ERROR_CHECK(p_evt->params.error_unexpected.error);
} break;

case PM_EVT_CONN_SEC_START:
case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
case PM_EVT_PEER_DELETE_SUCCEEDED:
case PM_EVT_LOCAL_DB_CACHE_APPLIED:
case PM_EVT_SERVICE_CHANGED_IND_SENT:
case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED:
default:
break;
}
}


/**@brief Function for the Peer Manager initialization.
*
* @param[in] erase_bonds Indicates whether bonding information should be cleared from
* persistent storage during initialization of the Peer Manager.
*/
static void peer_manager_init(bool erase_bonds)
{
ble_gap_sec_params_t sec_param;
ret_code_t err_code;

err_code = pm_init();
APP_ERROR_CHECK(err_code);

if (erase_bonds)
{
err_code = pm_peers_delete();
APP_ERROR_CHECK(err_code);
}

memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));

// Security parameters to be used for all security procedures.
sec_param.bond = SEC_PARAM_BOND;
sec_param.mitm = SEC_PARAM_MITM;
sec_param.lesc = SEC_PARAM_LESC;
sec_param.keypress = SEC_PARAM_KEYPRESS;
sec_param.io_caps = SEC_PARAM_IO_CAPABILITIES;
sec_param.oob = SEC_PARAM_OOB;
sec_param.min_key_size = SEC_PARAM_MIN_KEY_SIZE;
sec_param.max_key_size = SEC_PARAM_MAX_KEY_SIZE;
sec_param.kdist_own.enc = 1;
sec_param.kdist_own.id = 1;
sec_param.kdist_peer.enc = 1;
sec_param.kdist_peer.id = 1;

err_code = pm_sec_params_set(&sec_param);
APP_ERROR_CHECK(err_code);

err_code = pm_register(pm_evt_handler);
APP_ERROR_CHECK(err_code);
}

Parents
  • Hi,

    I suggest that you try with this with the Glucose Application example first, then use that as a reference on what settings to use. SEC_PARAM_MITM must be set to '1' and  SEC_PARAM_IO_CAPABILITIES  must say you have display capabilities. 

    Note that these security parameters define the security capabilities of the device and not the security requirements/level which is set individually for each characteristic. 

  • Thank you Vidar for your answer

    As far as I understood from the code, Glucose Application uses BLE_GAP_OPT_PRIVACY, not BLE_GAP_OPT_PASSKEY, Is that example relevant to using static passkey?

    I don't have display capabilities or keyboard on the peripheral I am developing for, I am connecting a peripheral to a mobile device (first as I said will try to use nRF Connect).

    Will a static passkey not ensure encryption for all characteristics?

    Thanks !

  • Thanks Vidar

    Do you have any idea why would advertising stop after the fast advertising timeout, it never goes into slow advertising in the GLS example, it just stops.

    Thanks again for your help

  • Hi, 

    This example does not implement slow advertising. Instead, it attempts to enter System OFF mode (deep sleep) when the fast advertising times out, see  BLE_ADV_EVT_IDLE event in on_adv_evt(). I say attempt because it can't enter deep sleep if you are debugging the app while it times out. 

  • Hi Vidar, 

    do you mean that 

            case BLE_ADV_EVT_IDLE:
                sleep_mode_enter();
                break; // BLE_ADV_EVT_IDLE

    I changed the entire routine to 

    static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
    {
        switch (ble_adv_evt)
        {
            case BLE_ADV_EVT_FAST:
    
                break;
            case BLE_ADV_EVT_SLOW:
    
                break;                
            default:
                break;
        }
    }

    as for the advertising_init() I think I added a slow advertisement configuraiton

    static void advertising_init(void)
    {
        uint32_t               err_code;
        ble_advdata_t          advdata;
        ble_adv_modes_config_t options;
    
        // Build and set advertising data.
        memset(&advdata, 0, sizeof(advdata));
    
        advdata.name_type               = BLE_ADVDATA_FULL_NAME;
        advdata.include_appearance      = true;
        advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;;
        advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        advdata.uuids_complete.p_uuids  = m_adv_uuids;
    
        memset(&options, 0, sizeof(options));
        options.ble_adv_fast_enabled  = true;
        options.ble_adv_fast_interval = APP_ADV_INTERVAL;
        options.ble_adv_fast_timeout  = APP_ADV_TIMEOUT_IN_SECONDS;
    
        options.ble_adv_slow_enabled = true; //BLE_ADV_SLOW_ENABLED; 
        options.ble_adv_slow_interval = MSEC_TO_UNITS(1475, UNIT_0_625_MS);
        options.ble_adv_slow_timeout = 0;	
    	
        err_code = ble_advertising_init(&advdata, NULL, &options, on_adv_evt, NULL);
        APP_ERROR_CHECK(err_code);
    }

    Still the effect is the same, after timeout advertisement stops. 

    Any more directions?

    Thanks again

  • Hi, 

    The slow advertiser will not start because you have disabled the advertiser timeout while using the "limited discovery mode". The max. advertisement duration for this mode is 180 seconds (BLE_GAP_ADV_TIMEOUT_LIMITED_MAX).

    It should work if you change the BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE flag to BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE. 

Reply Children
No Data
Related