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

There seems to be a problem merging encryption(AES CTR)crypto and NUS services.

5241.nRF5_SDK_17.0.2.zip

Hello

I am using sdk v17 and nrf52dk and implementing sensor encryption(AES CTR mode) and simple nus service. After reading the sensor to saadc, I want to encrypt and transmit Bluetooth.

The sensor's value encryption and the addition of NUS services were good, but there were some problems sending encryption data to Bluetooth.
This is part of the output to the terminal.
-Plain text-
sensor value : 408

-Encrypted text (hex)-
24 c0 cc f0 c0 70 3b 52 d5 23 da 01 ed a8 8e 3e 
90 75 

-Decrypted text-
sensor value : 408

It outputs well in the terminal, but when checked in the Bluetooth app, only some of the encrypted data is output and the rest is ignored.

this is the code that encrypts sensor data and sends encrypted data to Bluetooth. (I suspect there may be a problem in this code.)

static void hex_text_print(char const* p_label, char const * p_text, size_t len) //char const* p_label, char const * p_text, size_t len
{
    uint32_t err_code;

    NRF_LOG_RAW_INFO("-%s-\r\n", p_label);
    NRF_LOG_FLUSH();
    printf("-%s-\r\n", p_label);

    // Handle partial line (left)
    for (size_t i = 0; i < len; i++)
    {
        if (((i & 0xF) == 0) && (i > 0))
        {
            NRF_LOG_RAW_INFO("\r\n");
            NRF_LOG_FLUSH();
            printf("\r\n");
        }

        NRF_LOG_RAW_INFO("%02x ", p_text[i]);
        NRF_LOG_FLUSH();
        printf("%02x ", p_text[i]);

        //send to app
        sprintf(app_encrypted_text, "%02x ", p_text[i]); //app
        uint16_t length_app_encrypt = strlen(app_encrypted_text);

        err_code = ble_nus_data_send(&m_nus, &app_encrypted_text, &length_app_encrypt, m_conn_handle);
        if ((err_code != NRF_ERROR_INVALID_STATE) && 
            (err_code != NRF_ERROR_RESOURCES) &&
            (err_code != NRF_ERROR_NOT_FOUND) &&
            (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)) 
            {
                APP_ERROR_CHECK(err_code);
            }
    }

    NRF_LOG_RAW_INFO("\r\n");
    NRF_LOG_RAW_INFO("\r\n");
    printf("\r\n");
    printf("\r\n");
}

Encryption code and main() code.

//=====================================================================================
//AES CTR
int adc_value; //saadc

#define NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE  100 //(100)

#define AES_ERROR_CHECK(error)  \
    do {            \
        if (error)  \
        {           \
            NRF_LOG_RAW_INFO("\r\nError = 0x%x\r\n%s\r\n",           \
                             (error),                                \
                             nrf_crypto_error_string_get(error));    \
            return; \
        }           \
    } while (0);



/* Maximum allowed key = 256 bit */
static uint8_t m_key[32] = {'N', 'O', 'R', 'D', 'I', 'C', ' ',
                            'S', 'E', 'M', 'I', 'C', 'O', 'N', 'D', 'U', 'C', 'T', 'O', 'R',
                            'A', 'E', 'S', '&', 'M', 'A', 'C', ' ', 'T', 'E', 'S', 'T'};

/* Below text is used as plain text for encryption and decryption in AES CTR mode. */
//static char m_plain_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE] =
//{
//    "AES CTR Mode Test"
//};
char m_plain_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE];
static char m_encrypted_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE]; //encrypt
static char m_decrypted_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE]; //decrypt

char app_encrypted_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE];
char app_plain_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE];
char app_label_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE];



static void text_print(char const* p_label, char const * p_text, size_t len)
{
    uint32_t err_code;

    NRF_LOG_RAW_INFO("-%s-\r\n", p_label);
    NRF_LOG_FLUSH();
    printf("-%s-\r\n", p_label);


    //send to app
    //sprintf(app_label_text, "%c", p_label); //app
    //uint16_t length_app_label = strlen(app_label_text);

    //err_code = ble_nus_data_send(&m_nus, &app_label_text, &length_app_label, m_conn_handle);
    //if ((err_code != NRF_ERROR_INVALID_STATE) && 
    //      (err_code != NRF_ERROR_RESOURCES) &&
    //      (err_code != NRF_ERROR_NOT_FOUND) &&
    //      (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)) 
    //      {
    //          APP_ERROR_CHECK(err_code);
    //      }


    for(size_t i = 0; i < len; i++) //output sensor value
    {
        NRF_LOG_RAW_INFO("%c", p_text[i]);
        NRF_LOG_FLUSH();
        printf("%c", p_text[i]);
    }

    NRF_LOG_RAW_INFO("\r\n\r\n");
    NRF_LOG_FLUSH();
    printf("\r\n\r\n");


    //App
    char level_value_msg[50];
    sprintf(level_value_msg, "sensor value : %d", adc_value);
    uint16_t length_value = strlen(level_value_msg);

    err_code = ble_nus_data_send(&m_nus, &level_value_msg, &length_value, m_conn_handle);
    if ((err_code != NRF_ERROR_INVALID_STATE) && 
        (err_code != NRF_ERROR_RESOURCES) &&
        (err_code != NRF_ERROR_NOT_FOUND) &&
        (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)) 
        {
            APP_ERROR_CHECK(err_code);
        }
}


static void hex_text_print(char const* p_label, char const * p_text, size_t len) //char const* p_label, char const * p_text, size_t len
{
    uint32_t err_code;

    NRF_LOG_RAW_INFO("-%s-\r\n", p_label);
    NRF_LOG_FLUSH();
    printf("-%s-\r\n", p_label);

    // Handle partial line (left)
    for (size_t i = 0; i < len; i++)
    {
        if (((i & 0xF) == 0) && (i > 0))
        {
            NRF_LOG_RAW_INFO("\r\n");
            NRF_LOG_FLUSH();
            printf("\r\n");
        }

        NRF_LOG_RAW_INFO("%02x ", p_text[i]);
        NRF_LOG_FLUSH();
        printf("%02x ", p_text[i]);

        //send to app
        sprintf(app_encrypted_text, "%02x ", p_text[i]); //app
        uint16_t length_app_encrypt = strlen(app_encrypted_text);

        err_code = ble_nus_data_send(&m_nus, &app_encrypted_text, &length_app_encrypt, m_conn_handle);
        if ((err_code != NRF_ERROR_INVALID_STATE) && 
            (err_code != NRF_ERROR_RESOURCES) &&
            (err_code != NRF_ERROR_NOT_FOUND) &&
            (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)) 
            {
                APP_ERROR_CHECK(err_code);
            }
    }

    NRF_LOG_RAW_INFO("\r\n\r\n");
    printf("\r\n\r\n");
}


static void plain_text_print(void)
{
    text_print("Plain text", m_plain_text, strlen(m_plain_text));
    //hex_text_print("Plain text (hex)", m_plain_text, strlen(m_plain_text));
}


static void encrypted_text_print(char const * p_text, size_t encrypted_len)
{
    hex_text_print("Encrypted text (hex)", p_text, encrypted_len);
}


static void decrypted_text_print(char const * p_text, size_t decrypted_len)
{
    text_print("Decrypted text", p_text, decrypted_len);
    //hex_text_print("Decrypted text (hex)", p_text, decrypted_len);
}


static void crypt_ctr(void)
{
    uint8_t     iv[16];
    ret_code_t  ret_val;
    size_t      len_in;
    size_t      len_out;

    static nrf_crypto_aes_context_t ctr_encr_128_ctx; // AES CTR encryption context
    static nrf_crypto_aes_context_t ctr_decr_128_ctx; // AES CTR decryption context

    plain_text_print();

    /* Init encryption context for 128 bit key */
    ret_val = nrf_crypto_aes_init(&ctr_encr_128_ctx,
                                  &g_nrf_crypto_aes_ctr_128_info,
                                  NRF_CRYPTO_ENCRYPT);
    AES_ERROR_CHECK(ret_val);

    /* Set key for encryption context - only first 128 key bits will be used */
    ret_val = nrf_crypto_aes_key_set(&ctr_encr_128_ctx, m_key);
    AES_ERROR_CHECK(ret_val);

    memset(iv, 0, sizeof(iv));
    /* Set IV for encryption context */
    ret_val = nrf_crypto_aes_iv_set(&ctr_encr_128_ctx, iv);
    AES_ERROR_CHECK(ret_val);

    len_in = strlen(m_plain_text);

#define PARTIAL_MESSAGE_SIZE (16u)  // 16 bytes
    /* Encrypt first 10 bytes */
    ret_val = nrf_crypto_aes_update(&ctr_encr_128_ctx,
                                    (uint8_t *)m_plain_text,
                                    PARTIAL_MESSAGE_SIZE,           // encrypt first 10 bytes
                                    (uint8_t *)m_encrypted_text);
    AES_ERROR_CHECK(ret_val);

    size_t offset = PARTIAL_MESSAGE_SIZE;
    len_out = sizeof(m_encrypted_text) - PARTIAL_MESSAGE_SIZE;

    /* Encrypt first rest of text */
    ret_val = nrf_crypto_aes_finalize(&ctr_encr_128_ctx,
                                      (uint8_t *)m_plain_text + offset, // skip already encrypted bytes
                                      len_in - offset,
                                      (uint8_t *)m_encrypted_text + offset,
                                      &len_out);
    AES_ERROR_CHECK(ret_val);

    encrypted_text_print(m_encrypted_text, PARTIAL_MESSAGE_SIZE + len_out);

    memset(iv, 0, sizeof(iv));

    len_in  = len_out + offset; // length of encrypted message is an input for decryption
    len_out = sizeof(m_decrypted_text);
    /* Decrypt with integrated function */
    ret_val = nrf_crypto_aes_crypt(&ctr_decr_128_ctx,
                                   &g_nrf_crypto_aes_ctr_128_info,
                                   NRF_CRYPTO_DECRYPT,
                                   m_key,
                                   iv,
                                   (uint8_t *)m_encrypted_text,
                                   len_in,
                                   (uint8_t *)m_decrypted_text,
                                   &len_out);
    AES_ERROR_CHECK(ret_val);

    decrypted_text_print(m_decrypted_text, len_out);

    if (memcmp(m_plain_text, m_decrypted_text, len_out) == 0)
    {
        //NRF_LOG_RAW_INFO("AES CTR example executed successfully.\r\n");
    }
    else
    {
        NRF_LOG_RAW_INFO("AES CTR example failed!!!\r\n");
        printf("AES CTR example failed!!!\r\n");
    }
}



//=====================================================================================
//saadc
#define SAMPLES_IN_BUFFER 5
#define ADC_Time 700
volatile uint8_t state = 1;

static const nrf_drv_timer_t m_timer = NRF_DRV_TIMER_INSTANCE(2); //0
static nrf_saadc_value_t     m_buffer_pool[2][SAMPLES_IN_BUFFER];
static nrf_ppi_channel_t     m_ppi_channel;
static uint32_t              m_adc_evt_counter;


void timer_handler(nrf_timer_event_t event_type, void * p_context)
{

}


void saadc_sampling_event_init(void)
{
    ret_code_t err_code;

    err_code = nrf_drv_ppi_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
    err_code = nrf_drv_timer_init(&m_timer, &timer_cfg, timer_handler);
    APP_ERROR_CHECK(err_code);

    /* setup m_timer for compare event every (ADC_Time)ms */
    uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, ADC_Time); //output time
    nrf_drv_timer_extended_compare(&m_timer,
                                   NRF_TIMER_CC_CHANNEL0,
                                   ticks,
                                   NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                   false);
    nrf_drv_timer_enable(&m_timer);

    uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer,
                                                                                NRF_TIMER_CC_CHANNEL0);
    uint32_t saadc_sample_task_addr   = nrf_drv_saadc_sample_task_get();

    /* setup ppi channel so that timer compare event is triggering sample task in SAADC */
    err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_assign(m_ppi_channel,
                                          timer_compare_event_addr,
                                          saadc_sample_task_addr);
    APP_ERROR_CHECK(err_code);
}


void saadc_sampling_event_enable(void)
{
    ret_code_t err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);

    APP_ERROR_CHECK(err_code);
}


//int adc_value;

void saadc_callback(nrf_drv_saadc_evt_t const * p_event) 
{ 
    int sum = 0;
    int value = 0;
    //int adc_value = 0;   
    ret_code_t err_code;

   if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
   {
        err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);

        //NRF_LOG_INFO("ADC event number: %d", (int)m_adc_evt_counter);
        //printf("ADC event number: %d\n", (int)m_adc_evt_counter);
      
        for (int i = 0; i < SAMPLES_IN_BUFFER; i++) 
        {
            value = p_event->data.done.p_buffer[i];
            sum = sum + value;
        }

        adc_value = sum / SAMPLES_IN_BUFFER;
        //NRF_LOG_INFO("value : %d", adc_value);
        //printf("value : %d\n", adc_value);

        //crypto
        //sprintf(m_plain_text, "%d", adc_value);
        //crypt_ctr();
        
        m_adc_evt_counter++;
   }
}


void saadc_init(void)
{
    ret_code_t err_code;
    nrf_saadc_channel_config_t channel_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN1); //p0.03
        //add option 
        //adc input range = reperence / gain   (REFERENCE_VDD4 / GAIN1_4 = VDD)
        channel_config.gain = NRF_SAADC_GAIN1_4; //volt gain change (ADC range, Gain factor 1/4)
        channel_config.reference = NRF_SAADC_REFERENCE_VDD4; //VDD/4 as reference

    err_code = nrf_drv_saadc_init(NULL, saadc_callback);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_channel_init(0, &channel_config);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);
}


void saadc_all_init()
{
    saadc_init();
    saadc_sampling_event_init();
    saadc_sampling_event_enable();
}

//=====================================================================================



/**@brief Function for application main entry.
 */
int main(void)
{
    bool erase_bonds;
    uint32_t err_code;

    // Initialize.
    uart_init();
    log_init();
    timers_init();
    buttons_leds_init(&erase_bonds);
    power_management_init();
    ble_stack_init(); 
    gap_params_init();
    gatt_init();
    services_init();
    advertising_init(); 
    conn_params_init();
    peer_manager_init();

    // Start execution.
    NRF_LOG_INFO("Template example started.");
    printf("Template example started\n");
    advertising_start(erase_bonds);

    nrf_drv_clock_lfclk_request(NULL);

    err_code = nrf_crypto_init();
    APP_ERROR_CHECK(err_code);

    err_code = nrf_mem_init();
    APP_ERROR_CHECK(err_code);

    saadc_all_init();

    //crypt_ctr();

    // Enter main loop.
    for (;;)
    {
        idle_state_handle();

        if(adc_value > 0)
        {
          sprintf(m_plain_text, "sensor value : %d", adc_value);
          //sprintf(m_plain_text, "%d ", adc_value);
          crypt_ctr();
 
          adc_value = 0;
        }
    }
}

May I know the cause of this problem?
Thank you.
Related