Tool/software:
We want to implement a system using key information that exceeds the maximum number of keys registered in the PSA KeyStore (35 keys).
So, after importing the plaintext keys, we export the encrypted keys and store them in the data flash, and then delete the key information in PSAKeyStore with destroy. After that, I thought of re-importing the encrypted key stored in the data flash to perform the cryptographic operation.
To test whether this method is feasible, we compared the results of the cipher operation with the key that was first imported with the following code and the results of the cipher operation with the key that was reimported after exporting that key, and found that the results were completely different.
Is it possible to import as key information that yields the same cipher operation result by setting some parameter?
If this is not possible, is there any other way to handle key information exceeding 35 keys without calling plaintext key information into RAM?
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.9.10
/* 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_HSM_ASSET_STORE)
uint8_t keyingMaterial[16] = { 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b, 0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 };
uint8_t keyingMaterial2[16] = { 0x02, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b, 0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 }; /* FSI_add */
uint8_t iv[16] = { 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30, 0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 };
uint8_t plaintext[16] = { 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x6d, 0x73, 0x67 };
uint8_t ciphertext[16];
uint8_t ciphertext_exp[16]; /* FSI_add */
uint8_t expkey_encflg; /* FSI_add */
uint8_t aescbc_matchflg; /* FSI_add */
uint8_t exported_key[sizeof(keyingMaterial)];
//ciphertest { 0xe3, 0x53, 0x77, 0x9c, 0x10, 0x79, 0xae, 0xb8, 0x27, 0x08, 0x94, 0x2d, 0xbe, 0x77, 0x18, 0x1a };
/*
* ======== mainThread ========
*/
void *mainThread(void *arg0)
{
psa_status_t status;
psa_key_id_t key_id;
size_t exported_key_length;
psa_cipher_operation_t op = PSA_CIPHER_OPERATION_INIT;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
size_t cipher_length = 0;
int_fast16_t ret;
psa_key_id_t key_id_exp; /* FSI_add */
psa_key_id_t key_id_oth; /* FSI_add */
uint8_t i; /* FSI_add */
psa_cipher_operation_t op_exp = PSA_CIPHER_OPERATION_INIT; /* FSI_add */
status = psa_crypto_init();
if (status != PSA_SUCCESS)
{
while(1);
}
ret = HSMLPF3_provisionHUK();
if (ret != HSMLPF3_STATUS_SUCCESS)
{
while(1);
}
/* Import Key*/
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT|PSA_KEY_USAGE_ENCRYPT|PSA_KEY_USAGE_DECRYPT);
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);
}
/* FSI_add_st */
#if 0
/* ★Operation Check. Other Key import */
key_id_oth = PSA_KEY_ID_USER_MIN + 1;
psa_set_key_id(&attributes, key_id_oth);
status = psa_import_key(&attributes, keyingMaterial2, sizeof(keyingMaterial2), &key_id_oth);
if (status != PSA_SUCCESS)
{
while(1);
}
key_id_exp = PSA_KEY_ID_USER_MIN + 2;
psa_set_key_id(&attributes, key_id_exp);
status = psa_import_key(&attributes, keyingMaterial, sizeof(keyingMaterial), &key_id_exp);
if (status != PSA_SUCCESS)
{
while(1);
}
#endif
/* FSI_add_ed */
#if 0
/* AES-CBC Encrypt */
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);
}
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);
}
#endif
#if 1
/* Export Key*/
status = psa_export_key(key_id, exported_key, sizeof(exported_key), &exported_key_length);
if (status != PSA_SUCCESS)
{
while(1);
}
#endif
/* FSI_add_st */
#if 1
/* 3. Export Key Encryption Check */
expkey_encflg = 0;
for ( i = 0; i < 16; i++ )
{
if( exported_key[i] == keyingMaterial[i] )
{
/* Check NG */
}
else
{
expkey_encflg = 1; /* Check OK */
}
}
#endif
#if 1
/* 4. Export Key import */
key_id_exp = PSA_KEY_ID_USER_MIN + 1;
psa_set_key_id(&attributes, key_id_exp);
status = psa_import_key(&attributes, exported_key, sizeof(exported_key), &key_id_exp);
if (status != PSA_SUCCESS)
{
while(1);
}
#endif
#if 1
/* 5. AES-CBC Encrypt (By Export Key) */
status = psa_cipher_encrypt_setup(&op_exp, key_id_exp, PSA_ALG_CBC_NO_PADDING);
if (status != PSA_SUCCESS)
{
while(1);
}
status = psa_cipher_set_iv(&op_exp, iv, sizeof(iv));
if (status != PSA_SUCCESS)
{
while(1);
}
status = psa_cipher_update(&op_exp,
plaintext,
sizeof(plaintext),
ciphertext_exp,
sizeof(plaintext),
&cipher_length);
if (status != PSA_SUCCESS)
{
while(1);
}
status = psa_cipher_finish(&op_exp,
ciphertext_exp,
sizeof(plaintext),
&cipher_length);
if (status != PSA_SUCCESS)
{
while(1);
}
#endif
#if 0
/* 6. AES-CBC Encrypt Result Match Check */
aescbc_matchflg = 1;
for ( i = 0; i < 16; i++ )
{
if( ciphertext_exp[i] == ciphertext[i] )
{
/* Check OK */
}
else
{
aescbc_matchflg = 0; /* Check NG */
}
}
#endif
/* FSI_add_ed */
while(1);
}