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

CryptoCell CC310 AES CCM* CRYS_FATAL_ERROR after 2nd decrypt operation

Hello guys,

During implementation of a test set for CryptoCell AES CCM* functionality i'm facing some issue with the CryptoCell.

Encryption works fine without any issue. When it comes to the decryption parts only first test set passed whereas the second fails with error code 0x00F5000, CRYS_FATAL_ERROR.

Initialization covers following steps:

NRF_CRYPTOCELL->ENABLE = 1;

SaSi_LibInit()

CRYS_AESCCMStar_Init()

the test cases are the following 2 where it does not matter if you swap them.

   aes_ccms_dec_suite_t aes_ccms_dec_suite[] = {

    {
        { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* key */
        0, /* tag len */
        { 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x04 }, /* nonce */
        { 0x69, 0x98, 0x03, 0x33, 0x63, 0xbb, 0xaa, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x03}, /* a vector */
        { 0x92, 0xe8, 0xad, 0xca, 0x53, 0x81, 0xbf, 0xd0, 0x5b, 0xdd, 0xf3, 0x61, 0x09, 0x09, 0x82, 0xe6, 0x2c,
           0x61, 0x01, 0x4e, 0x7b, 0x34, 0x4f, 0x09}, /* c vector (m + tag) */
        0, /* len_a */
        20, /* len_m */
        2, /* CCM L */
        { 0x14, 0xaa, 0xbb, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
            0x0c, 0x0d, 0x0e, 0x0f } /* expected plaintext */
    },
      {
        { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* key */
        4, /* tag len */
        { 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x05 }, /* nonce */
        { 0x69, 0x98, 0x03, 0x33, 0x63, 0xbb, 0xaa, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x03 }, /* a vector */
        { 0x92, 0xe8, 0xad, 0xca, 0x53, 0x81, 0xbf, 0xd0, 0x5b, 0xdd, 0xf3, 0x61, 0x09, 0x09, 0x82, 0xe6, 0x2c,
            0x61, 0x01, 0x4e, 0x7b, 0x34, 0x4f, 0x09 }, /* c vector (m + tag) */
        15, /* len_a */
        24, /* len_c */
        2, /* CCM L */
        { 0x14, 0xaa, 0xbb, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
            0x0c, 0x0d, 0x0e, 0x0f } /* expected plaintext */
      },
   };
   
foreach aes_ccms_dec_suite[]
 
CRYS_AESCCMStar(
                SASI_AES_DECRYPT,
                key,
                CRYS_AES_Key128BitSize,
                nonce,
                (15-l), 
                a,
                len_a,
                m,
                *len_m,
                m,
                len_mac,
                &m[*len_m]
);

Calling SaSi_LibFini makes no sense for me. And somesthing like CRYS_AESCCM_Finish is not existing.

I also tried to initialze the user context again before i call any crypto operation using CRYS_AESCCMStar_Init with Encrypt or Decrypt respectivly - without success. Which brought me to the point leaving that call aside which had no consequences so far.

Any considerations what might be issue, or do i miss something? Is there any other documentation of the library API than https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v14.2.0%2Fgroup__cryptocell__api.html ?

Best regards

Chris

Parents Reply Children
  • Please do test with modification I've proposed and let me know if there is any difference. So all arguments to function cryptoengine_aes_ccms_dec shall be changed from suite[i] to suite[0]

  • Maybe I am wrong but I think you shall update second test suit:
    24, /* len_c */  to  20, /* len_c */.

    With this modification it is working fine with suite iteration.

  • suite iteration works fine for me. Your right the memcmp fails because of array size.

    using:

    if(memcmp(suite[i].c, suite[i].expected_plaintext, (suite[i].len_c - suite[i].len_tag)) == 0)

    compares the wished context

  • Please use test vectors from attached file and let me know if you still see CRYS_FATAL_ERROR.

    In my case updating second decryption vector in decryption  suit helped and I don't see CRYS_FATAL_ERROR any more.

    You can leave interation as you have it.

    #include "stdint.h"
    #include "stdio.h"
    #include <string.h>
    
    #include "board.h"
    #include "cryptoengine.h"
    #include "leds.h"
    
    typedef struct
    {
       uint8_t key[16];
       uint8_t len_tag;
       uint8_t nonce[13];
       uint8_t a[15];
       uint8_t m[20 + 4];
       uint8_t len_a;
       uint8_t len_m;
       uint8_t l;
       uint8_t expected_ciphertext[24];
    } aes_ccms_enc_suite_t;
    
    typedef struct
    {
       uint8_t key[16];
       uint8_t len_tag;
       uint8_t nonce[13];
       uint8_t a[15];
       uint8_t c[20 + 4];
       uint8_t len_a;
       uint8_t len_c;
       uint8_t l;
       uint8_t expected_plaintext[20];
    } aes_ccms_dec_suite_t;
    
    
    static int hang(uint8_t error_code) {
    
       error_code ? leds_error_on() : leds_error_off();
    
       while (1);
    
       return 0;
    }
    
    
    static owerror_t run_aes_ccms_enc_suite(aes_ccms_enc_suite_t* suite, uint8_t test_suite_len) {
       uint8_t i = 0;
       uint8_t success = 0;
    
       for(i = 0; i < test_suite_len; i++) {
          if(cryptoengine_aes_ccms_enc(suite[i].a,
                                       suite[i].len_a,
                                       suite[i].m,
                                       &suite[i].len_m,
                                       suite[i].nonce,
                                       suite[i].l,
                                       suite[i].key,
                                       suite[i].len_tag) == E_SUCCESS) {
    
                                          if(memcmp(suite[i].m, suite[i].expected_ciphertext, suite[i].len_m) == 0) {
                                             success++;
                                          }
                                       }
       }
       return success == test_suite_len ? E_SUCCESS : E_FAIL;
    }
    
    static owerror_t run_aes_ccms_dec_suite(aes_ccms_dec_suite_t* suite, uint8_t test_suite_len) {
       uint8_t i = 0;
       uint8_t success = 0;
       
       owerror_t ret;
    
       for(i = 0; i < test_suite_len; i++)
       {
    
          ret = cryptoengine_aes_ccms_dec(suite[i].a,
                                       suite[i].len_a,
                                       suite[i].c,
                                       &suite[i].len_c,
                                       suite[i].nonce,
                                       suite[i].l,
                                       suite[i].key,
                                       suite[i].len_tag);
          if (ret == E_SUCCESS) 
          {
              if(memcmp(suite[i].c, suite[i].expected_plaintext, suite[i].len_c) == 0)
              {
                  success++;
              }
          }
       }
       return success == test_suite_len ? E_SUCCESS : E_FAIL;
    }
    
    
    /**
    \brief The program starts executing here.
    */
    int main(void) {
       uint8_t fail = 0;
    
       aes_ccms_enc_suite_t aes_ccms_enc_suite[] = {
    
          { /* example case len_a and Mval = 0 */
             { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* key */
             0x0, /* tag_len */
             { 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x04 }, /* nonce */
             { 0x69, 0x98, 0x03, 0x33, 0x63, 0xbb, 0xaa, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x03}, /* a vector */
             { 0x14, 0xaa, 0xbb, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
             0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00 }, /* m vector */
             0, /* len_a */
             20, /* len_m */
             2, /* CCM L */
             { 0x92, 0xe8, 0xad, 0xca, 0x53, 0x81, 0xbf, 0xd0, 0x5b, 0xdd, 0xf3, 0x61, 0x09, 0x09, 0x82, 0xe6, 0x2c,
             0x61, 0x01, 0x4e, 0x7b, 0x34, 0x4f, 0x09 } /* expected_ciphertext */
          },
          {
             { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* key */
             4, /* tag_len */
             { 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x05 }, /* nonce */
             { 0x69, 0x98, 0x03, 0x33, 0x63, 0xbb, 0xaa, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x03}, /* a vector */
             { 0x14, 0xaa, 0xbb, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
             0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00 }, /* m vector + 4 octets for authentication tag */
             15, /* len_a */
             20, /* len_m */
             2, /* CCM L */
             { 0x92, 0xe8, 0xad, 0xca, 0x53, 0x81, 0xbf, 0xd0, 0x5b, 0xdd, 0xf3, 0x61, 0x09, 0x09, 0x82, 0xe6, 0x2c,
             0x61, 0x01, 0x4e, 0x7b, 0x34, 0x4f, 0x09 } /* expected ciphertext */
          }
       };
    
       aes_ccms_dec_suite_t aes_ccms_dec_suite[] = {
    
          {
             { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* key */
             0, /* tag len */
             { 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x04 }, /* nonce */
             { 0x69, 0x98, 0x03, 0x33, 0x63, 0xbb, 0xaa, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x03}, /* a vector */
             { 0x92, 0xe8, 0xad, 0xca, 0x53, 0x81, 0xbf, 0xd0, 0x5b, 0xdd, 0xf3, 0x61, 0x09, 0x09, 0x82, 0xe6, 0x2c,
             0x61, 0x01, 0x4e, 0x7b, 0x34, 0x4f, 0x09}, /* c vector (m + tag) */
             0, /* len_a */
             20, /* len_m */
             2, /* CCM L */
             { 0x14, 0xaa, 0xbb, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
             0x0c, 0x0d, 0x0e, 0x0f } /* expected plaintext */
          },
          {
             { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* key */
             4, /* tag len */
             { 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x05 }, /* nonce */
             { 0x69, 0x98, 0x03, 0x33, 0x63, 0xbb, 0xaa, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x03 }, /* a vector */
             { 0x92, 0xe8, 0xad, 0xca, 0x53, 0x81, 0xbf, 0xd0, 0x5b, 0xdd, 0xf3, 0x61, 0x09, 0x09, 0x82, 0xe6, 0x2c,
             0x61, 0x01, 0x4e, 0x7b, 0x34, 0x4f, 0x09 }, /* c vector (m + tag) */
             15, /* len_a */
             20, /* len_c */
             2, /* CCM L */
             { 0x14, 0xaa, 0xbb, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
             0x0c, 0x0d, 0x0e, 0x0f } /* expected plaintext */
          }
       };
    
    
       board_init();
    
       if (run_aes_ccms_enc_suite(aes_ccms_enc_suite, sizeof(aes_ccms_enc_suite)/sizeof(aes_ccms_enc_suite[0])) == E_FAIL) {
          fail++;
       }
    
       if (run_aes_ccms_dec_suite(aes_ccms_dec_suite, sizeof(aes_ccms_dec_suite)/sizeof(aes_ccms_dec_suite[0])) == E_FAIL) {
          fail++;
       }
    
    
    
       return hang(fail);
    }
    
    

  • compare fails because inverse transformation seems not delivering the expected plaintext.

    which is in fact the reverse input data from the encryption tets set

Related