CC2745R10-Q1: About Dual-Use Keys

Part Number: CC2745R10-Q1

Tool/software:

Hello,

My environment is as follows:
Board: CC2745R10-Q1
Debugger: XDS110
SDK: SimpleLink Lowpower f3 ver.9.10.00.83
IDE: IAR Embedded Workbench for ARM 9.60.3.7274

Because there is a limit to the number of keys that can be stored in the KeyStore,
I'm considering using the same key for multiple functions.
Is this possible? If so, please tell me how.

In the test code below,
the algorithm is not specified when importing the key:
psa_set_key_algorithm(&attributes, PSA_ALG_NONE);

I would like to specify the algorithm only at the time of use,
psa_raw_key_agreement(PSA_ALG_ECDH, key_id, ‥
psa_sign_hash(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), ‥

This did not work (psa_import_key returned error code -135).

static void vos_store_test( void )
{
    uint8_t myPrivateKey[32] =   {0x96, 0xBF, 0x85, 0x49, 0xC3, 0x79, 0xE4, 0x04,
                                  0xED, 0xA1, 0x08, 0xA5, 0x51, 0xF8, 0x36, 0x23,
                                  0x12, 0xD8, 0xD1, 0xB2, 0xA5, 0xFA, 0x57, 0x06,
                                  0xE2, 0xCC, 0x22, 0x5C, 0xF6, 0xF9, 0x77, 0xC4};
    uint8_t messageHash[32] =    {0xA4, 0x1A, 0x41, 0xA1, 0x2A, 0x79, 0x95, 0x48,
                                  0x21, 0x1C, 0x41, 0x0C, 0x65, 0xD8, 0x13, 0x3A,
                                  0xFD, 0xE3, 0x4D, 0x28, 0xBD, 0xD5, 0x42, 0xE4,
                                  0xB6, 0x80, 0xCF, 0x28, 0x99, 0xC8, 0xA8, 0xC4};
    uint8_t theirPublicKey[65] = {0x04,
                                  // X
                                  0xB7, 0xE0, 0x8A, 0xFD, 0xFE, 0x94, 0xBA, 0xD3,
                                  0xF1, 0xDC, 0x8C, 0x73, 0x47, 0x98, 0xBA, 0x1C,
                                  0x62, 0xB3, 0xA0, 0xAD, 0x1E, 0x9E, 0xA2, 0xA3,
                                  0x82, 0x01, 0xCD, 0x08, 0x89, 0xBC, 0x7A, 0x19,
                                  //Y
                                  0x36, 0x03, 0xF7, 0x47, 0x95, 0x9D, 0xBF, 0x7A,
                                  0x4B, 0xB2, 0x26, 0xE4, 0x19, 0x28, 0x72, 0x90,
                                  0x63, 0xAD, 0xC7, 0xAE, 0x43, 0x52, 0x9E, 0x61,
                                  0xB5, 0x63, 0xBB, 0xC6, 0x06, 0xCC, 0x5E, 0x09};

    int_fast16_t s2t_status;
    uint8_t u1t_Out[100] = {0};
    size_t output_len = 0;

    s2t_status = psa_crypto_init();
    if (s2t_status != PSA_SUCCESS)
    {
        while(1);
    }

    s2t_status = HSMLPF3_provisionHUK();
    if (s2t_status != HSMLPF3_STATUS_SUCCESS)
    {
        while(1);
    }
    
    psa_key_id_t key_id = PSA_KEY_ID_USER_MIN;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
    psa_set_key_usage_flags(&attributes, (PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_SIGN_HASH));
    psa_set_key_algorithm(&attributes, PSA_ALG_NONE);
    psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT);
    psa_set_key_bits(&attributes, 256);
    /* Import the keyingMaterial */
    s2t_status = psa_import_key(&attributes, myPrivateKey, sizeof(myPrivateKey), &key_id);
    if(s2t_status != PSA_SUCCESS)
    {
        while(1);
    }

    s2t_status = psa_raw_key_agreement(PSA_ALG_ECDH,
                                       key_id,
                                       theirPublicKey,
                                       sizeof(theirPublicKey),
                                       u1t_Out,
                                       sizeof(u1t_Out),
                                       &output_len);
    if(s2t_status != PSA_SUCCESS)
    {
        while(1);
    }

    s2t_status = psa_sign_hash(key_id,
                               PSA_ALG_ECDSA(PSA_ALG_SHA_256),
                               messageHash,
                               sizeof(messageHash),
                               u1t_Out,
                               sizeof(u1t_Out),
                               &output_len);
    if(s2t_status != PSA_SUCCESS)
    {
        while(1);
    }
}

Best,

  • Hello,

    I am a little new to the keystore here! But I should be able to help a little with some of our documentation on this:

    Cryptographic keying material may be stored on an embedded system multiple ways.

    • plaintext: in plaintext in flash or RAM
    • key store: in a dedicated hardware database whose entries can not be directly read out.

    Each storage option requires different approaches to handling the keying material when performing a crypto operation. In order to separate these concerns from the API of the various crypto drivers available with TI-RTOS, the CryptoKey type abstracts away from these details. It does not contain any cryptographic keying material itself but instead contains the details necessary for drivers to use the keying material. The driver implementation handles preparing and moving the keying material as necessary to perform the desired crypto operation.

    The same CryptoKey may be passed to crypto APIs of different modes subject to restrictions placed on the key by their storage types. Plaintext keys may be used without restriction while key store keys have their permitted uses restricted when the keying material is loaded. These restrictions are specified in a CryptoKey_SecurityPolicy that is device-specific and depends on the hardware capability of the device.

    Additonally the psaRawKeyAgreement example in the SDK (9.12 F3 SDK) has an example showing how to store/use some keys. 

    I'm considering using the same key for multiple functions.

    When I did a test before with AES crypto I was able to re-use the key on different plaintexts.

    Thanks,
    Alex F

  • Hello,

    I've been able to import the key twice (ECDH, ECDSA) and use psa_raw_key_agreement and psa_sign_hash,
    but I'm looking for a way to import the key once and use both psa_raw_key_agreement and psa_sign_hash.

    Is this possible? If so, please tell me how.

    Best,

  • Hello,

    Just so I am not misunderstanding your question, you want to call psa_import_key(...) once and then use it for both ECDH and ECDSA? Or are you using some other function currently. 

    Thanks,
    Alex F

  • yes, I want to call psa_import_key(...) once and then use it for both ECDH and ECDSA?
    Is this possible? If so, please tell me how.

  • Hello,

    After looking into it some more if we are specifically using the psa_import_key(...) function we cannot re-use the key/call. The reason being is that the psa_import_key function calls the psa_key_attributes which each ECDH and ECDSA have their own specific attributes; so once we call psa_import_key for ECDH or ECDSA we cannot use it for the other algorithm. 

    I've been able to import the key twice (ECDH, ECDSA) and use psa_raw_key_agreement and psa_sign_hash,

    This is the correct path for using the psa_import_key(...) function. 

    Thanks,
    Alex F