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.

How to use AES CCM service?

Other Parts Discussed in Thread: TIMAC, CC2530, CC2420

I want to use AES CCM service in sample project in TIMAC 1.5.2.43299 for CC2530, in particular, zaesccmDecryptAuth() function. I have included corresponding headers in application file msa.c:

#include "hal_aes.h"
#include "zaesccm_api.h"

but still get some linking errors

Is there some file missing in project? Or should I do some additional configuration?

  • I assume I need to include library macLibSec_cc2530-Banked.lib. Could somebody explain how to do it in IAR?

  • I did. As I understood for CC2420 CCM mechanism is implemented at HW level and for CC2530, which I am working on, I need to write additional SW. And seems library, which I mentioned above is designed for this purpose. But I am not able to use its API.
  • To solve the link issue, you have to add hal_aes.c and hal_ccm.c under \TIMAC 1.5.2.43299\Components\hal\target\CC2530USB to you project.
  • These files are included in mentioned folder by default.

  • I mean to add them to project files like the following screen shot.

  • Thanks YiKai Chen (1482894).

    I also had to add usb_board_crf.h and usb_req.h files and change configuration of project to Banked for successful build.

    Now when debugging I have issue with using zaesccmDecryptAuth() function.

    I added some code in msa.c for testing purposes:

    unsigned char decrypt = DECRYPT;
    unsigned char Mval = 4;
    unsigned char Nonce[13] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x02, 0x30, 0xC2, 0x00, 0x00, 0x00, 0x7F, 0x05};
    unsigned char M[13] = {0xBC, 0xAD, 0x4A, 0x10, 0xD4, 0x0C, 0x48, 0xD8, 0xFB, 0x57, 0x14, 0x03, 0xA3};
    unsigned short len_m = 13;
    unsigned char A[13] = {0x20, 0xE8, 0x11, 0x00, 0x05, 0xC1, 0xE8, 0xC9, 0x05, 0x7F, 0x00, 0x00, 0x00};
    unsigned short len_a = 13;
    unsigned char AesKey[16] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
    unsigned char MAC[13] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc}; //{0x06, 0xF2, 0x2D, 0xFF};
    unsigned char ccmLVal = 2;

    unsigned char result = (unsigned char) zaesccmDecryptAuth(decrypt, Mval, Nonce, M, len_m, A, len_a, AesKey, MAC, ccmLVal);

    uint16 len = HalUARTWrite(HAL_UART_PORT_0, &result, 1);

     

    ...and debug session is hanging after performing lines highlighted with yellow on screenshot below.

    Not sure how I can troubleshoot this.

  • I have no problem to step over that statement in IAR debug.

  • Could you provide me with sample code or with parameters you are feeding to decryption function? For test purposes.
  • You can refer to red part:

    /**************************************************************************************************
     *
     * @fn          MSA_Init
     *
     * @brief       Initialize the application
     *
     * @param       taskId - taskId of the task after it was added in the OSAL task queue
     *
     * @return      none
     *
     **************************************************************************************************/
    unsigned char decrypt = true;
    unsigned char Mval = 4;
    unsigned char Nonce[13] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x02, 0x30, 0xC2, 0x00, 0x00, 0x00, 0x7F, 0x05};
    unsigned char M[13] = {0xBC, 0xAD, 0x4A, 0x10, 0xD4, 0x0C, 0x48, 0xD8, 0xFB, 0x57, 0x14, 0x03, 0xA3};
    unsigned short len_m = 13;
    unsigned char A[13] = {0x20, 0xE8, 0x11, 0x00, 0x05, 0xC1, 0xE8, 0xC9, 0x05, 0x7F, 0x00, 0x00, 0x00};
    unsigned short len_a = 13;
    unsigned char AesKey[16] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
    unsigned char MAC[13] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc}; //{0x06, 0xF2, 0x2D, 0xFF};
    unsigned char ccmLVal = 2;


    void MSA_Init(uint8 taskId)
    {
      uint8 i;

      /* Initialize the task id */
      MSA_TaskId = taskId;

      /* initialize MAC features */
    #ifdef MSA_FFD
      MAC_InitCoord();
    #else
      MAC_InitDevice();
    #endif

      /* Reset the MAC */
      MAC_MlmeResetReq(TRUE);
     
      /* Initialize MAC beacon. Note that the beacon init must be done
       * after MAC_MlmeResetReq() or some of the functions may be reverted
       * back to non-beacon mode.
       */
    #ifdef MSA_FFD
      MAC_InitBeaconCoord();
    #else
      MAC_InitBeaconDevice();
    #endif

    #ifdef FEATURE_MAC_SECURITY
      /* Initialize the security part of the application */
      MSA_SecurityInit();
    #endif /* FEATURE_MAC_SECURITY */

      /* Initialize the data packet */
      for (i=MSA_HEADER_LENGTH; i<MSA_PACKET_LENGTH; i++)
      {
        msa_Data1[i] = i-MSA_HEADER_LENGTH;
      }

      /* Initialize the echo packet */
      for (i=0; i<MSA_ECHO_LENGTH; i++)
      {
        msa_Data2[i] = 0xEE;
      }

      msa_BeaconOrder = MSA_MAC_BEACON_ORDER;
      msa_SuperFrameOrder = MSA_MAC_SUPERFRAME_ORDER;
      {
        unsigned char result = (unsigned char) zaesccmDecryptAuth(decrypt, Mval, Nonce, M, len_m, A, len_a, AesKey, MAC, ccmLVal);
      }
    ...

    }

  • Hm. Same result. Any idea what can be the problem?
  • Which IAR version do you use?
  • Latest one - 9.30.3
  • I use 9.10.1 and I suggest you to use the same version with me.
  • OK, I've installed 9.10.1. Now it stucks in deadloop in different place

  • I've seen this happen if the aes engine is not initialized with key and or IV/nonce before use. Make sure to initialize the aes engine as well as key and IV/nonce before EACH use.
  • You can add "HalAesInit();" before you call zaesccmDecryptAuth.
  • Thanks Brocklobsta (4737007)  and YiKai Chen (1482894).

    Adding HalAesInit() had help. And it seems important to place it just before calling zaesccmDecryptAuth(). Before I tried to add it to initialization section in msa_main.c and it didn't work.

     HalAesInit();

     unsigned char result = (unsigned char) zaesccmDecryptAuth(decrypt, Mval, Nonce, M, len_m, A, len_a, AesKey, MAC, ccmLVal);

     HalUARTWrite(HAL_UART_PORT_0, &result, 1);

    Now I am getting status for decryption 0x01, which means FAILURE, I suppose. As I understood from looking through the code decryption returns 0x00 (SUCCESS) status, while authentication gives failure. Result is different from what I expect.

    I want to clarify general format of inputs and output, and configuration.

    1. I am using following inputs according to requirement of my project (see below, I had to replace some data with 0xXX because of NDA). Is it generally OK?
    2. I believe MAC here is Message Integrity Code. Right?
    3. Does cleartext replaces cyphertext in message M as output?
    4. Also I have confusion regarding mode. Looking though the code I found instruction AES_SETMODE(ECB). However, I need to use CCM encryption mode. I believe it should be CBC_MAC. Or shouldn't I touch this section at all? Is it working in CCM mode by default?

    unsigned char decrypt = TRUE;
    unsigned char Mval = 4;
    unsigned char Nonce[13] = {0xXX, 0xXX, 0xXX, 0xFF, 0xFE, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x05};
    unsigned char M[13] = {0xB7, 0x5B, 0xB8, 0x1D, 0xE2, 0x85, 0x41, 0x8B, 0xF9, 0xE4, 0xB7, 0x85, 0x80};
    unsigned short len_m = 13;
    unsigned char A[13] = {0x20, 0x01, 0x01, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00};
    unsigned short len_a = 13;
    unsigned char AesKey[16] = {0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX}; 
    unsigned char MAC[4] = {0xC9, 0xBA, 0x1D, 0x21};
    unsigned char ccmLVal = 2;

  • I realized how it works.

    I still didn't get what is MAC exactly. I just feed there empty array with size of encrypted message. Result (decrypted message) is substituting encrypted message M. M is concatenation of useful encrypted message with encrypted MIC/tag (cyphertext, full encrypted message). No additional configuration for encryption mode required. It is handled properly with sub functions. 

    Below is excerpt from zaesccm.h with my comments for quick reference.

    /**
    * Decrypts and authenticates an encrypted text using an MLE key.
    * This function is thread-safe.
    *
    * @param decrypt set to TRUE to decrypt. Set to FALSE to authenticate without decryption.
    * @param Mval length of authentication field in octets // size of MIC/tag, 4 in my case
    * @param N 13 byte nonce // part of IV, other fields of IV are computed automatically
    * @param M octet string 'm' // C || U, C - is useful encrypted data, U - encrypted authentication tag
    * @param len_m length of M[] in octets // total length of encrypted message, in my case 13 (variable) + 4 (fixed)
    * @param A octet string 'a' // authenticated data, not encrypted 
    * @param len_a length of A[] in octets // length of authenticated data
    * @param AesKey Pointer to AES Key or Pointer to Key Expansion buffer. // 128-bit key in my case
    * @param MAC MAC output buffer // I don't know what is this, just put here empty buffer with size of len_m
    * @param ccmLVal ccm L value to be used // 2 in my case
    *
    * @return Zero when successful. Non-zero, otherwise.
    */
    extern signed char zaesccmDecryptAuth(unsigned char decrypt,

    unsigned char Mval, unsigned char *Nonce,
    unsigned char *M, unsigned short len_m,
    unsigned char *A, unsigned short len_a,
    unsigned char *AesKey,
    unsigned char *MAC, unsigned char ccmLVal);

  • Cool! It is good to know you figure out how it works.