Unable to decrypt AES-CCM encrypted message from Central

Hi,

I was trying to decrypt an encrypted message I send form  my phone using the psa/crypto library. I managed to send the encrypted message over to my board by ble correctly, however when I tried to decrypt the message, I was meet with an error (status -135). I was unable to find any information with regards to this error code. The picture below explains my issue:

As seen from the image, I am able to send the encrypted data from my phone correctly to the board but I am unable decrypt it. I am quite sure I have implemented the decryption process correctly as I did not run into the error log I have set for debugging until the decryption process. Below is the segment of the code I wrote for the decryption:

static size_t received_data_len = 0;
static void bt_receive_cb(struct bt_conn *conn, const uint8_t *const data, uint16_t len)
{
    int err;
    char addr[BT_ADDR_LE_STR_LEN] = { 0 };

    bt_addr_le_to_str(bt_conn_get_dst(conn), addr, ARRAY_SIZE(addr));

    LOG_INF("Received data from: %s", addr);

    // Assuming the received data is encrypted using AES-CCM
    uint8_t nonce[12] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B};
    uint8_t aad[8] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
    uint8_t plaintext[CONFIG_BT_NUS_UART_BUFFER_SIZE] = { 0 };
    size_t plaintext_len = sizeof(plaintext);

    psa_status_t status;

    // Initialize the PSA crypto API
    status = psa_crypto_init();
    if (status != PSA_SUCCESS) {
        LOG_ERR("Failed to initialize PSA crypto API");
        return;
    }

    // Import the AES key into the PSA keystore
    psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES);
    psa_set_key_bits(&key_attributes, 128);
    psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DECRYPT);
    psa_set_key_algorithm(&key_attributes, PSA_ALG_CCM);

    psa_key_id_t key_id;
    uint8_t aes_key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 };
    status = psa_import_key(&key_attributes, aes_key, sizeof(aes_key), &key_id);
    if (status != PSA_SUCCESS) {
        LOG_ERR("Failed to import AES key");
        return;
    }

    // Decrypt the received data using AES-CCM
    status = psa_aead_decrypt(key_id, PSA_ALG_CCM, nonce, sizeof(nonce),
                              aad, sizeof(aad),
                              data, sizeof(data),
                              plaintext, sizeof(plaintext),
                               &plaintext_len);

    LOG_INF("Decryption in progress......");

    if (status == PSA_SUCCESS) {
        LOG_INF("Decryption successful");
        LOG_INF("Decrypted plaintext (hex): ");
        for (size_t i = 0; i < plaintext_len; i++) {
            LOG_INF("%02X", plaintext[i]);
        }
        // Process the decrypted plaintext data
        // ...
    } else {
        LOG_ERR("Decryption failed (status %d)", status);
    }

    if ((received_data_len + len) <= sizeof(received_data)) {
        memcpy(&received_data[received_data_len], data, len);
        received_data_len += len;

        // Log the received data
        LOG_INF("Received data (hex):");
        for (size_t i = 0; i < received_data_len; i++) {
            LOG_INF("0x%02X", received_data[i]);
        }
       
    } else {
        LOG_ERR("Received data exceeds the buffer size");
    }

    for (uint16_t pos = 0; pos != len;) {
        struct uart_data_t *tx = k_malloc(sizeof(*tx));

        if (!tx) {
            LOG_WRN("Not able to allocate UART send data buffer");
            return;
        }

        /* Keep the last byte of TX buffer for potential LF char. */
        size_t tx_data_size = sizeof(tx->data) - 1;

        if ((len - pos) > tx_data_size) {
            tx->len = tx_data_size;
        } else {
            tx->len = (len - pos);
        }

        memcpy(tx->data, &data[pos], tx->len);

        pos += tx->len;

        /* Append the LF character when the CR character triggered
         * transmission from the peer.
         */
        if ((pos == len) && (data[len - 1] == '\r')) {
            tx->data[tx->len] = '\n';
            tx->len++;
        }
       
        /* STEP 8.3 - Forward the data received over Bluetooth LE to the UART peripheral */
        err = uart_tx(uart, tx->data, tx->len, SYS_FOREVER_MS);
        if (err) {
            k_fifo_put(&fifo_uart_tx_data, tx);
        }
    }
}
This is how I formuate my key, aad and nonce in flutter, i make sure to check that its the same as in the code for the board:
final key = KeyParameter(Uint8List.fromList([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10]));
final nonce = Uint8List.fromList([0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B]);
final aad = Uint8List.fromList([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]);
I was wondering if you have any idea as to what is causing this error?
Thanks and regards,
Johan
  • Hi Johan

    The error code -135 means PSA_ERROR_INVALID_ARGUMENT

    The following conditions can result in this error:

    • alg is not an AEAD algorithm.

    • key is not compatible with alg.

    • nonce_length is not valid for use with alg and key.

    • additional_data_length or ciphertext_length are too large for alg.

    Please check out psa_aead_decrypt (function).  

    Regards, 
    Amanda H.

  • Hi Amanda,

    I have validated that I my key is compatible and the nonce length is correct (12 bytes), I have also looked though various sources, but I still encounter the status -135 error. 

    Also, it seem strange that my ciphertext is only 18 bytes as I calculated that it should be 31 bytes:
    • Plaintext size: 2 bytes: [0x01, 0x0C]
    • Nonce size: 12 bytes: [0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B]
    • Additional authentication data (AAD) size: 1 byte: [0x00]
    • Authentication tag size: 16 bytes  
    Total: 2+12+1+16 = 31 bytes
    However, my ciphertext after encryption with AES-CCM (in flutter) is 18 bytes or
    [180, 164, 171, 198, 129, 128, 178, 33, 55, 252, 241, 150, 243, 128, 243, 116, 146, 219]
     
    I tried decrypting this set of data using the PSA_ALG_CCM algorithm with the psa_aead_decrypt function and got the status -135 error. Could this be the problem?
    I am sorry if the question is very basic as I am new to the topic of encryption.
     Thanks,
    Jinhhao
  • Hi Amanda,

    I tried the sample on AES-CCM and have finally zoned down the issue to the key generation part (or in my case key import function). I encrypted a message in flutter (android phone) and send it over to the controller through ble NUS and I declared the same nonce key and aad I used in flutter. It seem that only when I tried to use 

    status_key = psa_import_key(&key_attributes, aes_key, sizeof(aes_key), &key_id);  
    where aes_key is the key I  declared in VScode for the controller: 
    uint8_t aes_key[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 };
    instead of 
    status = psa_generate_key(&key_attributes, &key_handle); (original code in the example)
    that I ran into issue.
    Also, I noticed that the data type for key identifier in the example you linked me to is 
    "psa_key_handle_t" while the data type used in the documentation you linked me to uses "
    psa_key_id_t". While both seem to work (the key is either generated or imported successfully for the aes-ccm example), "psa_key_handle_t" does not work for psa_import_key function.
    Regards,
    Johan
Related