psa_cipher_encrypt_setup() failed with error code -133

I tested AES CBC encryption/decryption on nRF5340 device. But I encountered psa_cipher_encrypt_setup() failed with error code -133. What is meaning of error code -133 and how to fix this issue? Why policy_alg and requested_alg parameters of psa_key_algorithm_permits() are not same?

int nrfAes128Encrypt(void) {
    uint32_t olen;
    psa_status_t status;
    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;

    printk("Encrypting using AES CBC MODE...\n");

    /* Setup the encryption operation */
    status = psa_cipher_encrypt_setup(&operation, _gAes128KeyHandle, PSA_ALG_CBC_NO_PADDING);
    if (status != PSA_SUCCESS) {
        printk("psa_cipher_encrypt_setup() failed! (Error: %d)\n", status);
        return ERROR_AES_ENCRYPT_FAIL;
    }

    /* Generate an IV */
    status = psa_cipher_generate_iv(&operation, _gIv, sizeof(_gIv), &olen);
    if (status != PSA_SUCCESS) {
        printk("psa_cipher_generate_iv() failed! (Error: %d)\n", status);
        return ERROR_AES_ENCRYPT_FAIL;
    }

    /* Perform the encryption */
    status = psa_cipher_update(&operation, m_plain_text,
                   sizeof(m_plain_text), m_encrypted_text,
                   sizeof(m_encrypted_text), &olen);
    if (status != PSA_SUCCESS) {
        printk("psa_cipher_update() failed! (Error: %d)\n", status);
        return ERROR_AES_ENCRYPT_FAIL;
    }

    /* Finalize the encryption */
    status = psa_cipher_finish(&operation, m_encrypted_text + olen,
                   sizeof(m_encrypted_text) - olen,
                   &olen);
    if (status != PSA_SUCCESS) {
        printk("psa_cipher_finish() failed! (Error: %d)\n", status);
        return ERROR_AES_ENCRYPT_FAIL;
    }

    printk("Encryption successful!\n");
    PRINT_HEX("IV", _gIv, sizeof(_gIv));
    PRINT_HEX("Plaintext", m_plain_text, sizeof(m_plain_text));
    PRINT_HEX("Encrypted text", m_encrypted_text, sizeof(m_encrypted_text));

    /* Clean up cipher operation context */
    psa_cipher_abort(&operation);

    return 0;
}

The following are log messages of RTT Viewer.

00> *** Booting Zephyr OS build v3.3.99-ncs1 ***
00> btInit() e
00> btInit() x
00> Starting AES-CBC-NO-PADDING example...
00> Encrypting using AES CBC MODE...
00> Importing AES key...
00> psa_import_key() nrf e
00> psa_cipher_encrypt_setup() nrf e
00> psa_cipher_setup() nrf e
00> psa_key_algorithm_permits() e key_type=9216, policy_alg=71320576, requested_alg=71319552
00> psa_key_algorithm_permits() e key_type=9216, policy_alg=0, requested_alg=71319552
00> psa_key_policy_permits() failed -133
00> psa_get_and_lock_key_slot_with_policy() failed -133
00> psa_cipher_setup() return -133
00> psa_cipher_encrypt_setup() failed! (Error: -133)

Procedures to reproduce this issue are as follows.

1. Unzipping minimal_log_aes.zip to D:\ncs\v2.4.0\nrf\samples\ folder.

2. cd D:\ncs\v2.4.0\nrf\samples\minimal_log_aes

3. west build -b nrf5340dk_nrf5340_cpuapp

4. west flash

5. Rebooting nRF5340 device and connecting to RTT Viewer.

  • Hi, 

    What is meaning of error code -133

    -133 is PSA_ERROR_NOT_PERMITTED which means the requested action is denied by a policy.

    Why policy_alg and requested_alg parameters of psa_key_algorithm_permits() are not same?

    psa_key_algorithm_permits() is used by psa_key_policy_permits() to check whether the algorithmof key is pemited by the policy algorithm or not. 

    psa_key_policy_permits() failed -133
    psa_key_policy_permits returns -133 (PSA_ERROR_NOT_PERMITTED ) means the key algorithm is a specific algorithm, but the policy does not allow it.
    Regards,
    Amanda H.
  • Thanks for your reply! I have fixed this issue by changing nrf_aes.c. The following are log messages of RTT Viewer.

    00> *** Booting Zephyr OS build v3.3.99-ncs1 ***
    00> btInit() e
    00> btInit() x
    00> [00:00:00.974,151] <inf> aes_cbc: Starting AES-CBC-NO-PADDING test 1
    00> [00:00:00.974,456] <inf> aes_cbc: Importing random AES key...
    00> psa_import_key() nrf e
    00> [00:00:00.974,853] <inf> aes_cbc: AES key imported successfully!
    00> [00:00:00.975,189] <inf> aes_cbc: Encrypting using AES CBC MODE...
    00> psa_cipher_encrypt_setup() nrf e
    00> psa_cipher_setup() nrf e
    00> psa_key_algorithm_permits() e key_type=9216, policy_alg=71319552, requested_alg=71319552
    00> psa_cipher_setup() return 0
    00> [00:00:00.976,531] <inf> aes_cbc: Encryption successful!
    00> [00:00:00.976,867] <inf> aes_cbc: Decrypting using AES CBC MODE...
    00> psa_cipher_setup() nrf e
    00> psa_key_algorithm_permits() e key_type=9216, policy_alg=71319552, requested_alg=71319552
    00> psa_cipher_setup() return 0
    00> [00:00:00.977,996] <inf> aes_cbc: Decryption successful!
    00> [00:00:00.978,302] <inf> aes_cbc: Example finished successfully!
    00> [00:00:00.978,607] <

  • /*
     * Copyright (c) 2021 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <zephyr/kernel.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/logging/log.h>
    #include <stdio.h>
    #include <psa/crypto.h>
    #include <psa/crypto_extra.h>
    
    #ifdef CONFIG_BUILD_WITH_TFM
    #include <tfm_ns_interface.h>
    #endif
    
    #define APP_SUCCESS     (0)
    #define APP_ERROR       (-1)
    #define APP_SUCCESS_MESSAGE "Example finished successfully!"
    #define APP_ERROR_MESSAGE "Example exited with error!"
    
    #define PRINT_HEX(p_label, p_text, len)\
        ({\
            LOG_INF("---- %s (len: %u): ----", p_label, len);\
            LOG_HEXDUMP_INF(p_text, len, "Content:");\
            LOG_INF("---- %s end  ----", p_label);\
        })
    
    LOG_MODULE_REGISTER(aes_cbc, LOG_LEVEL_DBG);
    
    /* ====================================================================== */
    /* Global variables/defines for the AES-CBC-NO-PADDING example */
    
    #define NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE (64)
    #define NRF_CRYPTO_EXAMPLE_AES_BLOCK_SIZE (16)
    
    static uint8_t m_iv[NRF_CRYPTO_EXAMPLE_AES_BLOCK_SIZE];
    
    /* Below text is used as plaintext for encryption/decryption */
    static uint8_t m_plain_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE] = {
        "Example string to demonstrate basic usage of AES CBC mode."
    };
    
    static uint8_t m_encrypted_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE];
    static uint8_t m_decrypted_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE];
    
    static psa_key_handle_t key_handle;
    
    static uint8_t _gAes128Key[16] = {
        0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
        0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
    };
    /* ====================================================================== */
    
    int crypto_init(void)
    {
        psa_status_t status;
    
        /* Initialize PSA Crypto */
        status = psa_crypto_init();
        if (status != PSA_SUCCESS)
            return APP_ERROR;
    
        return APP_SUCCESS;
    }
    
    int crypto_finish(void)
    {
        psa_status_t status;
    
        /* Destroy the key handle */
        status = psa_destroy_key(key_handle);
        if (status != PSA_SUCCESS) {
            LOG_INF("psa_destroy_key failed! (Error: %d)", status);
            return APP_ERROR;
        }
    
        return APP_SUCCESS;
    }
    
    int import_key(void)
    {
        psa_status_t status;
    
        LOG_INF("Importing random AES key...");
    
        /* Configure the key attributes */
        psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
    
        psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
        psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
        psa_set_key_algorithm(&key_attributes, PSA_ALG_CBC_NO_PADDING);
        psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES);
        psa_set_key_bits(&key_attributes, 128);
    
        /* Generate a random key. The key is not exposed to the application,
         * we can use it to encrypt/decrypt using the key handle
         */
        status = psa_import_key(&key_attributes, _gAes128Key, 16, &key_handle);;
        if (status != PSA_SUCCESS) {
            LOG_INF("psa_generate_key failed! (Error: %d)", status);
            return APP_ERROR;
        }
    
        /* After the key handle is acquired the attributes are not needed */
        psa_reset_key_attributes(&key_attributes);
    
        LOG_INF("AES key imported successfully!");
    
        return APP_SUCCESS;
    }
    
    int encrypt_cbc_aes(void)
    {
        uint32_t olen;
        psa_status_t status;
        psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
    
        LOG_INF("Encrypting using AES CBC MODE...");
    
        /* Setup the encryption operation */
        status = psa_cipher_encrypt_setup(&operation, key_handle, PSA_ALG_CBC_NO_PADDING);
        if (status != PSA_SUCCESS) {
            LOG_INF("psa_cipher_encrypt_setup failed! (Error: %d)", status);
            return APP_ERROR;
        }
    
        /* Generate an IV */
        status = psa_cipher_generate_iv(&operation, m_iv, sizeof(m_iv), &olen);
        if (status != PSA_SUCCESS) {
            LOG_INF("psa_cipher_generate_iv failed! (Error: %d)", status);
            return APP_ERROR;
        }
    
        /* Perform the encryption */
        status = psa_cipher_update(&operation, m_plain_text,
                       sizeof(m_plain_text), m_encrypted_text,
                       sizeof(m_encrypted_text), &olen);
        if (status != PSA_SUCCESS) {
            LOG_INF("psa_cipher_update failed! (Error: %d)", status);
            return APP_ERROR;
        }
    
        /* Finalize the encryption */
        status = psa_cipher_finish(&operation, m_encrypted_text + olen,
                       sizeof(m_encrypted_text) - olen,
                       &olen);
        if (status != PSA_SUCCESS) {
            LOG_INF("psa_cipher_finish failed! (Error: %d)", status);
            return APP_ERROR;
        }
    
        LOG_INF("Encryption successful!");
        //PRINT_HEX("IV", m_iv, sizeof(m_iv));
        //PRINT_HEX("Plaintext", m_plain_text, sizeof(m_plain_text));
        //PRINT_HEX("Encrypted text", m_encrypted_text, sizeof(m_encrypted_text));
    
        /* Clean up cipher operation context */
        psa_cipher_abort(&operation);
    
        return APP_SUCCESS;
    }
    
    int decrypt_cbc_aes(void)
    {
        uint32_t olen;
        psa_status_t status;
        psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
    
        LOG_INF("Decrypting using AES CBC MODE...");
    
        /* Setup the decryption operation */
        status = psa_cipher_decrypt_setup(&operation, key_handle, PSA_ALG_CBC_NO_PADDING);
        if (status != PSA_SUCCESS) {
            LOG_INF("psa_cipher_decrypt_setup failed! (Error: %d)", status);
            return APP_ERROR;
        }
    
        /* Set the IV generated in encryption */
        status = psa_cipher_set_iv(&operation, m_iv, sizeof(m_iv));
        if (status != PSA_SUCCESS) {
            LOG_INF("psa_cipher_set_iv failed! (Error: %d)", status);
            return APP_ERROR;
        }
    
        /* Perform the decryption */
        status = psa_cipher_update(&operation, m_encrypted_text,
                       sizeof(m_encrypted_text), m_decrypted_text,
                       sizeof(m_decrypted_text), &olen);
        if (status != PSA_SUCCESS) {
            LOG_INF("psa_cipher_update failed! (Error: %d)", status);
            return APP_ERROR;
        }
    
        /* Finalize the decryption */
        status = psa_cipher_finish(&operation, m_decrypted_text + olen,
                       sizeof(m_decrypted_text) - olen,
                       &olen);
        if (status != PSA_SUCCESS) {
            LOG_INF("psa_cipher_finish failed! (Error: %d)", status);
            return APP_ERROR;
        }
    
        //PRINT_HEX("Decrypted text", m_decrypted_text, sizeof(m_decrypted_text));
    
        /* Check the validity of the decryption */
        if (memcmp(m_decrypted_text,
                    m_plain_text,
                    NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE) != 0){
    
            LOG_INF("Error: Decrypted text doesn't match the plaintext");
            return APP_ERROR;
        }
    
        LOG_INF("Decryption successful!");
    
        /*  Clean up cipher operation context */
        psa_cipher_abort(&operation);
    
        return APP_SUCCESS;
    }
    
    int nrfAes128Init(void) {
        return 0;
    }
    
    int nrfAes128Test(const int count) {
        int status;
    
        LOG_INF("Starting AES-CBC-NO-PADDING test %d", count);
        status = crypto_init();
        if (status != APP_SUCCESS) {
            LOG_INF(APP_ERROR_MESSAGE);
            return APP_ERROR;
        }
    
        status = import_key();
        if (status != APP_SUCCESS) {
            LOG_INF(APP_ERROR_MESSAGE);
            return APP_ERROR;
        }
    
        status = encrypt_cbc_aes();
        if (status != APP_SUCCESS) {
            LOG_INF(APP_ERROR_MESSAGE);
            return APP_ERROR;
        }
    
        status = decrypt_cbc_aes();
        if (status != APP_SUCCESS) {
            LOG_INF(APP_ERROR_MESSAGE);
            return APP_ERROR;
        }
    
        status = crypto_finish();
        if (status != APP_SUCCESS) {
            LOG_INF(APP_ERROR_MESSAGE);
            return APP_ERROR;
        }
    
        LOG_INF(APP_SUCCESS_MESSAGE);
    
        return APP_SUCCESS;
    }
    

Related