bdk: se: handle original and updated IV in one go

IV set now requires a size where the second block is updated IV
IV clear now clears both.
This commit is contained in:
CTCaer
2026-01-06 22:28:18 +02:00
parent d442390e9b
commit b4ca6cae21
2 changed files with 11 additions and 20 deletions

View File

@@ -131,6 +131,9 @@ static int _se_execute_finalize()
static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot) static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot)
{ {
if (dst_size > SE_LL_MAX_SIZE || src_size > SE_LL_MAX_SIZE)
return 0;
ll_src_ptr = NULL; ll_src_ptr = NULL;
ll_dst_ptr = NULL; ll_dst_ptr = NULL;
@@ -254,13 +257,14 @@ void se_aes_key_set(u32 ks, const void *key, u32 size)
} }
} }
void se_aes_iv_set(u32 ks, const void *iv) void se_aes_iv_set(u32 ks, const void *iv, u32 size)
{ {
u32 data[SE_AES_IV_SIZE / sizeof(u32)]; u32 data[SE_AES_MAX_KEY_SIZE / sizeof(u32)];
memcpy(data, iv, SE_AES_IV_SIZE); memcpy(data, iv, size);
for (u32 i = 0; i < (SE_AES_IV_SIZE / sizeof(u32)); i++) for (u32 i = 0; i < (size / sizeof(u32)); i++)
{ {
// QUAD UPDATED_IV bit is automatically set by PKT macro.
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(ORIGINAL_IV) | SE_KEYTABLE_PKT(i); SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(ORIGINAL_IV) | SE_KEYTABLE_PKT(i);
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data[i]; SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data[i];
} }
@@ -292,22 +296,14 @@ void se_aes_key_clear(u32 ks)
void se_aes_iv_clear(u32 ks) void se_aes_iv_clear(u32 ks)
{ {
for (u32 i = 0; i < (SE_AES_IV_SIZE / sizeof(u32)); i++) for (u32 i = 0; i < (SE_AES_MAX_KEY_SIZE / sizeof(u32)); i++)
{ {
// QUAD UPDATED_IV bit is automatically set by PKT macro.
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(ORIGINAL_IV) | SE_KEYTABLE_PKT(i); SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(ORIGINAL_IV) | SE_KEYTABLE_PKT(i);
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0; SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0;
} }
} }
void se_aes_iv_updated_clear(u32 ks)
{
for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++)
{
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(UPDATED_IV) | SE_KEYTABLE_PKT(i);
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0;
}
}
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *seed) int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *seed)
{ {
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_MODE(MODE_KEY128) | SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTABLE); SE(SE_CONFIG_REG) = SE_CONFIG_DEC_MODE(MODE_KEY128) | SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTABLE);
@@ -652,7 +648,6 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
srk[3] = PMC(APBDEV_PMC_SECURE_SCRATCH7); srk[3] = PMC(APBDEV_PMC_SECURE_SCRATCH7);
// Decrypt context. // Decrypt context.
se_aes_key_clear(3);
se_aes_key_set(3, srk, SE_KEY_128_SIZE); se_aes_key_set(3, srk, SE_KEY_128_SIZE);
se_aes_crypt_cbc(3, DECRYPT, keys, SE_AES_KEYSLOT_COUNT * keysize, keys, SE_AES_KEYSLOT_COUNT * keysize); se_aes_crypt_cbc(3, DECRYPT, keys, SE_AES_KEYSLOT_COUNT * keysize, keys, SE_AES_KEYSLOT_COUNT * keysize);
se_aes_key_clear(3); se_aes_key_clear(3);
@@ -669,7 +664,6 @@ int se_aes_cmac_128(u32 ks, void *hash, const void *src, u32 size)
// Generate sub key (CBC with zeroed IV, basically ECB). // Generate sub key (CBC with zeroed IV, basically ECB).
se_aes_iv_clear(ks); se_aes_iv_clear(ks);
se_aes_iv_updated_clear(ks);
if (!se_aes_crypt_hash(ks, ENCRYPT, subkey, SE_KEY_128_SIZE, subkey, SE_KEY_128_SIZE)) if (!se_aes_crypt_hash(ks, ENCRYPT, subkey, SE_KEY_128_SIZE, subkey, SE_KEY_128_SIZE))
goto out; goto out;
@@ -682,8 +676,6 @@ int se_aes_cmac_128(u32 ks, void *hash, const void *src, u32 size)
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_MEMORY) | SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_MEMORY) |
SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) | SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_HASH(HASH_ENABLE) |
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT); SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
se_aes_iv_clear(ks);
se_aes_iv_updated_clear(ks);
u32 num_blocks = (size + 0xF) >> 4; u32 num_blocks = (size + 0xF) >> 4;
if (num_blocks > 1) if (num_blocks > 1)

View File

@@ -27,11 +27,10 @@ u32 se_key_acc_ctrl_get(u32 ks);
/*! AES Key Management Functions */ /*! AES Key Management Functions */
void se_aes_key_set(u32 ks, const void *key, u32 size); void se_aes_key_set(u32 ks, const void *key, u32 size);
void se_aes_iv_set(u32 ks, const void *iv); void se_aes_iv_set(u32 ks, const void *iv, u32 size);
void se_aes_key_get(u32 ks, void *key, u32 size); void se_aes_key_get(u32 ks, void *key, u32 size);
void se_aes_key_clear(u32 ks); void se_aes_key_clear(u32 ks);
void se_aes_iv_clear(u32 ks); void se_aes_iv_clear(u32 ks);
void se_aes_iv_updated_clear(u32 ks);
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *seed); int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *seed);
void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize); void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize);
/*! Encryption Functions */ /*! Encryption Functions */