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

encryption and decryption of advertising data

Hii nordic;

I need to encrypt and decrypt my advertising data i.e;UUID,Major,Minor,etc.;  of my nrf52832

So it cannot be seen by third parties

my sdk version is 15.2 and softdevice is 132

Parents
  •  I have been thinking some more on the solution I proposed in my previous reply and from a security perspective I think it would be better to include the nounce in the advertisement packet and then keep the counter values static, i.e. 0x0000 and 0x0001. 

    I am afraid that we do not have any example code that does this in our SDK out-of-the-box. You should be able to modify the existing code I have provided for the peripheral side, you would just have to modify it to place the nounce in the scan response packet as manufacturing specifc data. 

    On the central side you will have to add the handling of  the NRF_BLE_SCAN_EVT_SCAN_REQ_REPORT case in the scan_evt_handler() function that is set as the scan event handler function in scan_init() in main.c. There you will have to extract the nounce and then store both the nounce and the address of the sender. You will need this to determine which nounce that should be used to decrypt which advertisment message. 

    Best regards

    Bjørn

  • bjorn-spockeli:

    I think i had done the same that you told in the above code then also i am not getting the values 

    Please help me to write that code

Reply Children
  • You can start by modifying the BLE peripheral code so that the nounce that you generate is placed in the Scan response packet. This is done by populating the ble_advdata_t srdata struct in the ble_advertising_init_t init struct in advertising_init() in main.c

    /**@brief Function for initializing the Advertising functionality.
     */
    static void advertising_init(void)
    {
        ret_code_t             err_code;
        ble_advertising_init_t init;
    
        memset(&init, 0, sizeof(init));
    
        init.advdata.name_type               = BLE_ADVDATA_FULL_NAME;
        init.advdata.include_appearance      = true;
        init.advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
        init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        init.advdata.uuids_complete.p_uuids  = m_adv_uuids;
        
        // Populate Scan Response Data struct
        ble_advdata_manuf_data_t sr_advdata;
    
        memset(&sr_advdata,0, sizeof(sr_advdata));
        sr_advdata.data.p_data = nounce;
        sr_advdata.data.size = sizeof(nounce);
        sr_advdata.company_identifier = 0x0059; // Nordic Semiconductor Company ID, should be replaced with own company ID. 
    
        init.srdata.p_manuf_specific_data = &sr_advdata;
    
    
        init.config.ble_adv_fast_enabled  = true;
        init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
        init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
    
        init.evt_handler = on_adv_evt;
    
        err_code = ble_advertising_init(&m_advertising, &init);
        APP_ERROR_CHECK(err_code);
    
        ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    }

  • bjorn-spockeli:

    yes its done i had added nounce to the scan response.

    now what is the code that i should add in the central side i.e., Scanning side

    this code is for peripheral side usinf ble_app_proximity_beacon:

    encryption peripheral.rar

    decryption central.rar

    this is code i wrote using ble_app_uart_c example for decryption.Please check i am getting garbage values not getting the encrypted values

  • I did not see any reference any code that added the nounce to the scan response data in the ble_app_proximity_beacon example that was attached. I added this the following way.

    static void advertising_init(void)
    {
        uint32_t      err_code;
        ble_advdata_t advdata;
        ble_advdata_t scandata;
        uint8_t       flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    
        ble_advdata_manuf_data_t manuf_specific_data;
    
        manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
    
    #if defined(USE_UICR_FOR_MAJ_MIN_VALUES)
    
        uint16_t major_value = ((*(uint32_t *)UICR_ADDRESS) & 0xFFFF0000) >> 16;
        uint16_t minor_value = ((*(uint32_t *)UICR_ADDRESS) & 0x0000FFFF);
    
        uint8_t index = MAJ_VAL_OFFSET_IN_BEACON_INFO;
    
        m_beacon_info[index++] = MSB_16(major_value);
        m_beacon_info[index++] = LSB_16(major_value);
    
        m_beacon_info[index++] = MSB_16(minor_value);
        m_beacon_info[index++] = LSB_16(minor_value);
    #endif
    
        manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info;
        manuf_specific_data.data.size   = APP_BEACON_INFO_LENGTH;
    
        m_beacon_info[18] = 0x00;
        m_beacon_info[19] = 100; // init battery
     
        m_beacon_info[20] = 0x00;
        m_beacon_info[21] = 0x00;
    
    
        memset(&advdata, 0, sizeof(advdata));
        advdata.flags                 = flags;
        advdata.p_manuf_specific_data = &manuf_specific_data;
    
    
    
        memset(&m_adv_params, 0, sizeof(m_adv_params));
    
        m_adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
        m_adv_params.p_peer_addr     = NULL;    
        m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
        m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
        m_adv_params.duration        = 0;       
    
        err_code = ble_advdata_encode(&advdata, m_adv_data_buffer_1.adv_data.p_data, &m_adv_data_buffer_1.adv_data.len);
        APP_ERROR_CHECK(err_code);
    
        ble_advdata_manuf_data_t sr_manuf_data;
    
        memset(&sr_manuf_data,0, sizeof(sr_manuf_data));
    
        sr_manuf_data.data.p_data = nounce;
        sr_manuf_data.data.size = sizeof(nounce);
        sr_manuf_data.company_identifier = APP_COMPANY_IDENTIFIER;
    
        memset(&scandata, 0, sizeof(scandata));
    
        //scandata.name_type             = BLE_ADVDATA_FULL_NAME;
        scandata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        scandata.uuids_complete.p_uuids  = m_adv_uuids;
        scandata.p_manuf_specific_data = &sr_manuf_data;
    
        ble_gap_addr_t gap_address;
        gap_address.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
        memcpy(&gap_address.addr, "\xbb\xaa\xcc\xbb\xaa\xAC", sizeof(gap_address.addr));
        err_code = sd_ble_gap_addr_set(&gap_address);
        APP_ERROR_CHECK(err_code);
    
        err_code = ble_advdata_encode(&scandata, m_adv_data_buffer_1.scan_rsp_data.p_data, &m_adv_data_buffer_1.scan_rsp_data.len);
        APP_ERROR_CHECK(err_code);
        err_code = ble_advdata_encode(&scandata, m_adv_data_buffer_2.scan_rsp_data.p_data, &m_adv_data_buffer_2.scan_rsp_data.len);
        APP_ERROR_CHECK(err_code);
    
        err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data_buffer_1, &m_adv_params);
        APP_ERROR_CHECK(err_code);
    }
    

    On the central side you have come a bit on the way. However, I would recommend filtering the ADV reports on a specific ID in the scan response manufacturing data as you now are processing all advertisement reports. In the ble_app_proximity_beacon example you are adding a lot of service UUIDs which doesnt are not used. I would remove these as these take up space in the scan response packet. 

    You can use the ble_advdata_search() function  from ble_advdata.c to find the manufacturing data by setting the ad_type input parameter set to BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA. This will give you the offset indicating where the manufacturing data starts. 

    Best regards

    Bjørn

  • I did not see any reference any code that added the nounce to the scan response data in the ble_app_proximity_beacon example that was attached. I added this the following way.

    static void advertising_init(void)
    {
        uint32_t      err_code;
        ble_advdata_t advdata;
        ble_advdata_t scandata;
        uint8_t       flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    
        ble_advdata_manuf_data_t manuf_specific_data;
    
        manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
    
    #if defined(USE_UICR_FOR_MAJ_MIN_VALUES)
    
        uint16_t major_value = ((*(uint32_t *)UICR_ADDRESS) & 0xFFFF0000) >> 16;
        uint16_t minor_value = ((*(uint32_t *)UICR_ADDRESS) & 0x0000FFFF);
    
        uint8_t index = MAJ_VAL_OFFSET_IN_BEACON_INFO;
    
        m_beacon_info[index++] = MSB_16(major_value);
        m_beacon_info[index++] = LSB_16(major_value);
    
        m_beacon_info[index++] = MSB_16(minor_value);
        m_beacon_info[index++] = LSB_16(minor_value);
    #endif
    
        manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info;
        manuf_specific_data.data.size   = APP_BEACON_INFO_LENGTH;
    
        m_beacon_info[18] = 0x00;
        m_beacon_info[19] = 100; // init battery
     
        m_beacon_info[20] = 0x00;
        m_beacon_info[21] = 0x00;
    
    
        memset(&advdata, 0, sizeof(advdata));
        advdata.flags                 = flags;
        advdata.p_manuf_specific_data = &manuf_specific_data;
    
    
    
        memset(&m_adv_params, 0, sizeof(m_adv_params));
    
        m_adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
        m_adv_params.p_peer_addr     = NULL;    
        m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
        m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
        m_adv_params.duration        = 0;       
    
        err_code = ble_advdata_encode(&advdata, m_adv_data_buffer_1.adv_data.p_data, &m_adv_data_buffer_1.adv_data.len);
        APP_ERROR_CHECK(err_code);
    
        ble_advdata_manuf_data_t sr_manuf_data;
    
        memset(&sr_manuf_data,0, sizeof(sr_manuf_data));
    
        sr_manuf_data.data.p_data = nounce;
        sr_manuf_data.data.size = sizeof(nounce);
        sr_manuf_data.company_identifier = APP_COMPANY_IDENTIFIER;
    
        memset(&scandata, 0, sizeof(scandata));
    
        //scandata.name_type             = BLE_ADVDATA_FULL_NAME;
        scandata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        scandata.uuids_complete.p_uuids  = m_adv_uuids;
        scandata.p_manuf_specific_data = &sr_manuf_data;
    
        ble_gap_addr_t gap_address;
        gap_address.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
        memcpy(&gap_address.addr, "\xbb\xaa\xcc\xbb\xaa\xAC", sizeof(gap_address.addr));
        err_code = sd_ble_gap_addr_set(&gap_address);
        APP_ERROR_CHECK(err_code);
    
        err_code = ble_advdata_encode(&scandata, m_adv_data_buffer_1.scan_rsp_data.p_data, &m_adv_data_buffer_1.scan_rsp_data.len);
        APP_ERROR_CHECK(err_code);
        err_code = ble_advdata_encode(&scandata, m_adv_data_buffer_2.scan_rsp_data.p_data, &m_adv_data_buffer_2.scan_rsp_data.len);
        APP_ERROR_CHECK(err_code);
    
        err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data_buffer_1, &m_adv_params);
        APP_ERROR_CHECK(err_code);
    }
    

    On the central side you have come a bit on the way. However, I would recommend filtering the ADV reports on a specific ID in the scan response manufacturing data as you now are processing all advertisement reports. In the ble_app_proximity_beacon example you are adding a lot of service UUIDs which doesnt are not used. I would remove these as these take up space in the scan response packet. 

    You can use the ble_advdata_search() function  from ble_advdata.c to find the manufacturing data by setting the ad_type input parameter set to BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA. This will give you the offset indicating where the manufacturing data starts. 

    Best regards

    Bjørn

Related