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: AES-CCM Encryption

Part Number: CC2650STK
Other Parts Discussed in Thread: CC2640, CC2650

Tool/software: TI-RTOS

If searched the forum for hints, but I didn't get any helpful tips.

I'm using the CC2650STK - Sensortag.

What I try to accomplish is, that the sensor values (humidity and IR- temp)  are encrypted via AES-CCM. Later a RaspberryPi 3 connects to it and collects the data and then decrypts it.

If read the Developers Guide (CC2640 and CC2650 SimpleLink™ Bluetooth® low energy Software Stack 2.2.1) it states that there is a crypto driver. 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. This leads me to the CryptoCC26XX.h File Reference - Part.

I'v used the sample code (inside the sensortag_hum.c - file starting at line  328 --> right after the SensorHdc1000_read(&data.v.rawTemp, &data.v.rawHum)-function):

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


        // 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;

        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;

        // 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]);  // 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;
        }

        // 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;
        }

While I debugged it,  my dummy variables ( cryptoOpen, keyLocation, encryption_AND_signing, decrytion_AND_ath, keyRelease) always got the value 1, which means everything should have worked.. unfortunately I can't access the trans variable (more precise the trans.msgOut, which should be the cipher + the MAC).

I'v also tried the crypto.c/crypto.h (first seen in this thread: e2e.ti.com/.../2298769 ):

uint32_t Plaintext[16] = { 't','h','i','s','i','s','a','p','l','a','i','n','t','e','x','t'};
uint32_t Ciphertext[16]= 0;
uint32_t MsgLength = 16;
uint32_t Nonce[16] = {'t','h','i','s','i','s','a','n','o','n','c','e','1','2','3','4'};
uint32_t status;

CRYPTOAesCbc(Plaintext, Ciphertext, MsgLength, Nonce, CRYPTO_KEY_AREA_0, true, false);
status = CRYPTOAesCbcStatus();
if(status != AES_SUCCESS)
{
  //Error
  encryption_AND_signing = 0;
}else {
  //Success
  encryption_AND_signing = 1;
}

Which leads to a stop of the application (it seems it gets stuck at the CRYPTOAesCbc()-function <-- I'v tried this time another mode (CBC)).

Is there a way to encrypt (using AES-CCM) a value, for example the  uint16_t rawTemp, rawHum of the huminidity typdef union and then sending it like as the normal value? - As far as I know the:  

uint8* const pValue; 

can get up to 512 octets, which should be enough for a encryption-length of (2*16bit = 4 byte + 16byte authentication length).

I appreciate any help and thank you in advance.

  • Hi Eagle5,

    trans.msgOut might be optimized out depending on your compiler settings. The encrypted message gets stored in the clearAndCipherText array after the encryption process. In the sample usage code from the CryptoCC26XX usage guide you referenced, what is the value of clearAndCipherText after the call to CryptoCC26XX_transact in the "Encrypt and authenticate the message" section?
  •  Hi RachelP,

    Unfortunately I can't even see the variable clearAndCipherText while in a debug session.. Also adding ccmSetup.clearAndCipherText to the expressions didn't helped.
    I made the breakpoint right before the decryption would start. So I expect that the ccmSetup.clearAndCipherText array would hold the ciphertext.


  • Hi RachelP,
    I managed to see the variables while debugging now (just declared them as global variables..).

    I'was also able to transmit the encrypted content to the IOS - Sensortag- app where I can see the encrypted cipher of

     ccmSetup.clearAndCipherText = { 't','h','i','s','i','s','a','p','l','a','i','n','t','e','x','t','0','0','0','0' },

    but the problem now is that it encrypts the content twice. Which means on the "first" time it decrypts wihout a problem and gives me the following chiper+mac message:

    	[0]	unsigned char	156 '\x9c'	0x20000935	
    	[1]	unsigned char	79 'O'	0x20000936	
    	[2]	unsigned char	234 '\xea'	0x20000937	
    	[3]	unsigned char	155 '\x9b'	0x20000938	
    	[4]	unsigned char	150 '\x96'	0x20000939	
    	[5]	unsigned char	204 '\xcc'	0x2000093A	
    	[6]	unsigned char	138 '\x8a'	0x2000093B	
    	[7]	unsigned char	136 '\x88'	0x2000093C	
    	[8]	unsigned char	82 'R'	0x2000093D	
    	[9]	unsigned char	44 ','	0x2000093E	
    	[10]	unsigned char	198 '\xc6'	0x2000093F	
    	[11]	unsigned char	162 '\xa2'	0x20000940	
    	[12]	unsigned char	191 '\xbf'	0x20000941	
    	[13]	unsigned char	204 '\xcc'	0x20000942	
    	[14]	unsigned char	162 '\xa2'	0x20000943	
    	[15]	unsigned char	40 '('	0x20000944	
    	[16]	unsigned char	77 'M'	0x20000945	
    	[17]	unsigned char	92 '\'	0x20000946	
    	[18]	unsigned char	144 '\x90'	0x20000947	
    	[19]	unsigned char	124 '|'	0x20000948	

    In the IOS-App I see the following string:

    9c4fea9b 96cc8a88 522cc6a2 bfcca228 4d5c907c

    which is the expected chiper+mac (see the picture below).

    But then it tries again to encrypt, but fails which gives me than this message (this is what I can see with my IOS-app, as soon as the config of the humidity is set to 0x01, the sensor data will be displayed/transmitted):

    74686973 69736170 6c61696e 74657874 a92b8239

    Here is the picture, while debugging:

    As you can see the encryption and signing fails (as you can see the clearAndCipherText is still "the old one" --> it does not match what I see every second time with the IOS-App).

    Do you have a clue, what is wrong?

    Thank you in advance

  • I'v tried also to decrypt the ciphertext, which I have obtained while debugging --> I'm using a python2 script.

    I don't know if its right, but it seems to me that the decryption is somehow wrong?

    because I always get:

    [0]	unsigned char	116 't'	0x20000935	
    [1]	unsigned char	104 'h'	0x20000936	
    [2]	unsigned char	105 'i'	0x20000937	
    [3]	unsigned char	115 's'	0x20000938	
    [4]	unsigned char	105 'i'	0x20000939	
    [5]	unsigned char	115 's'	0x2000093A	
    [6]	unsigned char	97 'a'	0x2000093B	
    [7]	unsigned char	112 'p'	0x2000093C	
    [8]	unsigned char	108 'l'	0x2000093D	
    [9]	unsigned char	97 'a'	0x2000093E	
    [10]	unsigned char	105 'i'	0x2000093F	
    [11]	unsigned char	110 'n'	0x20000940	
    [12]	unsigned char	116 't'	0x20000941	
    [13]	unsigned char	101 'e'	0x20000942	
    [14]	unsigned char	120 'x'	0x20000943	
    [15]	unsigned char	116 't'	0x20000944	
    [16]	unsigned char	77 'M'	0x20000945	
    [17]	unsigned char	92 '\'	0x20000946	
    [18]	unsigned char	144 '\x90'	0x20000947	
    [19]	unsigned char	124 '|'	0x20000948	

    Instead of the original plaintext:

    [0]	unsigned char	116 't'	0x20000935	
    [1]	unsigned char	104 'h'	0x20000936	
    [2]	unsigned char	105 'i'	0x20000937	
    [3]	unsigned char	115 's'	0x20000938	
    [4]	unsigned char	105 'i'	0x20000939	
    [5]	unsigned char	115 's'	0x2000093A	
    [6]	unsigned char	97 'a'	0x2000093B	
    [7]	unsigned char	112 'p'	0x2000093C	
    [8]	unsigned char	108 'l'	0x2000093D	
    [9]	unsigned char	97 'a'	0x2000093E	
    [10]	unsigned char	105 'i'	0x2000093F	
    [11]	unsigned char	110 'n'	0x20000940	
    [12]	unsigned char	116 't'	0x20000941	
    [13]	unsigned char	101 'e'	0x20000942	
    [14]	unsigned char	120 'x'	0x20000943	
    [15]	unsigned char	116 't'	0x20000944	
    [16]	unsigned char	48 '0'	0x20000945	
    [17]	unsigned char	48 '0'	0x20000946	
    [18]	unsigned char	48 '0'	0x20000947	
    [19]	unsigned char	48 '0'	0x20000948	

    Here is also the python script I am using:

    from Cryptodome.Cipher import AES
    from Cryptodome.Random import get_random_bytes
    import base64
    
    
    hdr = b'thisisaheader1'
    plaintext = b'thisisaplaintext0000'
    key = b'\x2B\x7E\x15\x16\x28\xAE\xD2\xA6\xAB\xF7\x15\x88\x09\xCF\x4F\x3C'
    nonce = b'thisisanonce'
    cipher = AES.new(key, AES.MODE_CCM, nonce, mac_len=4)
    cipher.update(hdr)
    ciphertxt = cipher.encrypt(plaintext)
    #msg = nonce, hdr, cipher.encrypt(plaintext), cipher.digest()
    msg = nonce, hdr, ciphertxt, cipher.digest()
    print "message: %s , cipher: %s, mac: %s" %(msg, ciphertxt, cipher.digest())
    
    
    # We assume that the tuple ``msg`` is transmitted to the receiver:
    #nonce, hdr, ciphertext, mac = msg
    
    ciphertext = b'\x9c\x4f\xea\x9b\x96\xcc\x8a\x88\x52\x2c\xc6\xa2\xbf\xcc\xa2' #\x28\4D\x5c\x90\7C'
    
    
    mac = b'\x28\4D\x5c\x90\7C'
    
    print "Nonce: %s" %(nonce)
    print "hdr: %s" %(hdr)
    print("ciphertext: %s" %(ciphertext))
    print("mac: %s" %(mac))
    
    key = b'\x2B\x7E\x15\x16\x28\xAE\xD2\xA6\xAB\xF7\x15\x88\x09\xCF\x4F\x3C'
    cipher = AES.new(key, AES.MODE_CCM, nonce, mac_len=4)
    cipher.update(hdr)
    plaintext = cipher.decrypt(ciphertext)
    try:
        cipher.verify(mac)
        print "The message is authentic: hdr=%s, pt=%s" % (hdr, plaintext)
    except ValueError:
        print "Key incorrect or message corrupted"
    

    As AES-Lib I'm using PyCryptodome here is the link: http://pycryptodome.readthedocs.io/en/latest/src/installation.html

     pip install pycryptodomex

    I also add the sensortag_hum.c file.

    Thank you for your help in advance.

    /******************************************************************************
    
     @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
    
    /*********************************************************************
    *********************************************************************/
    
    

  • Until now encryption and decryption was always right (on the sensor-side) it was a mistake in my python script.

    But the problem with a "double encryption" inside the humidity-task remains.

    I moved the Initialization of the crypto driver to the init function of the humidity task:

    /*********************************************************************
     * @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();
    
      // Initialize Crypto driver structures
      CryptoCC26XX_init();
    }



    And the rest of the crpyto-code (from the example: file:///C:/ti/tirtos_cc13xx_cc26xx_2_20_01_08/products/tidrivers_cc13xx_cc26xx_2_20_01_10/docs/doxygen/html/_crypto_c_c26_x_x_8h.html#CRYPTO_USE_CASES) is left in the taskFxn():

    /*********************************************************************
     * @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];
        } 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)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
    
    
            // 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];
            }
    
    
            // 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;
            }
    
            // 3. Send data
            Humidity_setParameter(SENSOR_DATA, SENSOR_DATA_LEN, data.a);
    
    
            // 4. Wait until next cycle
            DELAY_MS(sensorPeriod - HUM_DELAY_PERIOD);
        }
        else
        {
            DELAY_MS(SENSOR_DEFAULT_PERIOD);
        }
      }
    }



    For debugging (so that I can read the variables I declared them globally):

    // includes and other variables inside the file sensortag_hum.c
    .
    .
    .
    // 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;
    .
    .
    .


    Is it a wrong initialization of the crypto methods? Or do I just wrongly use the crypto methods?

    Thanks in advance