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.

CC2640R2F: Issue encrypting using AES in CCM mode for data lengths greater than 16

Part Number: CC2640R2F

TI,

I'm having an issue when encrypting using AES in CCM mode for data lengths greater than 16. I am following the example in the documentation:

http://software-dl.ti.com/simplelink/esd/simplelink_cc2640r2_sdk/1.50.00.58/exports/docs/tidrivers/doxygen/html/_crypto_c_c26_x_x_8h.html#CRYPTO_USE_CASES  

The code works fine for examples where ‘clearTextLength’ is <= 16, but fails if a value > 16 is given for the length (return code != Success). I have tested for the specific case in the example (text length = 16), and for shorter text lengths (CCM does not restrict the length to be a multiple of bytes)

You should be able to repeat the test by using the example code with the text length extended by 1 byte to 17 bytes.

Please will you look as this.

  • /*
     * Copyright (c) 2015-2017, 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.
     */
    
    /*
     *  ======== empty.c ========
     */
    
    /* For usleep() */
    #include <unistd.h>
    #include <stdint.h>
    #include <stddef.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/crypto/CryptoCC26XX.h>
    // #include <ti/drivers/I2C.h>
    // #include <ti/drivers/SDSPI.h>
    // #include <ti/drivers/SPI.h>
    // #include <ti/drivers/UART.h>
    // #include <ti/drivers/Watchdog.h>
    
    /* Board Header file */
    #include "Board.h"
    #include <xdc/runtime/System.h>
    
    #define macLength           (4)
    #define clearTextLength     (21)
    #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).
        uint8_t verificationMAC[macLength];             // Location that the recalculated and encrypted MAC is stored during decryption.
    } 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','a','0','0','0','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;
    
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        // Declaration (typically done in a task)
        CryptoCC26XX_Handle      handle;
        CryptoCC26XX_Params      params;
        bool                     exclusiveAccess = false;
        // Initialize Crypto driver
        CryptoCC26XX_init();
        // Configure CryptoCC26XX parameters.
        CryptoCC26XX_Params_init(&params);
        // Attempt to open CryptoCC26XX.
        handle = CryptoCC26XX_open(Board_CRYPTO0, exclusiveAccess, &params);
        if (!handle) {
            System_printf("CryptoCC26XX did not open");
        }
    
        // 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.");
        }
    
        // 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.");
        }
    
    
        /* 1 second delay */
        uint32_t time = 1;
    
        /* Call driver init functions */
        GPIO_init();
        // I2C_init();
        // SDSPI_init();
        // SPI_init();
        // UART_init();
        // Watchdog_init();
    
        /* Turn on user LED */
        GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
    
        while (1) {
            sleep(time);
            GPIO_toggle(Board_GPIO_LED0);
        }
    }
    

    I took the code from the example and copied it into the empty example in the SDK. I don't see any issues running the code with the length larger than 16. 

  • Thanks for looking into this.

    Please will you also confirm your example works with SDK1.30.

    Thanks.

  • It looks like it also runs with SDK 1.3
  • I have compared the example in detail against the code I was running, and the difference appears to be the size of the header (aad) data. If the clear text length > 16 bytes and the header length = 0 then I see return code 11; if I set the header length to 1 or more then the function works as expected (return code = 0; I haven’t checked the output).

    As far as I know, it is valid to use the algorithm with the aad length (trans.headerLength) set to 0; please can you confirm?
  • I need to check with the engineer implementing the driver. He has been on vacation and I think he is OOO today, I will update when I have talked with him.
  • AAD length = 0 should work. As far as I understand ADD length = 0 and cleartext = 20 was used as one test case for testing the driver.

    I also set

    #define aadLength (0)

    in the code I posted earlier and the code seems to be running without issues.