This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTOS/CC2650STK: CC2650STK

Part Number: CC2650STK
Other Parts Discussed in Thread: CC2650

Tool/software: TI-RTOS

I want to implement AES CCM in sensor tag cc2650. So i used crypto drivers which releates to: C:\TI\tirtos_cc13xx_cc26xx_2_20_01_08\products\tidrivers_cc13xx_cc26xx_2_20_01_10\docs\doxygen\html\index.html. and encrypted the humidity data using AES CCM by getting help from the following forum

https://e2e.ti.com/support/wireless-connectivity/bluetooth/f/538/t/663941

Following is given script for encryption.

/******************************************************************************

 @file  sensortag_hum.c

 @brief This file contains the Sensor Tag sample application,
        Humidity part, for use with the TI Bluetooth Low
        Energy Protocol Stack.

 Group: WCS, BTS
 Target Device: CC2650, CC2640, CC1350

 ******************************************************************************
 
 Copyright (c) 2015-2016, Texas Instruments Incorporated
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:

 *  Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

 *  Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.

 *  Neither the name of Texas Instruments Incorporated nor the names of
    its contributors may be used to endorse or promote products derived
    from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 ******************************************************************************
 Release Name: ble_sdk_2_02_01_18
 Release Date: 2016-10-26 15:20:04
 *****************************************************************************/

#ifndef EXCLUDE_HUM
/*********************************************************************
 * INCLUDES
 */
#include "gatt.h"
#include "gattservapp.h"
#include "board.h"
#include "string.h"

#include "humidityservice.h"
#include "sensortag_hum.h"
#include "SensorHdc1000.h"
#include "sensortag.h"
#include "SensorTagTest.h"
#include "SensorUtil.h"

#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Task.h>

/* Include lib for encryption */
#include <ti/drivers/crypto/CryptoCC26XX.h>
//#include "crypto.h"

/*********************************************************************
 * MACROS
 */

/*********************************************************************
 * CONSTANTS
 */

// How often to perform sensor reads (milliseconds)
#define SENSOR_DEFAULT_PERIOD   1000

// Time start measurement and data ready
#define HUM_DELAY_PERIOD        15

// Length of the data for this sensor
#define SENSOR_DATA_LEN         HUMIDITY_DATA_LEN

// Task configuration
#define SENSOR_TASK_PRIORITY    1
#define SENSOR_TASK_STACK_SIZE  600

#define macLength           (4)
#define clearTextLength     (16)
#define cipherTextLength    (macLength + clearTextLength)
#define nonceLength         (12)
#define aadLength           (14)

/*********************************************************************
 * TYPEDEFS
 */


uint8_t UpperByteTemp;
uint8_t LowerByteTemp;
uint8_t UpperByteHum;
uint8_t LowerByteHum;

// Parameters for encryption
uint8_t cryptoOpen = 0;
uint8_t keyLocation = 0;
uint8_t keyRealease = 0;
uint8_t decrytion_AND_ath = 0;
uint8_t encryption_AND_signing = 0;
// Holds the AES-CCM setup for this example
typedef struct
{
    uint8_t key[16];                                // A 128 Bit AES key
    CryptoCC26XX_KeyLocation keyLocation;           // One of 8 key locations in the hardware
    uint8_t clearAndCipherText[cipherTextLength];   // Holds the cleartext before, and the ciphertext
                                                    // after the encryption operation.
                                                    // Ciphertext = encrypted text + message authentication code (MAC).
    uint8_t nonce[nonceLength];  // A value that is used only once (cryptographic term 'nonce')
    uint8_t header[aadLength];   // A header that is not encrypted but is authenticated in the operation (AAD).
} AesCcmExample;

uint8_t clearAndCipherText_test[cipherTextLength]= { '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0' };

/*********************************************************************
 * GLOBAL VARIABLES
 */
AesCcmExample ccmSetup =
{
 .key = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
          0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
 .keyLocation = CRYPTOCC26XX_KEY_0,
 .clearAndCipherText = { 't','h','i','s','i','s','a','p','l','a','i','n','t','e','x','t','0','0','0','0' },
 .nonce  = { 't','h','i','s','i','s','a','n','o','n','c','e' },
 .header = { 't','h','i','s','i','s','a','h','e','a','d','e','r','1' }
};

CryptoCC26XX_Handle             handle;
int32_t                         keyIndex;
CryptoCC26XX_AESCCM_Transaction trans;
int32_t                         status;

/*********************************************************************
 * EXTERNAL VARIABLES
 */

/*********************************************************************
 * EXTERNAL FUNCTIONS
 */

/*********************************************************************
 * LOCAL VARIABLES
 */

// Entity ID globally used to check for source and/or destination of messages
static ICall_EntityID sensorSelfEntity;

// Semaphore globally used to post events to the application thread
static ICall_Semaphore sensorSem;

// Task setup
static Task_Struct sensorTask;
static Char sensorTaskStack[SENSOR_TASK_STACK_SIZE];

// Parameters
static uint8_t sensorConfig;
static uint16_t sensorPeriod;



/*********************************************************************
 * LOCAL FUNCTIONS
 */
static void sensorTaskFxn(UArg a0, UArg a1);
static void sensorConfigChangeCB(uint8_t paramID);
static void initCharacteristicValue(uint8_t paramID, uint8_t value,
                                    uint8_t paramLen);

/*********************************************************************
 * PROFILE CALLBACKS
 */
static sensorCBs_t sensorCallbacks =
{
  sensorConfigChangeCB,  // Characteristic value change callback
};


/*********************************************************************
 * PUBLIC FUNCTIONS
 */
/*********************************************************************
 * @fn      SensorTagHum_createTask
 *
 * @brief   Task creation function for the SensorTag
 *
 * @param   none
 *
 * @return  none
 */
void SensorTagHum_createTask(void)
{
  Task_Params taskParames;

  // Create the task for the state machine
  Task_Params_init(&taskParames);
  taskParames.stack = sensorTaskStack;
  taskParames.stackSize = SENSOR_TASK_STACK_SIZE;
  taskParames.priority = SENSOR_TASK_PRIORITY;

  Task_construct(&sensorTask, sensorTaskFxn, &taskParames, NULL);
}

/*********************************************************************
 * @fn      SensorTagHum
 *
 * @brief   Initialization function for the SensorTag humidity sensor
 *
 * @param   none
 *
 * @return  none
 */
void SensorTagHum_init(void)
{
  // Add service
  Humidity_addService();

  // Register callbacks with profile
  Humidity_registerAppCBs(&sensorCallbacks);

  // Initialize the module state variables
  sensorPeriod = SENSOR_DEFAULT_PERIOD;
  SensorTagHum_reset();
  initCharacteristicValue(SENSOR_PERI, SENSOR_DEFAULT_PERIOD
                          / SENSOR_PERIOD_RESOLUTION, sizeof(uint8_t));

  // Initialize the driver
  SensorHdc1000_init();
}

/*********************************************************************
 * @fn      SensorTagHum_processCharChangeEvt
 *
 * @brief   SensorTag Humidity event handling
 *
 * @param   none
 *
 * @return  none
 */
void SensorTagHum_processCharChangeEvt(uint8_t paramID)
{
  uint8_t newValue;

  switch (paramID)
  {
  case  SENSOR_CONF:
    if ((SensorTag_testResult() & SENSOR_HUM_TEST_BM) == 0)
    {
      sensorConfig = ST_CFG_ERROR;
    }

    if (sensorConfig != ST_CFG_ERROR)
    {
      Humidity_getParameter(SENSOR_CONF, &newValue);

      if (newValue == ST_CFG_SENSOR_DISABLE)
      {
        // Reset characteristics
        initCharacteristicValue(SENSOR_DATA, 0, SENSOR_DATA_LEN);

        // Deactivate task
        Task_setPri(Task_handle(&sensorTask), -1);
      }
      else
      {
        // Activate task
        Task_setPri(Task_handle(&sensorTask), SENSOR_TASK_PRIORITY);
      }

      sensorConfig = newValue;
    }
    else
    {
      // Make sure the previous characteristics value is restored
      initCharacteristicValue(SENSOR_CONF, sensorConfig, sizeof(uint8_t));
    }
    break;

  case SENSOR_PERI:
    Humidity_getParameter(SENSOR_PERI, &newValue);
    sensorPeriod = newValue * SENSOR_PERIOD_RESOLUTION;
    break;

  default:
    // Should not get here
    break;
  }
}

/*********************************************************************
 * @fn      SensorTagHum_reset
 *
 * @brief   Reset characteristics
 *
 * @param   none
 *
 * @return  none
 */
void SensorTagHum_reset(void)
{
  sensorConfig = ST_CFG_SENSOR_DISABLE;
  initCharacteristicValue(SENSOR_DATA, 0, SENSOR_DATA_LEN);
  initCharacteristicValue(SENSOR_CONF, ST_CFG_SENSOR_DISABLE, sizeof(uint8_t));
}

/*********************************************************************
* Private functions
*/


/*********************************************************************
 * @fn      sensorTaskFxn
 *
 * @brief   The task loop of the humidity readout task
 *
 * @param   a0 - not used
 *
 * @param   a1 - not used
 *
 * @return  none
 */
static void sensorTaskFxn(UArg a0, UArg a1)
{
  typedef union {
    struct {
      //uint16_t rawTemp, rawHum; //Length of sensor(humidity) data in bytes is 4 (2*16bit = 32bit = 4bytes)
      uint8_t sensor_data[20];
        //uint32_t rawTemp, rawHum; //Length of sensor(humidity) data in bytes is 8 (2*32bit = 64bit = 8bytes)
    } v;
    uint8_t a[SENSOR_DATA_LEN];
  } Data_t;
  uint16_t test_rawTemp = 0;
  uint16_t test_rawHum = 0;


  // Register task with BLE stack
  ICall_registerApp(&sensorSelfEntity, &sensorSem);

  // Deactivate task (active only when measurement is enabled)
  Task_setPri(Task_handle(&sensorTask), -1);

  // Task loop
  while (true)
  {
    if (sensorConfig == ST_CFG_SENSOR_ENABLE)
    {
      Data_t data;

      // 1. Start temperature measurement
      SensorHdc1000_start();
      DELAY_MS(HUM_DELAY_PERIOD);

      // 2. Read data
      //SensorHdc1000_read(&data.v.rawTemp, &data.v.rawHum);
      SensorHdc1000_read(&test_rawTemp, &test_rawHum);

      /*
      LowerByteTemp = (uint8_t)data.v.rawTemp;
      UpperByte = (uint8_t)(data.v.rawTemp >> 8);
      ccmSetup.clearAndCipherText[0]=LowerByte;
      ccmSetup.clearAndCipherText[1]=UpperByte;

      LowerByteHum = (uint8_t)data.v.rawHum;
      UpperByteHum = (uint8_t)(data.v.rawHum >> 8);
      ccmSetup.clearAndCipherText[2]=LowerByte;
      ccmSetup.clearAndCipherText[3]=UpperByte;
      */

      LowerByteTemp = (uint8_t)test_rawTemp;
      UpperByteTemp = (uint8_t)(test_rawTemp >> 8);
      ccmSetup.clearAndCipherText[0]=LowerByteTemp;
      ccmSetup.clearAndCipherText[1]=UpperByteTemp;

      LowerByteHum = (uint8_t)test_rawHum;
      UpperByteHum = (uint8_t)(test_rawHum >> 8);
      ccmSetup.clearAndCipherText[2]=LowerByteHum;
      ccmSetup.clearAndCipherText[3]=UpperByteHum;
        

      //TODO: Encrypt sensor data here

        // Initialize Crypto driver structures
        CryptoCC26XX_init();

        // Open the crypto hardware with non-exclusive access and default parameters.
        handle = CryptoCC26XX_open(Board_CRYPTO, false, NULL);

        if (handle == NULL) {
            //System_abort("CryptoCC26XX did not open");
            cryptoOpen = 0;
        }else{
            cryptoOpen = 1;
        }

        // Allocate a key storage location in the hardware
        keyIndex = CryptoCC26XX_allocateKey(handle, ccmSetup.keyLocation, (const uint32_t *) ccmSetup.key);
        if (keyIndex == CRYPTOCC26XX_STATUS_ERROR) {
            //System_abort("Key Location was not allocated.");
            keyLocation = 0;
        } else {
            keyLocation = 1;
        }

        // Encrypt and authenticate the message
        CryptoCC26XX_Transac_init((CryptoCC26XX_Transaction *) &trans, CRYPTOCC26XX_OP_AES_CCM);
        trans.keyIndex   = keyIndex;
        trans.authLength = macLength;
        trans.nonce  = (char *) ccmSetup.nonce;
        trans.header = (char *) ccmSetup.header;
        trans.fieldLength  = 3;
        trans.msgInLength  = clearTextLength;
        trans.headerLength = aadLength;
        trans.msgIn  = (char *) &(ccmSetup.clearAndCipherText[0]);                // Message is encrypted in place
        trans.msgOut = (char *) &(ccmSetup.clearAndCipherText[clearTextLength]);//&clearAndCipherText_test[clearTextLength]; // MAC will be written to this position
        status = CryptoCC26XX_transact(handle, (CryptoCC26XX_Transaction *) &trans);


        if (status != CRYPTOCC26XX_STATUS_SUCCESS) {
            //System_abort("Encryption and signing failed.");
            encryption_AND_signing = 0;
        } else {
            encryption_AND_signing = 1;
        }

        for(int i = 0; i < 20; i ++)
        {
            data.v.sensor_data[i] = ccmSetup.clearAndCipherText[i];
        }



		
        // Decrypt and authenticate message
        CryptoCC26XX_Transac_init((CryptoCC26XX_Transaction *) &trans, CRYPTOCC26XX_OP_AES_CCMINV);
        trans.keyIndex   = keyIndex;
        trans.authLength = macLength;
        trans.nonce  = (char *) ccmSetup.nonce;
        trans.header = (char *) ccmSetup.header;
        trans.fieldLength  = 3;
        trans.msgInLength  = cipherTextLength;
        trans.headerLength = aadLength;
        trans.msgIn  = (char *) &(ccmSetup.clearAndCipherText[0]);                // Message is decrypted in place
        trans.msgOut = (char *) &(ccmSetup.clearAndCipherText[clearTextLength]);  // Points to the MAC, is used as input here

        // Do AES-CCM decryption and authentication
        status = CryptoCC26XX_transact(handle, (CryptoCC26XX_Transaction *) &trans);
        if(status != CRYPTOCC26XX_STATUS_SUCCESS){
            //System_abort("Decryption and authentication failed.");
            decrytion_AND_ath = 0;
        }
        else {
            decrytion_AND_ath = 1;
        }



        // Release the key location
        status = CryptoCC26XX_releaseKey(handle, &keyIndex);
        if (status != CRYPTOCC26XX_STATUS_SUCCESS) {
            //System_abort("Key release was not successful.");
            keyRealease = 0;
        } else {
            keyRealease = 1;
        }

        /*
        test_rawTemp = data.v.rawTemp;
        test_rawHum = data.v.rawHum;

        data.v.rawTemp = test_rawTemp;
        data.v.rawHum = test_rawHum;

        data.v.rawTemp = 10;
        data.v.rawHum = 20;
        */

        // 3. Send data
        Humidity_setParameter(SENSOR_DATA, SENSOR_DATA_LEN, data.a);

        //reset sensor_data array
        for(int i = 0; i < 20; i ++)
        {
            data.v.sensor_data[i] = 0;
        }

        // 4. Wait until next cycle
        DELAY_MS(sensorPeriod - HUM_DELAY_PERIOD);
    }
    else
    {
        DELAY_MS(SENSOR_DEFAULT_PERIOD);
    }
  }
}

/*********************************************************************
 * @fn      sensorConfigChangeCB
 *
 * @brief   Callback from Humidity Service indicating a value change
 *
 * @param   paramID - parameter ID of the value that was changed.
 *
 * @return  none
 */
static void sensorConfigChangeCB(uint8_t paramID)
{
  // Wake up the application thread
  SensorTag_charValueChangeCB(SERVICE_ID_HUM, paramID);
}

/*********************************************************************
 * @fn      initCharacteristicValue
 *
 * @brief   Initialize a characteristic value
 *
 * @param   paramID - parameter ID of the value is to be cleared
 *
 * @param   value - value to initialize with
 *
 * @param   paramLen - length of the parameter
 *
 * @return  none
 */
static void initCharacteristicValue(uint8_t paramID, uint8_t value,
                                    uint8_t paramLen)
{
  uint8_t data[SENSOR_DATA_LEN];

  memset(data,value,paramLen);
  Humidity_setParameter(paramID, paramLen, data);
}
#endif // EXCLUDE_HUM

/*********************************************************************
*********************************************************************/

I am getting the humidity data in my android app which i have built using cordova framework. Crypto drivers also have built in function for decryption but i want to decrypt my humidity data in my mobile app.. So how can i do that?

Also give me some hints that how can i ensure that my data is properly encrypted?