AES Encryption and Decryption using CCM mode

I am trying to write and code of aes encryption and decryption using ccm mode for my application on nrf52832 controller. I have went through some example on Github for the same and took the function from there the git link is "https://github.com/NordicPlayground/nrf52-esb-ccm-example.git" form this in the common folder took files og ccm_crypt.c and ccm_crypt.h and integrated with my project my project code is.
int main(void)
{
  /* Initialise the system clock */
  InitSysClock();
  /* Initialise the Gpios */
  InitSysGpios();

  // Initialize the CCM
  ccm_crypt_init();

  // Prepare the pair request
  ccm_pair_request_packet_t request_out;
  ccm_passkey_t passkey = {0}; // Replace with your passkey
  uint32_t result = ccm_crypt_pair_request_prepare(passkey, &request_out);

  if (result != CCM_CRYPT_SUCCESS)
  {
    printf("Error preparing pair request\n");
    while(1);
  }

  // Accept the pair request
  result = ccm_crypt_pair_request_accept(passkey, &request_out);

  if (result != CCM_CRYPT_SUCCESS)
  {
    printf("Error accepting pair request\n");
    while(1);
  }

  uint8_t plaintext[16] = "This is a test!"; // Your 16-byte plaintext
  uint8_t encrypted_text[20]; // Encrypted text (16-byte ciphertext + 4-byte MAC)
  uint8_t decrypted_text[16]; // Decrypted text (16-byte plaintext)

  // Encrypt a packet
  result = ccm_crypt_packet_encrypt(plaintext, sizeof(plaintext), encrypted_text);

  if (result != CCM_CRYPT_SUCCESS)
  {
    printf("Error encrypting packet\n");
    while(1);
  }

  // Print the plaintext and the encrypted text
  print_data("Plaintext", plaintext, sizeof(plaintext));
  print_data("Encrypted text", encrypted_text, sizeof(encrypted_text));

  // Now let's decrypt the encrypted text
  result = ccm_crypt_packet_decrypt(encrypted_text, sizeof(encrypted_text) - 1, decrypted_text);

  if (result == CCM_CRYPT_SUCCESS)
  {
    // Print the decrypted text
    print_data("Decrypted text", decrypted_text, sizeof(decrypted_text));
  }
  else
  {
    while(1);
  }

  return 0;
}
Now when I amtrying to execute the code it is getting stuck ccm_crypt_pair_request_prepare(passkey, &request_out); my preduction it is not able to generate the key. Can you Help me with this?

  • Hi PK424,

    The example you followed is very old. It is based on the nRF5 SDK, which is in maintenance mode and is not recommended on any new project. Not only that, but it is also based on an old version of the SDK.

    Unless you have a strong reason to use the nRF5 SDK, I highly recommend you move to the nRF Connect SDK.
    You can find the documentation here: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.6.1/nrf/index.html, and
    cryptography samples for the SDK here: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.6.1/nrf/samples/crypto.html.

    Hieu

  • Hi Hieu

    Thank you for the guidance but can you guide me with how can I use hardware ccm method for encryption and decryption of data without using the nordic's SDK and also the links you provided this link " https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.6.1/nrf/index.html," is out of use it says 'Page not found'.

    PK424

  • Hi PK424,

    It looks like the comma character got combined into the link. Sorry for the inconvenience. Please use this link:
    https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.6.1/nrf/index.html

    I will also fix the previous link.

    In the nRF Connect SDK, the crypto library is setup so that, by default, if the hardware supports the crypto operation, then it will be done by hardware. Otherwise, a software library will be used.

    Hieu

  • Hi Hieu

    Thank you for the link the link is working, but can you guide me with how can I use hardware ccm method without using nRF Connect SDK for encryption and decryption of data.

    PK424

  • Hi Hieu

    I have written the code for AES encryption and decryption for nrf52832 the code is

    int main(void)

    {

    // Define the key, nonce, and input data

    aes_nonce_key_t nk = {

    .key = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},

    .nonce = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C},

    .scratch = {0} // Initialize scratch area

    };

    uint8_t input[16] = "Hello, World!";

    uint8_t encrypted[20];

    uint8_t decrypted[16];

    /* Bootloader code */

    /* Initialize the system clock */

    InitSysClock();

    /* Initialize the system gpios */

    InitSysGpio();

    /* Initialize the UARTE0 */

    InitHostCon();

    // Encrypt the data

    aes_encrypt(&nk, input, encrypted);

    // Decrypt the data

    aes_decrypt(&nk, encrypted, decrypted, sizeof(decrypted));

    // Print the input data

    print_data("Input", input, sizeof(input));

    // Print the encrypted data

    print_data("Encrypted", encrypted, sizeof(encrypted));

    // Print the decrypted data

    print_data("Decrypted", decrypted, sizeof(decrypted));

    // Verify that the decrypted data matches the input data

    if(memcmp(input, decrypted, sizeof(input)) == 0) {

    // Success: The decrypted data matches the input

    printf("Decryption successful: Decrypted data matches input.\n");

    } else {

    // Error: The decrypted data does not match the input

    printf("Decryption failed: Decrypted data does not match input.\n");

    }

    }

    // Function to generate key-stream

    void aes_generate_keystream(aes_nonce_key_t* nk){

    // Enable the CCM

    NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled << CCM_ENABLE_ENABLE_Pos;

    // Set the key and nonce

    NRF_CCM->CNFPTR = (uint32_t) nk;

    // Set the scratch pointer for temporary key-stream storage

    NRF_CCM->SCRATCHPTR = (uint32_t) nk->scratch;

    // Start key-stream generation

    NRF_CCM->TASKS_KSGEN = 1;

    // Wait for key-stream generation to complete

    while (NRF_CCM->EVENTS_ENDKSGEN == 0);

    }

    // Function to encrypt data

    void aes_encrypt(aes_nonce_key_t* nk, uint8_t* input, uint8_t* output){

    // Generate key-stream

    aes_generate_keystream(nk);

    // Set the input and output pointers

    NRF_CCM->INPTR = (uint32_t) input;

    NRF_CCM->OUTPTR = (uint32_t) output;

    // Set mode to encryption

    NRF_CCM->MODE = CCM_MODE_MODE_Encryption;

    // Start the encryption

    NRF_CCM->TASKS_CRYPT = 1;

    // Wait for the encryption to complete

    while (NRF_CCM->EVENTS_ENDCRYPT == 0);

    }

    // Function to decrypt data

    void aes_decrypt(aes_nonce_key_t* nk, uint8_t* input, uint8_t* output, size_t len){

    // Ensure CCM is enabled and configured correctly

    NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled << CCM_ENABLE_ENABLE_Pos;

    // Set the key and nonce

    NRF_CCM->CNFPTR = (uint32_t) nk;

    // Set the input and output pointers

    NRF_CCM->INPTR = (uint32_t) input;

    NRF_CCM->OUTPTR = (uint32_t) output;

    NRF_CCM->MODE = CCM_MODE_MODE_Decryption; // Set mode to decryption

    // Set the packet length

    NRF_CCM->MODE &= ~CCM_MODE_LENGTH_Msk;

    NRF_CCM->MODE |= ((len << CCM_MODE_LENGTH_Pos) & CCM_MODE_LENGTH_Msk);

    // Start the decryption

    NRF_CCM->TASKS_CRYPT = 1;

    while (NRF_CCM->EVENTS_ENDCRYPT == 0); // Wait for the decryption to complete

    // Check MIC status

    if (NRF_CCM->MICSTATUS != 0) {

    printf("MIC check failed.\n");

    } else {

    printf("MIC check passed.\n");

    }

    }

    /* --------------------------------------------------------------------------------*/


    The output of code is

    00> MIC check passed.
    00> Input: 48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 21 00 00 00
    00> Encrypted: 04 d5 9c e9 86 7c 36 17 36 b1 f4 a5 79 21 ff 7b 50 48 00 b0
    00> Decrypted: 48 65 6c 6c 6f 2c 20 57 f3 39 ec 1a 05 af 66 51
    00> Decryption failed: Decrypted data does not match input.


    The output which is generating the decrypted data do not match with the input data.
    Can you pleas guide me with this what is wrong in the code.

Related