Dear All,
I want to set attributes(BOOT_PROT、DEBUG_PROT、KEY_USAGE、WILDCARD、VERIFY_ONLY) of CSEc keys,but i don't know where to set it?
Hello @wang_q4,
Please refer to AN5401 Getting Started with CSEc Security Module.
the below code is from csec_utils.c (csec_keyconfig_s32k1xx SDK example)
You could add the attributes before it is encrypted.
uint8_t FID = 0x00; // or set FID = WRITE_PROTECTION | BOOT_ PROTECTION | DEBUGGER_PROTECTION | KEY_USAGE | WILDCARD
/* Calculate flag value */
m2Plain[3] |= (FID & 0xF0) >> 4;
m2Plain[4] |= (FID & 0x0F) << 4;
Regards,
Daniel
Hi Daniel
Referring to this figure, I would like to ask if if SFE=0x00, FID=0b00010 should be set in computeM1M2M3 if the key is to be used for CMAC generation, similarly, if SFE=0x01, if the key is to be used for CMAC generation FID=0x000100, I wonder if there is any problem with this understanding.
In addition, I set FID=0b00010 in computeM1M2M3, which caused an error when I updated the key. What was strange was that the first key update was normal, but the error occurred in the second update. Could you please explain?The following is the update I made, please point out if there are any mistakes, thank you very much.
I load the key according to the following code,
but I have returned "STATUS_SEC_KEY_WRITE_PROTECTED" when restoring the factory settings
status_t CSEcDrv_ComputeM1M2M3(uint8_t* p_auth_key, csec_key_id_t auth_id, csec_key_id_t key_id, const uint8_t* p_key, uint32_t counter,
uint8_t* p_uid, uint8_t* p_m1, uint8_t* p_m2, uint8_t* p_m3, bool boot_protection)
{
status_t stat;
uint8_t FID = 0x00;
uint8_t i;
uint8_t iv[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t k1[16];
uint8_t k2[16];
uint8_t m2Plain[32];
uint8_t m1m2[48];
/* Derive K1 and K2 from AuthID */
CSEcDrv_KDF(p_auth_key, key_update_enc_c, k1);
CSEcDrv_KDF(p_auth_key, key_update_mac_c, k2);
/* Compute M1 = UID | ID | AuthID */
for (i = 0; i < 15; i++)
{
p_m1[i] = p_uid[i];
}
p_m1[15] = ((key_id & 0xF) << 4) | (auth_id & 0xF);
/* Compute M2 (C = counter, F = 0) */
for(i = 0; i < 16; i++)
{
m2Plain[i] = 0;
m2Plain[16 + i] = p_key[i];
}
m2Plain[0] = (counter & 0xFF00000) >> 20;
m2Plain[1] = (counter & 0xFF000) >> 12;
m2Plain[2] = (counter & 0xFF0) >> 4;
m2Plain[3] |= (FID & 0xF0) >> 4;
m2Plain[4] |= (FID & 0x0F) << 4;
/* Encrypt M2 */
stat = CSEC_DRV_LoadPlainKey(k1);
if (stat != STATUS_SUCCESS)
{
return stat;
}
stat = CSEC_DRV_EncryptCBC(CSEC_RAM_KEY, m2Plain, 32U, iv, p_m2, 1U);
if (stat != STATUS_SUCCESS)
{
return stat;
}
/* Compute M3 as CMAC(key=k2, m1|m2)*/
for (i = 0; i < 16; i++)
{
m1m2[i] = p_m1[i];
}
for(i = 0; i < 32; i++)
{
m1m2[16 + i] = p_m2[i];
}
stat = CSEC_DRV_LoadPlainKey(k2);
if (stat != STATUS_SUCCESS)
{
return stat;
}
stat = CSEC_DRV_GenerateMAC(CSEC_RAM_KEY, m1m2, 384U, p_m3, 1U);
if (stat != STATUS_SUCCESS)
{
return stat;
}
return STATUS_SUCCESS;
}
status_t CSEcDrv_EraseKeys_Sync(void)
{
status_t stat;
uint8_t auth_key[16];
uint8_t challenge[16];
uint8_t auth[16];
uint8_t auth_plain[31];
uint8_t k[16];
uint8_t uid[15];
uint8_t i;
CSEcDrv_GenerateMasterKey(&auth_key[0]);
CSEcDrv_GetUID_Sync(uid);
CSEcDrv_KDF(auth_key, key_debug_key_c, k);
stat = CSEC_DRV_LoadPlainKey(k);
if (stat != STATUS_SUCCESS)
{
return stat;
}
stat = CSEC_DRV_DbgChal(challenge);
if (stat != STATUS_SUCCESS)
{
return stat;
}
for (i = 0; i < 16; i++)
{
auth_plain[i] = challenge[i];
}
for (i = 0; i < 15; i++)
{
auth_plain[i + 16] = uid[i];
}
stat = CSEC_DRV_GenerateMAC(CSEC_RAM_KEY, auth_plain, 248U, auth, 1U);
if (stat != STATUS_SUCCESS)
{
return stat;
}
stat = CSEC_DRV_DbgAuth(auth);
if (stat != STATUS_SUCCESS)
{
return stat;
}
return stat;
}
Hi @wang_q4,
According to this thread of yours, you have already at least one key protected.
https://community.nxp.com/t5/S32K/CSEs-failed-to-restore-factory-Settings/m-p/1307273#M11340
In this case, it can be erased, unfortunately.
Regards,
Daniel