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

  • 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

  • Hi  bjorn-spockeli

    #include <stdio.h>
    #include <stdint.h>
    #include <stdbool.h>
    #include "nordic_common.h"
    #include "app_error.h"
    #include "app_uart.h"
    #include "ble_db_discovery.h"
    #include "app_timer.h"
    #include "app_util.h"
    #include "bsp_btn_ble.h"
    #include "ble.h"
    #include "ble_gap.h"
    #include "ble_hci.h"
    #include "nrf_sdh.h"
    #include "nrf_sdh_ble.h"
    #include "nrf_sdh_soc.h"
    #include "ble_nus_c.h"
    #include "nrf_ble_gatt.h"
    #include "nrf_pwr_mgmt.h"
    #include "nrf_ble_scan.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    
    #define APP_BLE_CONN_CFG_TAG    1                                       /**< Tag that refers to the BLE stack configuration set with @ref sd_ble_cfg_set. The default tag is @ref BLE_CONN_CFG_TAG_DEFAULT. */
    #define APP_BLE_OBSERVER_PRIO   3                                       /**< BLE observer priority of the application. There is no need to modify this value. */
    
    #define UART_TX_BUF_SIZE        256                                     /**< UART TX buffer size. */
    #define UART_RX_BUF_SIZE        256                                     /**< UART RX buffer size. */
    
    #define NUS_SERVICE_UUID_TYPE   BLE_UUID_TYPE_VENDOR_BEGIN              /**< UUID type for the Nordic UART Service (vendor specific). */
    
    #define ECHOBACK_BLE_UART_DATA  1                                       /**< Echo the UART data that is received over the Nordic UART Service (NUS) back to the sender. */
    #define ECB_KEY_LEN            (16UL)
    #define COUNTER_BYTE_LEN       (4UL)
    #define NONCE_RAND_BYTE_LEN    (12UL)
    
    static uint8_t m_ecb_key[16] = {0x6E,0x88,0x90,0x8D,0x75,0xBB,0x95,0xEA,0x2C,0x65,0x93,0x01,0x43,0xF8,0x1B,0x5F};
    static nrf_ecb_hal_data_t m_ecb_data;
    // The RNG wait values are typical and not guaranteed. See Product Specifications for more info.
    #ifdef NRF51
    #define RNG_BYTE_WAIT_US       (677UL)
    #elif defined NRF52
    #define RNG_BYTE_WAIT_US       (124UL)
    #else
    #error "Either NRF51 or NRF52 must be defined."
    #endif     
    
    BLE_NUS_C_DEF(m_ble_nus_c);                                             /**< BLE Nordic UART Service (NUS) client instance. */
    NRF_BLE_GATT_DEF(m_gatt);                                               /**< GATT module instance. */
    BLE_DB_DISCOVERY_DEF(m_db_disc);                                        /**< Database discovery module instance. */
    NRF_BLE_SCAN_DEF(m_scan);                                               /**< Scanning Module instance. */
    
    static uint16_t m_ble_nus_max_data_len = BLE_GATT_ATT_MTU_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH; /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
    
    /**@brief NUS UUID. */
    static ble_uuid_t const m_nus_uuid =
    {
        .uuid = BLE_UUID_NUS_SERVICE,
        .type = NUS_SERVICE_UUID_TYPE
    };
    
    
    void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
    {
        app_error_handler(0xDEADBEEF, line_num, p_file_name);
    }
    
    
    /**@brief Function for starting scanning. */
    static void scan_start(void)
    {
        ret_code_t ret;
    
        ret = nrf_ble_scan_start(&m_scan);
        APP_ERROR_CHECK(ret);
    
        ret = bsp_indication_set(BSP_INDICATE_SCANNING);
        APP_ERROR_CHECK(ret);
    }
    
    
    /**@brief Function for handling Scanning Module events.
     */
    static void scan_evt_handler(scan_evt_t const * p_scan_evt)
    {
        ret_code_t err_code;
    
        switch(p_scan_evt->scan_evt_id)
        {
             case NRF_BLE_SCAN_EVT_CONNECTING_ERROR:
             {
                  err_code = p_scan_evt->params.connecting_err.err_code;
                  APP_ERROR_CHECK(err_code);
             } break;
    
             case NRF_BLE_SCAN_EVT_SCAN_REQ_REPORT:
             {
                   ble_gap_addr_t  addr;
                   memcpy(addr.addr, p_scan_evt->params.req_report.peer_addr.addr, 6);
                   NRF_LOG_INFO("Beacon address: %02x:%02x:%02x:%02x:%02x:%02x",
                                     p_scan_evt->params.req_report.peer_addr.addr[5],
                                     p_scan_evt->params.req_report.peer_addr.addr[4],
                                     p_scan_evt->params.req_report.peer_addr.addr[3],
                                     p_scan_evt->params.req_report.peer_addr.addr[2],
                                     p_scan_evt->params.req_report.peer_addr.addr[1],
                                     p_scan_evt->params.req_report.peer_addr.addr[0]
                                     );
    
    
             } break;
    
             case NRF_BLE_SCAN_EVT_CONNECTED:
             {
                  ble_gap_evt_connected_t const * p_connected =
                                   p_scan_evt->params.connected.p_connected;
                 // Scan is automatically stopped by the connection.
                 NRF_LOG_INFO("Connecting to target %02x:%02x:%02x:%02x:%02x:%02x",
                          p_connected->peer_addr.addr[0],
                          p_connected->peer_addr.addr[1],
                          p_connected->peer_addr.addr[2],
                          p_connected->peer_addr.addr[3],
                          p_connected->peer_addr.addr[4],
                          p_connected->peer_addr.addr[5]
                          );
             } break;
    
             case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:
             {
                 NRF_LOG_INFO("Scan timed out.");
                 scan_start();
             } break;
    
             default:
                 break;
        }
    }
    
    
    /**@brief Function for initializing the scanning and setting the filters.
     */
    static void scan_init(void)
    {
        ret_code_t          err_code;
        nrf_ble_scan_init_t init_scan;
    
        memset(&init_scan, 0, sizeof(init_scan));
    
        init_scan.connect_if_match = true;
        init_scan.conn_cfg_tag     = APP_BLE_CONN_CFG_TAG;
    
        err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_UUID_FILTER, &m_nus_uuid);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_UUID_FILTER, false);
        APP_ERROR_CHECK(err_code);
    }
    
    
    
    static void db_disc_handler(ble_db_discovery_evt_t * p_evt)
    {
        ble_nus_c_on_db_disc_evt(&m_ble_nus_c, p_evt);
    }
    
    
    
    static void ble_nus_chars_received_uart_print(uint8_t * p_data, uint16_t data_len)
    {
        ret_code_t ret_val;
    
        NRF_LOG_DEBUG("Receiving data.");
        NRF_LOG_HEXDUMP_DEBUG(p_data, data_len);
    
        for (uint32_t i = 0; i < data_len; i++)
        {
            do
            {
                ret_val = app_uart_put(p_data[i]);
                if ((ret_val != NRF_SUCCESS) && (ret_val != NRF_ERROR_BUSY))
                {
                    NRF_LOG_ERROR("app_uart_put failed for index 0x%04x.", i);
                    APP_ERROR_CHECK(ret_val);
                }
            } while (ret_val == NRF_ERROR_BUSY);
        }
        if (p_data[data_len-1] == '\r')
        {
            while (app_uart_put('\n') == NRF_ERROR_BUSY);
        }
        if (ECHOBACK_BLE_UART_DATA)
        {
            // Send data back to the peripheral.
            do
            {
                ret_val = ble_nus_c_string_send(&m_ble_nus_c, p_data, data_len);
                if ((ret_val != NRF_SUCCESS) && (ret_val != NRF_ERROR_BUSY))
                {
                    NRF_LOG_ERROR("Failed sending NUS message. Error 0x%x. ", ret_val);
                    APP_ERROR_CHECK(ret_val);
                }
            } while (ret_val == NRF_ERROR_BUSY);
        }
    }
    
    
    
    void uart_event_handle(app_uart_evt_t * p_event)
    {
        static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
        static uint16_t index = 0;
        uint32_t ret_val;
    
        switch (p_event->evt_type)
        {
            /**@snippet [Handling data from UART] */
            case APP_UART_DATA_READY:
                UNUSED_VARIABLE(app_uart_get(&data_array[index]));
                index++;
    
                if ((data_array[index - 1] == '\n') || (index >= (m_ble_nus_max_data_len)))
                {
                    NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                    NRF_LOG_HEXDUMP_DEBUG(data_array, index);
    
                    do
                    {
                        ret_val = ble_nus_c_string_send(&m_ble_nus_c, data_array, index);
                        if ( (ret_val != NRF_ERROR_INVALID_STATE) && (ret_val != NRF_ERROR_RESOURCES) )
                        {
                            APP_ERROR_CHECK(ret_val);
                        }
                    } while (ret_val == NRF_ERROR_RESOURCES);
    
                    index = 0;
                }
                break;
    
            /**@snippet [Handling data from UART] */
            case APP_UART_COMMUNICATION_ERROR:
                NRF_LOG_ERROR("Communication error occurred while handling UART.");
                APP_ERROR_HANDLER(p_event->data.error_communication);
                break;
    
            case APP_UART_FIFO_ERROR:
                NRF_LOG_ERROR("Error occurred in FIFO module used by UART.");
                APP_ERROR_HANDLER(p_event->data.error_code);
                break;
    
            default:
                break;
        }
    }
    
    
    
    
    /**@snippet [Handling events from the ble_nus_c module] */
    static void ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, ble_nus_c_evt_t const * p_ble_nus_evt)
    {
        ret_code_t err_code;
    
        switch (p_ble_nus_evt->evt_type)
        {
            case BLE_NUS_C_EVT_DISCOVERY_COMPLETE:
                NRF_LOG_INFO("Discovery complete.");
                err_code = ble_nus_c_handles_assign(p_ble_nus_c, p_ble_nus_evt->conn_handle, &p_ble_nus_evt->handles);
                APP_ERROR_CHECK(err_code);
    
                err_code = ble_nus_c_tx_notif_enable(p_ble_nus_c);
                APP_ERROR_CHECK(err_code);
                NRF_LOG_INFO("Connected to device with Nordic UART Service.");
                break;
    
            case BLE_NUS_C_EVT_NUS_TX_EVT:
                ble_nus_chars_received_uart_print(p_ble_nus_evt->p_data, p_ble_nus_evt->data_len);
                break;
    
            case BLE_NUS_C_EVT_DISCONNECTED:
                NRF_LOG_INFO("Disconnected.");
                scan_start();
                break;
        }
    }
    /**@snippet [Handling events from the ble_nus_c module] */
    
    
    /**
     * @brief Function for handling shutdown events.
     *
     * @param[in]   event       Shutdown type.
     */
    static bool shutdown_handler(nrf_pwr_mgmt_evt_t event)
    {
        ret_code_t err_code;
    
        err_code = bsp_indication_set(BSP_INDICATE_IDLE);
        APP_ERROR_CHECK(err_code);
    
        switch (event)
        {
            case NRF_PWR_MGMT_EVT_PREPARE_WAKEUP:
                // Prepare wakeup buttons.
                err_code = bsp_btn_ble_sleep_mode_prepare();
                APP_ERROR_CHECK(err_code);
                break;
    
            default:
                break;
        }
    
        return true;
    }
    
    NRF_PWR_MGMT_HANDLER_REGISTER(shutdown_handler, APP_SHUTDOWN_HANDLER_PRIORITY);
    
    void nonce_generate(uint8_t * p_buf)
    {
        uint8_t i         = COUNTER_BYTE_LEN;
        uint8_t remaining = NONCE_RAND_BYTE_LEN;
    
    
        while(0 != remaining)
        {
            uint32_t err_code;
            uint8_t  available = 0;
    
            err_code = sd_rand_application_bytes_available_get(&available);
            APP_ERROR_CHECK(err_code);
    
            available = ((available > remaining) ? remaining : available);
            if (0 != available)
            {
    	        err_code = sd_rand_application_vector_get((p_buf + i), available);
    	        APP_ERROR_CHECK(err_code);
    
    	        i         += available;
    	        remaining -= available;
    	    }
    
    	    if (0 != remaining)
    	    {
    	        nrf_delay_us(RNG_BYTE_WAIT_US * remaining);
    	    }
        }
    }
    
    static bool m_initialized = false;
    
    
    
    
    
    void ctr_init(const uint8_t * p_nonce, const uint8_t * p_ecb_key)
    {
        m_initialized = true;
    
        // Save the key.
        memcpy(&m_ecb_data.key[0], p_ecb_key, ECB_KEY_LEN);
    
        // Copy the nonce.
        memcpy(&m_ecb_data.ciphertext[COUNTER_BYTE_LEN],
    	          &p_nonce[COUNTER_BYTE_LEN],
    	          NONCE_RAND_BYTE_LEN);
    
        // Zero the counter value.
        memset(&m_ecb_data.cleartext[0], 0x00, COUNTER_BYTE_LEN);
    }
    
    static uint32_t crypt(uint8_t * buf)
    {
        uint8_t  i;
        uint32_t err_code;
    
        if (!m_initialized)
        {
    	    return NRF_ERROR_INVALID_STATE;
        }
    
        err_code = sd_ecb_block_encrypt(&m_ecb_data);
        if (NRF_SUCCESS != err_code)
        {
    	    return err_code;
        }
    
        for (i=0; i < ECB_KEY_LEN; i++)
        {
    	    buf[i] ^= m_ecb_data.ciphertext[i];
        }
    
        // Increment the counter.
        (*((uint32_t*) m_ecb_data.cleartext))++;
    
        return NRF_SUCCESS;
    }
    
    
    uint32_t ctr_encrypt(uint8_t * p_clear_text)
    {
        return crypt(p_clear_text);
    }
    
    
    uint32_t ctr_decrypt(uint8_t * p_cipher_text)
    {
        return crypt(p_cipher_text);
    }
    
    
    /**@brief Function for handling BLE events.
     *
     * @param[in]   p_ble_evt   Bluetooth stack event.
     * @param[in]   p_context   Unused.
     */
    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        ret_code_t            err_code;
        ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;
        uint8_t uuid[26];
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
                err_code = ble_nus_c_handles_assign(&m_ble_nus_c, p_ble_evt->evt.gap_evt.conn_handle, NULL);
                APP_ERROR_CHECK(err_code);
    
                err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
                APP_ERROR_CHECK(err_code);
    
                // start discovery of services. The NUS Client waits for a discovery result
                err_code = ble_db_discovery_start(&m_db_disc, p_ble_evt->evt.gap_evt.conn_handle);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
    
                NRF_LOG_INFO("Disconnected. conn_handle: 0x%x, reason: 0x%x",
                             p_gap_evt->conn_handle,
                             p_gap_evt->params.disconnected.reason);
                break;
    
            case BLE_GAP_EVT_TIMEOUT:
                if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN)
                {
                    NRF_LOG_INFO("Connection Request timed out.");
                }
                break;
    
            case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
                // Pairing not supported.
                err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
                // Accepting parameters requested by peer.
                err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle,
                                                        &p_gap_evt->params.conn_param_update_request.conn_params);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
            {
                NRF_LOG_DEBUG("PHY update request.");
                ble_gap_phys_t const phys =
                {
                    .rx_phys = BLE_GAP_PHY_AUTO,
                    .tx_phys = BLE_GAP_PHY_AUTO,
                };
                err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
                APP_ERROR_CHECK(err_code);
            } break;
    
            case BLE_GATTC_EVT_TIMEOUT:
                // Disconnect on GATT Client timeout event.
                NRF_LOG_DEBUG("GATT Client Timeout.");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GATTS_EVT_TIMEOUT:
                // Disconnect on GATT Server timeout event.
                NRF_LOG_DEBUG("GATT Server Timeout.");
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;
           case BLE_GAP_EVT_ADV_REPORT:
    			
                            {
    				NRF_LOG_INFO("Advertise received");
    				scan_start();
                                    
    	//			nrf_gpio_pin_toggle(LED1_PIN);
    
                                      ble_gap_addr_t  addr;
                                     memcpy(addr.addr, p_gap_evt->params.adv_report.peer_addr.addr, 6);
                                     NRF_LOG_INFO("Beacon address: %02x:%02x:%02x:%02x:%02x:%02x",
                                     p_gap_evt->params.adv_report.peer_addr.addr[5],
                                     p_gap_evt->params.adv_report.peer_addr.addr[4],
                                     p_gap_evt->params.adv_report.peer_addr.addr[3],
                                     p_gap_evt->params.adv_report.peer_addr.addr[2],
                                     p_gap_evt->params.adv_report.peer_addr.addr[1],
                                     p_gap_evt->params.adv_report.peer_addr.addr[0]);
    				
    				memmove(uuid, p_gap_evt->params.adv_report.data.p_data, p_gap_evt->params.adv_report.data.len);
    				
    				NRF_LOG_INFO("UUID: %02x%02x%02x%02x%02x%02x", uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14]);
    				
    				NRF_LOG_INFO("TX_POWER: %02x", p_gap_evt->params.adv_report.tx_power);
    				
    				NRF_LOG_INFO("RSSI: %02x", p_gap_evt->params.adv_report.rssi);
                               
        uint8_t nounce[16] = {0};
        uint8_t m_beacon_info[16];
    
        ctr_init(nounce,m_ecb_key);
        NRF_LOG_INFO("Encrypted info:");
        NRF_LOG_HEXDUMP_INFO(uuid, sizeof(uuid));
    
        
        m_ecb_data.cleartext[0] = 0x00;
        m_ecb_data.cleartext[1] = 0x00;
        m_ecb_data.cleartext[2] = 0x00;
        m_ecb_data.cleartext[3] = 0x00;
    
        // Decrypt the ciphertext with the same counter value, i.e. 0x00,0x00,0x00,0x00, that was used for encrypting. 
        ctr_decrypt(uuid);
        ctr_decrypt(&uuid[16]);
            
        NRF_LOG_INFO("Decrypted info:");
        NRF_LOG_HEXDUMP_INFO(uuid, sizeof(uuid));
    
    
    
    		        } break;
    
                default:
                break;
        }
    }
    
    
    /**@brief Function for initializing the BLE stack.
     *
     * @details Initializes the SoftDevice and the BLE event interrupt.
     */
    static void ble_stack_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }
    
    
    /**@brief Function for handling events from the GATT library. */
    void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
    {
        if (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)
        {
            NRF_LOG_INFO("ATT MTU exchange completed.");
    
            m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
            NRF_LOG_INFO("Ble NUS max data length set to 0x%X(%d)", m_ble_nus_max_data_len, m_ble_nus_max_data_len);
        }
    }
    
    
    /**@brief Function for initializing the GATT library. */
    void gatt_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_gatt_att_mtu_central_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling events from the BSP module.
     *
     * @param[in] event  Event generated by button press.
     */
    void bsp_event_handler(bsp_event_t event)
    {
        ret_code_t err_code;
    
        switch (event)
        {
            case BSP_EVENT_SLEEP:
                nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
                break;
    
            case BSP_EVENT_DISCONNECT:
                err_code = sd_ble_gap_disconnect(m_ble_nus_c.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                if (err_code != NRF_ERROR_INVALID_STATE)
                {
                    APP_ERROR_CHECK(err_code);
                }
                break;
    
            default:
                break;
        }
    }
    
    /**@brief Function for initializing the UART. */
    static void uart_init(void)
    {
        ret_code_t err_code;
    
        app_uart_comm_params_t const comm_params =
        {
            .rx_pin_no    = RX_PIN_NUMBER,
            .tx_pin_no    = TX_PIN_NUMBER,
            .rts_pin_no   = RTS_PIN_NUMBER,
            .cts_pin_no   = CTS_PIN_NUMBER,
            .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
            .use_parity   = false,
            .baud_rate    = UART_BAUDRATE_BAUDRATE_Baud115200
        };
    
        APP_UART_FIFO_INIT(&comm_params,
                           UART_RX_BUF_SIZE,
                           UART_TX_BUF_SIZE,
                           uart_event_handle,
                           APP_IRQ_PRIORITY_LOWEST,
                           err_code);
    
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for initializing the Nordic UART Service (NUS) client. */
    static void nus_c_init(void)
    {
        ret_code_t       err_code;
        ble_nus_c_init_t init;
    
        init.evt_handler = ble_nus_c_evt_handler;
    
        err_code = ble_nus_c_init(&m_ble_nus_c, &init);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing buttons and leds. */
    static void buttons_leds_init(void)
    {
        ret_code_t err_code;
        bsp_event_t startup_event;
    
        err_code = bsp_init(BSP_INIT_LEDS, bsp_event_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = bsp_btn_ble_init(NULL, &startup_event);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing the timer. */
    static void timer_init(void)
    {
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing the nrf log module. */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    
    /**@brief Function for initializing power management.
     */
    static void power_management_init(void)
    {
        ret_code_t err_code;
        err_code = nrf_pwr_mgmt_init();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /** @brief Function for initializing the database discovery module. */
    static void db_discovery_init(void)
    {
        ret_code_t err_code = ble_db_discovery_init(db_disc_handler);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling the idle state (main loop).
     *
     * @details Handles any pending log operations, then sleeps until the next event occurs.
     */
    static void idle_state_handle(void)
    {
        if (NRF_LOG_PROCESS() == false)
        {
            nrf_pwr_mgmt_run();
        }
    }
    
    
    
    
    int main(void)
    {
        // Initialize.
        log_init();
        timer_init();
        uart_init();
        buttons_leds_init();
        db_discovery_init();
        power_management_init();
        ble_stack_init();
        gatt_init();
        nus_c_init();
        scan_init();
        printf("BLE UART central example started.\r\n");
        NRF_LOG_INFO("BLE UART central example started.");
        scan_start();
           
    
    
        // Start execution.
    
        // Enter main loop.
        for (;;)
        {
            idle_state_handle();
        }
    }

    this is another way of approach i had done so that we can decrypted data for each beacon

    But in this way also i am not getting original data

    Please help, give me the code to get original data

Reply Children
Related