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.

CC2745R10-Q1: Cryptographic operations using PSA KeyStore

Part Number: CC2745R10-Q1
Other Parts Discussed in Thread: SYSCONFIG, AES-128

Tool/software:

When I try to perform cryptographic operations with the following source code, the return value of psa_crypto_init() is -147 (PSA_ERROR_HARDWARE_FAILURE).
After that, the return value of psa_import_key() becomes -141 (PSA_ERROR_INSUFFICIENT_MEMORY) and cannot import. What is the cause and how can I fix it?
This code is a rewrite of the sample code empty.c.

The environment used is as follows:
・Bord : CC2745R10-Q1
・Debugger : XDS110 SDK : SimpleLink Lowpower f3 ver.8.40.2
・IDE : Code Composer Studio ver.12.8.1
・syscongig : see bellow

 

#include <ti/drivers/cryptoutils/cryptokey/CryptoKeyKeyStore_PSA.h>
#include <ti/drivers/cryptoutils/cryptokey/CryptoKeyKeyStore_PSA_init.h>
#include <ti/drivers/cryptoutils/cryptokey/CryptoKeyKeyStore_PSA_helpers.h>

#include <ti/drivers/AESCBC.h>

void *mainThread(void *arg0)
{
    uint8_t keyingMaterial[16] = {0x1f, 0x8e, 0x49, 0x73, 0x95, 0x3f, 0x3f, 0xb0,
                                  0xbd, 0x6b, 0x16, 0x66, 0x2e, 0x9a, 0x3c, 0x17};
    uint8_t KeyExportData[16] = {0};
    size_t ExportDataLength;
    CryptoKey cryptoKey;
    mbedtls_svc_key_id_t keyID;
    int_fast16_t status;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;

    AESCBC_Handle handle;
    AESCBC_OneStepOperation operation;
    int_fast16_t encryptionResult;

    uint8_t iv[16] =                {0x2f, 0xe2, 0xb3, 0x33, 0xce, 0xda, 0x8f, 0x98,
                                     0xf4, 0xa9, 0x9b, 0x40, 0xd2, 0xcd, 0x34, 0xa8};
    uint8_t plaintext[16] =         {0x45, 0xcf, 0x12, 0x96, 0x4f, 0xc8, 0x24, 0xab,
                                     0x76, 0x61, 0x6a, 0xe2, 0xf4, 0xbf, 0x08, 0x22};
    uint8_t ciphertext[sizeof(plaintext)];

    uint8_t errFlg = 0;


    status = psa_crypto_init();

    // Assign key attributes
    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
    psa_set_key_algorithm(&attributes, PSA_ALG_CBC_NO_PADDING);
    psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
    psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT);
    psa_set_key_bits(&attributes, 128);
    // Set key ID
    GET_KEY_ID(keyID, PSA_KEY_ID_USER_MIN);
    psa_set_key_id(&attributes, keyID);
    // Import the keyingMaterial
    status = psa_import_key(&attributes, keyingMaterial, sizeof(keyingMaterial), &keyID);
    if (status != PSA_SUCCESS)
    {
        errFlg = 1;
    }

    // Initialize cryptoKey for crypto operations
    KeyStore_PSA_initKeyHSM(&cryptoKey, keyID, sizeof(keyingMaterial), NULL);
    // Use the cryptoKey for AESCCM operations

    handle = AESCBC_open(0, NULL);
    AESCBC_OneStepOperation_init(&operation);
    operation.key               = &cryptoKey;
    operation.input             = plaintext;
    operation.output            = ciphertext;
    operation.inputLength       = sizeof(plaintext);
    operation.iv                = iv;
    encryptionResult = AESCBC_oneStepEncrypt(handle, &operation);
    AESCBC_close(handle);

    status = psa_export_key(keyID, KeyExportData, 16, &ExportDataLength);

    status = psa_import_key(&attributes, KeyExportData, sizeof(keyingMaterial), &keyID);

    handle = AESCBC_open(0, NULL);
    AESCBC_OneStepOperation_init(&operation);
    operation.key               = &cryptoKey;
    operation.input             = plaintext;
    operation.output            = ciphertext;
    operation.inputLength       = sizeof(plaintext);
    operation.iv                = iv;
    encryptionResult = AESCBC_oneStepEncrypt(handle, &operation);
    AESCBC_close(handle);

}

  • Hello,

    So there are a couple things to note in the code you provided:

    1. You should not mix PSA and SimpleLink drivers. For instance, you're using PSA, but I also see AESCBC_Handle, and AESCBC_OneStepOperation types, and those are from the SimpleLink driver. PSA is actually a wrapper around the SimpleLink crypto drivers, so that may cause some issues.

    2. You can't call the KeyStore APIs directly. All key management needs to be handled using PSA.

    When I try to perform cryptographic operations with the following source code, the return value of psa_crypto_init() is -147 (PSA_ERROR_HARDWARE_FAILURE).

    This could be because the HSM firmware is not loaded on to the device. Load the HSM firmware, and let me know if it still fails.

    After that, the return value of psa_import_key() becomes -141 (PSA_ERROR_INSUFFICIENT_MEMORY) and cannot import. What is the cause and how can I fix it?

    This could also be because the error above. Do you mind sending me a snapshot of your sysconfig settings regarding PSA + KeyStore?

    Additionally, we do have an example in the SDK that shows psaAeadEncryption: <sdk>\examples\rtos\LP_EM_CC2745R10_Q1\drivers\psaAeadEncrypt

    Best,

    Nima Behmanesh

  • Hello,

    No.1
    I am stating this because it was stated that AES-CBC does not support operations using PSA's API.
    If SimpleLink and PSA APIs should not be confused, does this mean that it is not possible to store the keys for AES-CBC operations in the PSA KeyStore?

    No.2
    I thought I was calling the PSA API for everything, but is there any place in this source code where I am calling the KeyStore API directly?

    I have tried loading the HSM, but it still fails.
    The error content is also the same.
    Please let me know what other measures I can take.

  • Hello,

    No.1
    I am stating this because it was stated that AES-CBC does not support operations using PSA's API.
    If SimpleLink and PSA APIs should not be confused, does this mean that it is not possible to store the keys for AES-CBC operations in the PSA KeyStore?

    What SDK version are you using? Support was added later, so it may be that those release notes/documentation might be old.

    No.2
    I thought I was calling the PSA API for everything, but is there any place in this source code where I am calling the KeyStore API directly?

    Yes, at line 50 of the code provided you are calling a KeyStore API.

    I have written the following code that does an AES-CBC operation using PSA. Before running it, some changes are required to the sysconfig file of the project:

    All that needs to be changed is the number of Volatile AES Keys. Note that I changes AES-128 Plaintext Keys to 1. I see that you're using persistent storage, and sysconfig will be updated so that it states Volatile/Non-Volatile. 

    /* For usleep() */
    #include <unistd.h>
    #include <stdint.h>
    #include <stddef.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <third_party/psa_crypto/include/psa/crypto.h>
    #include <ti/drivers/cryptoutils/hsm/HSMLPF3.h>
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    #define KEY_LIFETIME PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_DEFAULT, PSA_KEY_LOCATION_LOCAL_STORAGE)
    
    uint8_t keyingMaterial[16] = { 0x1f, 0x8e, 0x49, 0x73, 0x95, 0x3f, 0x3f, 0xb0,
                                   0xbd, 0x6b, 0x16, 0x66, 0x2e, 0x9a, 0x3c, 0x17
                                 };
    uint8_t iv[16] =                {0x2f, 0xe2, 0xb3, 0x33, 0xce, 0xda, 0x8f, 0x98,
                                     0xf4, 0xa9, 0x9b, 0x40, 0xd2, 0xcd, 0x34, 0xa8};
    
    uint8_t plaintext[16] =         {0x45, 0xcf, 0x12, 0x96, 0x4f, 0xc8, 0x24, 0xab,
                                     0x76, 0x61, 0x6a, 0xe2, 0xf4, 0xbf, 0x08, 0x22};
    
    uint8_t ciphertext[sizeof(plaintext)];
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        psa_status_t status;
        psa_key_id_t key_id;
        int_fast16_t ret;
    
        status = psa_crypto_init();
        if (status != PSA_SUCCESS)
        {
            while(1);
        }
    
        ret = HSMLPF3_provisionHUK();
        if (ret != HSMLPF3_STATUS_SUCCESS)
        {
            while(1);
        }
    
    
        psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    
        psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
        psa_set_key_algorithm(&attributes, PSA_ALG_CBC_NO_PADDING);
        psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
    
        psa_set_key_lifetime(&attributes, KEY_LIFETIME);
        psa_set_key_bits(&attributes, 128);
    
        key_id = PSA_KEY_ID_USER_MIN;
        psa_set_key_id(&attributes, key_id);
    
        status = psa_import_key(&attributes, keyingMaterial, sizeof(keyingMaterial), &key_id);
        if (status != PSA_SUCCESS)
        {
            while(1);
        }
    
        psa_cipher_operation_t op = PSA_CIPHER_OPERATION_INIT;
        status = psa_cipher_encrypt_setup(&op, key_id, PSA_ALG_CBC_NO_PADDING);
        if (status != PSA_SUCCESS)
        {
            while(1);
        }
    
        status = psa_cipher_set_iv(&op, iv, sizeof(iv));
        if (status != PSA_SUCCESS)
        {
            while(1);
        }
    
        size_t cipher_length = 0;
    
        status = psa_cipher_update(&op,
                                   plaintext,
                                   sizeof(plaintext),
                                   ciphertext,
                                   sizeof(plaintext),
                                   &cipher_length);
    
        if (status != PSA_SUCCESS)
        {
            while(1);
        }
    
        status = psa_cipher_finish(&op,
                                   ciphertext,
                                   sizeof(plaintext),
                                   &cipher_length);
        if (status != PSA_SUCCESS)
        {
            while(1);
        }
    
        while(1);
    }
    
    

    If you try the code above do you still see the hardware failure? 

    Best,

    Nima Behmanesh

  • Thank you very much.

    I was able to perform cryptographic operations with the source code you provided.