bdk: se: do a trivial refactor pass

This commit is contained in:
CTCaer
2026-01-06 22:18:45 +02:00
parent 13c91d2848
commit ca307e78c8
3 changed files with 150 additions and 143 deletions

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2025 CTCaer
* Copyright (c) 2018-2026 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -27,60 +27,54 @@
typedef struct _se_ll_t
{
vu32 num;
vu32 addr;
vu32 size;
u32 num;
u32 addr;
u32 size;
} se_ll_t;
se_ll_t ll_src, ll_dst;
se_ll_t *ll_src_ptr, *ll_dst_ptr; // Must be u32 aligned.
se_ll_t ll_src, ll_dst; // Must be u32 aligned.
se_ll_t *ll_src_ptr, *ll_dst_ptr;
static void _gf256_mul_x(void *block)
static void _se_ls_1bit(void *buf)
{
u8 *pdata = (u8 *)block;
u8 *block = (u8 *)buf;
u32 carry = 0;
for (int i = 0xF; i >= 0; i--)
for (int i = SE_AES_BLOCK_SIZE - 1; i >= 0; i--)
{
u8 b = pdata[i];
pdata[i] = (b << 1) | carry;
u8 b = block[i];
block[i] = (b << 1) | carry;
carry = b >> 7;
}
if (carry)
pdata[0xF] ^= 0x87;
block[SE_AES_BLOCK_SIZE - 1] ^= 0x87;
}
static void _gf256_mul_x_le(void *block)
static void _se_ls_1bit_le(void *buf)
{
u32 *pdata = (u32 *)block;
u32 *block = (u32 *)buf;
u32 carry = 0;
for (u32 i = 0; i < 4; i++)
{
u32 b = pdata[i];
pdata[i] = (b << 1) | carry;
u32 b = block[i];
block[i] = (b << 1) | carry;
carry = b >> 31;
}
if (carry)
pdata[0x0] ^= 0x87;
block[0x0] ^= 0x87;
}
static void _se_ll_init(se_ll_t *ll, u32 addr, u32 size)
static void _se_ll_set(se_ll_t *ll, u32 addr, u32 size)
{
ll->num = 0;
ll->addr = addr;
ll->size = size;
ll->size = size & 0xFFFFFF;
}
static void _se_ll_set(se_ll_t *src, se_ll_t *dst)
{
SE(SE_IN_LL_ADDR_REG) = (u32)src;
SE(SE_OUT_LL_ADDR_REG) = (u32)dst;
}
static int _se_wait()
static int _se_op_wait()
{
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
@@ -127,14 +121,11 @@ static int _se_wait()
static int _se_execute_finalize()
{
int res = _se_wait();
int res = _se_op_wait();
// Invalidate data after OP is done.
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
ll_src_ptr = NULL;
ll_dst_ptr = NULL;
return res;
}
@@ -146,17 +137,20 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src
if (src)
{
ll_src_ptr = &ll_src;
_se_ll_init(ll_src_ptr, (u32)src, src_size);
_se_ll_set(ll_src_ptr, (u32)src, src_size);
}
if (dst)
{
ll_dst_ptr = &ll_dst;
_se_ll_init(ll_dst_ptr, (u32)dst, dst_size);
_se_ll_set(ll_dst_ptr, (u32)dst, dst_size);
}
_se_ll_set(ll_src_ptr, ll_dst_ptr);
// Set linked list pointers.
SE(SE_IN_LL_ADDR_REG) = (u32)ll_src_ptr;
SE(SE_OUT_LL_ADDR_REG) = (u32)ll_dst_ptr;
// Clear status.
SE(SE_ERR_STATUS_REG) = SE(SE_ERR_STATUS_REG);
SE(SE_INT_STATUS_REG) = SE(SE_INT_STATUS_REG);
@@ -183,7 +177,7 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
u32 block[SE_AES_BLOCK_SIZE / sizeof(u32)] = {0};
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
SE(SE_CRYPTO_LAST_BLOCK_REG) = 1 - 1;
memcpy(block, src, src_size);
int res = _se_execute_oneshot(op, block, SE_AES_BLOCK_SIZE, block, SE_AES_BLOCK_SIZE);
@@ -192,19 +186,19 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
return res;
}
static void _se_aes_ctr_set(const void *ctr)
static void _se_aes_counter_set(const void *ctr)
{
u32 data[SE_AES_IV_SIZE / 4];
u32 data[SE_AES_IV_SIZE / sizeof(u32)];
memcpy(data, ctr, SE_AES_IV_SIZE);
for (u32 i = 0; i < SE_CRYPTO_LINEAR_CTR_REG_COUNT; i++)
SE(SE_CRYPTO_LINEAR_CTR_REG + (4 * i)) = data[i];
SE(SE_CRYPTO_LINEAR_CTR_REG + sizeof(u32) * i) = data[i];
}
void se_rsa_acc_ctrl(u32 rs, u32 flags)
{
if (flags & SE_RSA_KEY_TBL_DIS_KEY_ACCESS_FLAG)
SE(SE_RSA_KEYTABLE_ACCESS_REG + 4 * rs) =
SE(SE_RSA_KEYTABLE_ACCESS_REG + sizeof(u32) * rs) =
(((flags >> 4) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) | (flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG)) ^
SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_USE_FLAG;
if (flags & SE_RSA_KEY_LOCK_FLAG)
@@ -214,34 +208,35 @@ void se_rsa_acc_ctrl(u32 rs, u32 flags)
void se_key_acc_ctrl(u32 ks, u32 flags)
{
if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG)
SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks) = ~flags;
SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + sizeof(u32) * ks) = ~flags;
if (flags & SE_KEY_LOCK_FLAG)
SE(SE_CRYPTO_SECURITY_PERKEY_REG) &= ~BIT(ks);
}
u32 se_key_acc_ctrl_get(u32 ks)
{
return SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks);
return SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + sizeof(u32) * ks);
}
void se_aes_key_set(u32 ks, const void *key, u32 size)
{
u32 data[SE_AES_MAX_KEY_SIZE / 4];
u32 data[SE_AES_MAX_KEY_SIZE / sizeof(u32)];
memcpy(data, key, size);
for (u32 i = 0; i < (size / 4); i++)
for (u32 i = 0; i < (size / sizeof(u32)); i++)
{
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT.
// QUAD KEYS_4_7 bit is automatically set by PKT macro.
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(KEYS_0_3) | SE_KEYTABLE_PKT(i);
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data[i];
}
}
void se_aes_iv_set(u32 ks, const void *iv)
{
u32 data[SE_AES_IV_SIZE / 4];
u32 data[SE_AES_IV_SIZE / sizeof(u32)];
memcpy(data, iv, SE_AES_IV_SIZE);
for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++)
for (u32 i = 0; i < (SE_AES_IV_SIZE / sizeof(u32)); 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];
@@ -250,11 +245,12 @@ void se_aes_iv_set(u32 ks, const void *iv)
void se_aes_key_get(u32 ks, void *key, u32 size)
{
u32 data[SE_AES_MAX_KEY_SIZE / 4];
u32 data[SE_AES_MAX_KEY_SIZE / sizeof(u32)];
for (u32 i = 0; i < (size / 4); i++)
for (u32 i = 0; i < (size / sizeof(u32)); i++)
{
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT.
// QUAD KEYS_4_7 bit is automatically set by PKT macro.
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(KEYS_0_3) | SE_KEYTABLE_PKT(i);
data[i] = SE(SE_CRYPTO_KEYTABLE_DATA_REG);
}
@@ -263,16 +259,17 @@ void se_aes_key_get(u32 ks, void *key, u32 size)
void se_aes_key_clear(u32 ks)
{
for (u32 i = 0; i < (SE_AES_MAX_KEY_SIZE / 4); i++)
for (u32 i = 0; i < (SE_AES_MAX_KEY_SIZE / sizeof(u32)); i++)
{
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT.
// QUAD KEYS_4_7 bit is automatically set by PKT macro.
SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(KEYS_0_3) | SE_KEYTABLE_PKT(i);
SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0;
}
}
void se_aes_iv_clear(u32 ks)
{
for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++)
for (u32 i = 0; i < (SE_AES_IV_SIZE / sizeof(u32)); 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;
@@ -288,17 +285,17 @@ void se_aes_iv_updated_clear(u32 ks)
}
}
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *seed)
{
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTABLE);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_MODE(MODE_KEY128) | SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTABLE);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
SE(SE_CRYPTO_LAST_BLOCK_REG) = (SE_AES_BLOCK_SIZE >> 4) - 1;
SE(SE_CRYPTO_KEYTABLE_DST_REG) = SE_KEYTABLE_DST_KEY_INDEX(ks_dst) | SE_KEYTABLE_DST_WORD_QUAD(KEYS_0_3);
return _se_execute_oneshot(SE_OP_START, NULL, 0, input, SE_KEY_128_SIZE);
return _se_execute_oneshot(SE_OP_START, NULL, 0, seed, SE_KEY_128_SIZE);
}
int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
int se_aes_crypt_hash(u32 ks, int enc, void *dst, u32 dst_size, const void *src, u32 src_size)
{
if (enc)
{
@@ -314,64 +311,67 @@ int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src,
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM) |
SE_CRYPTO_HASH(HASH_ENABLE);
}
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
SE(SE_CRYPTO_LAST_BLOCK_REG) = (src_size >> 4) - 1;
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
}
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
int se_aes_crypt_ecb(u32 ks, int enc, void *dst, u32 dst_size, const void *src, u32 src_size)
{
if (enc)
{
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT);
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) |
SE_CRYPTO_XOR_POS(XOR_BYPASS);
}
else
{
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT);
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_MODE(MODE_KEY128) | SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT) |
SE_CRYPTO_XOR_POS(XOR_BYPASS);
}
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
SE(SE_CRYPTO_LAST_BLOCK_REG) = (src_size >> 4) - 1;
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
}
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size)
int se_aes_crypt_cbc(u32 ks, int enc, void *dst, u32 dst_size, const void *src, u32 src_size)
{
if (enc)
{
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) |
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP);
}
else
{
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CONFIG_REG) = SE_CONFIG_DEC_MODE(MODE_KEY128) | SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) |
SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM);
}
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
SE(SE_CRYPTO_LAST_BLOCK_REG) = (src_size >> 4) - 1;
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
}
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src)
int se_aes_crypt_block_ecb(u32 ks, int enc, void *dst, const void *src)
{
return se_aes_crypt_ecb(ks, enc, dst, SE_AES_BLOCK_SIZE, src, SE_AES_BLOCK_SIZE);
}
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr)
{
SE(SE_SPARE_REG) = SE_ECO(SE_ERRATA_FIX_ENABLE);
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) |
SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) |
SE(SE_SPARE_REG) = SE_INPUT_NONCE_LE;
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) |
SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) |
SE_CRYPTO_CTR_CNTN(1);
_se_aes_ctr_set(ctr);
_se_aes_counter_set(ctr);
u32 src_size_aligned = src_size & 0xFFFFFFF0;
u32 src_size_delta = src_size & 0xF;
if (src_size_aligned)
{
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1;
SE(SE_CRYPTO_LAST_BLOCK_REG) = (src_size >> 4) - 1;
if (!_se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size_aligned))
return 0;
}
@@ -384,7 +384,7 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s
return 1;
}
int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize)
int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, void *dst, void *src, u32 secsize)
{
int res = 0;
u32 tmp[SE_AES_BLOCK_SIZE / sizeof(u32)];
@@ -393,7 +393,7 @@ int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst
u8 *psrc = (u8 *)src;
// Generate tweak.
for (int i = 0xF; i >= 0; i--)
for (int i = SE_AES_BLOCK_SIZE - 1; i >= 0; i--)
{
tweak[i] = sec & 0xFF;
sec >>= 8;
@@ -410,7 +410,7 @@ int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst
goto out;
for (u32 j = 0; j < SE_AES_BLOCK_SIZE; j++)
pdst[j] = pdst[j] ^ tweak[j];
_gf256_mul_x(tweak);
_se_ls_1bit(tweak);
psrc += SE_AES_BLOCK_SIZE;
pdst += SE_AES_BLOCK_SIZE;
}
@@ -421,7 +421,7 @@ out:
return res;
}
int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size)
int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size)
{
u32 *pdst = (u32 *)dst;
u32 *psrc = (u32 *)src;
@@ -429,7 +429,7 @@ int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tw
if (regen_tweak)
{
for (int i = 0xF; i >= 0; i--)
for (int i = SE_AES_BLOCK_SIZE - 1; i >= 0; i--)
{
tweak[i] = sec & 0xFF;
sec >>= 8;
@@ -438,9 +438,9 @@ int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tw
return 0;
}
// tweak_exp allows using a saved tweak to reduce _gf256_mul_x_le calls.
// tweak_exp allows using a saved tweak to reduce _se_ls_1bit_le calls.
for (u32 i = 0; i < (tweak_exp << 5); i++)
_gf256_mul_x_le(tweak);
_se_ls_1bit_le(tweak);
u8 orig_tweak[SE_KEY_128_SIZE] __attribute__((aligned(4)));
memcpy(orig_tweak, tweak, SE_KEY_128_SIZE);
@@ -448,12 +448,12 @@ int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tw
// We are assuming a 16 sector aligned size in this implementation.
for (u32 i = 0; i < (sec_size >> 4); i++)
{
for (u32 j = 0; j < 4; j++)
for (u32 j = 0; j < (SE_AES_BLOCK_SIZE / sizeof(u32)); j++)
pdst[j] = psrc[j] ^ ptweak[j];
_gf256_mul_x_le(tweak);
psrc += 4;
pdst += 4;
_se_ls_1bit_le(tweak);
psrc += sizeof(u32);
pdst += sizeof(u32);
}
if (!se_aes_crypt_ecb(crypt_ks, enc, dst, sec_size, dst, sec_size))
@@ -463,17 +463,17 @@ int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tw
ptweak = (u32 *)orig_tweak;
for (u32 i = 0; i < (sec_size >> 4); i++)
{
for (u32 j = 0; j < 4; j++)
for (u32 j = 0; j < (SE_AES_BLOCK_SIZE / sizeof(u32)); j++)
pdst[j] = pdst[j] ^ ptweak[j];
_gf256_mul_x_le(orig_tweak);
pdst += 4;
_se_ls_1bit_le(orig_tweak);
pdst += sizeof(u32);
}
return 1;
}
int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs)
int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs)
{
u8 *pdst = (u8 *)dst;
u8 *psrc = (u8 *)src;
@@ -487,8 +487,6 @@ int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, vo
static void se_calc_sha256_get_hash(void *hash, u32 *msg_left)
{
u32 hash32[SE_SHA_256_SIZE / 4];
// Backup message left.
if (msg_left)
{
@@ -497,8 +495,9 @@ static void se_calc_sha256_get_hash(void *hash, u32 *msg_left)
}
// Copy output hash.
for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++)
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4)));
u32 hash32[SE_SHA_256_SIZE / sizeof(u32)];
for (u32 i = 0; i < (SE_SHA_256_SIZE / sizeof(u32)); i++)
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + sizeof(u32) * i));
memcpy(hash, hash32, SE_SHA_256_SIZE);
}
@@ -525,7 +524,7 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64
// Setup config for SHA256.
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
SE(SE_SHA_CONFIG_REG) = sha_cfg;
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
SE(SE_CRYPTO_LAST_BLOCK_REG) = 1 - 1;
// Set total size to current buffer size if empty.
if (!total_size)
@@ -581,15 +580,14 @@ int se_calc_sha256_finalize(void *hash, u32 *msg_left)
int se_gen_prng128(void *dst)
{
// Setup config for X931 PRNG.
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_HASH(HASH_DISABLE) | SE_CRYPTO_XOR_POS(XOR_BYPASS) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_NORMAL);
//SE(SE_RNG_SRC_CONFIG_REG) =
// SE_RNG_SRC_CONFIG_ENTR_SRC(RO_ENTR_ENABLE) | SE_RNG_SRC_CONFIG_ENTR_SRC_LOCK(RO_ENTR_LOCK_ENABLE);
// Setup config for SP 800-90 PRNG.
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_XOR_POS(XOR_BYPASS) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_NORMAL);
//SE(SE_RNG_SRC_CONFIG_REG) |= SE_RNG_SRC_CONFIG_ENTR_SRC(RO_ENTR_ENABLE); // DRBG. Depends on ENTROPY clock.
SE(SE_RNG_RESEED_INTERVAL_REG) = 1;
SE(SE_CRYPTO_BLOCK_COUNT_REG) = (16 >> 4) - 1;
SE(SE_CRYPTO_LAST_BLOCK_REG) = (16 >> 4) - 1;
// Trigger the operation.
return _se_execute_oneshot(SE_OP_START, dst, 16, NULL, 0);
@@ -652,25 +650,25 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
se_aes_key_clear(3);
}
int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size)
int se_aes_cmac_128(u32 ks, void *hash, const void *src, u32 size)
{
int res = 0;
u32 tmp1[SE_KEY_128_SIZE / sizeof(u32)] = {0};
u32 tmp2[SE_AES_BLOCK_SIZE / sizeof(u32)] = {0};
u8 *key = (u8 *)tmp1;
u8 *subkey = (u8 *)tmp1;
u8 *last_block = (u8 *)tmp2;
// Generate sub key (CBC with zeroed IV, basically ECB).
se_aes_iv_clear(ks);
se_aes_iv_updated_clear(ks);
// Generate sub key
if (!se_aes_crypt_hash(ks, ENCRYPT, key, SE_KEY_128_SIZE, key, SE_KEY_128_SIZE))
if (!se_aes_crypt_hash(ks, ENCRYPT, subkey, SE_KEY_128_SIZE, subkey, SE_KEY_128_SIZE))
goto out;
_gf256_mul_x(key);
if (src_size & 0xF)
_gf256_mul_x(key);
// Generate K1 subkey.
_se_ls_1bit(subkey);
if (size & 0xF)
_se_ls_1bit(subkey); // Convert to K2.
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG);
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_MEMORY) |
@@ -679,34 +677,35 @@ int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size)
se_aes_iv_clear(ks);
se_aes_iv_updated_clear(ks);
u32 num_blocks = (src_size + 0xf) >> 4;
u32 num_blocks = (size + 0xF) >> 4;
if (num_blocks > 1)
{
SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 2;
if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, src_size))
SE(SE_CRYPTO_LAST_BLOCK_REG) = num_blocks - 2;
if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, size))
goto out;
SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_IV_SEL(IV_UPDATED);
}
if (src_size & 0xf)
if (size & 0xF)
{
memcpy(last_block, src + (src_size & ~0xf), src_size & 0xf);
last_block[src_size & 0xf] = 0x80;
memcpy(last_block, src + (size & ~0xF), size & 0xF);
last_block[size & 0xF] = 0x80;
}
else if (src_size >= SE_AES_BLOCK_SIZE)
else if (size >= SE_AES_BLOCK_SIZE)
{
memcpy(last_block, src + src_size - SE_AES_BLOCK_SIZE, SE_AES_BLOCK_SIZE);
memcpy(last_block, src + size - SE_AES_BLOCK_SIZE, SE_AES_BLOCK_SIZE);
}
for (u32 i = 0; i < SE_KEY_128_SIZE; i++)
last_block[i] ^= key[i];
last_block[i] ^= subkey[i];
SE(SE_CRYPTO_LAST_BLOCK_REG) = 0;
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0;
res = _se_execute_oneshot(SE_OP_START, NULL, 0, last_block, SE_AES_BLOCK_SIZE);
u32 *dst32 = (u32 *)dst;
for (u32 i = 0; i < (SE_KEY_128_SIZE / 4); i++)
dst32[i] = SE(SE_HASH_RESULT_REG + (i * 4));
u32 *hash32 = (u32 *)hash;
for (u32 i = 0; i < (SE_AES_CMAC_DIGEST_SIZE / sizeof(u32)); i++)
hash32[i] = SE(SE_HASH_RESULT_REG + sizeof(u32) * i);
out:
return res;

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2019-2022 CTCaer
* Copyright (c) 2019-2026 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -24,26 +24,31 @@
void se_rsa_acc_ctrl(u32 rs, u32 flags);
void se_key_acc_ctrl(u32 ks, u32 flags);
u32 se_key_acc_ctrl_get(u32 ks);
void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize);
/*! AES Key Management Functions */
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_key_get(u32 ks, void *key, u32 size);
void se_aes_key_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 *input);
int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src);
int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize);
int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size);
int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs);
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);
/*! Encryption Functions */
int se_aes_crypt_cbc(u32 ks, int enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_ecb(u32 ks, int enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_block_ecb(u32 ks, int enc, void *dst, const void *src);
int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, void *dst, void *src, u32 secsize);
int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size);
int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs);
/*! Hashing Functions */
int se_aes_crypt_hash(u32 ks, int enc, void *dst, u32 dst_size, const void *src, u32 src_size);
int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr);
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot);
int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size);
int se_calc_sha256_finalize(void *hash, u32 *msg_left);
int se_aes_cmac_128(u32 ks, void *hash, const void *src, u32 size);
/*! Random Functions */
int se_gen_prng128(void *dst);
int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size);
#endif

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2021 CTCaer
* Copyright (c) 2018-2026 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -26,7 +26,6 @@
#define SE_AES_KEYSLOT_COUNT 16
#define SE_RSA_KEYSLOT_COUNT 2
#define SE_MAX_LAST_BLOCK_SIZE 0xFFFFF
#define SE_AES_BLOCK_SIZE 16
#define SE_AES_IV_SIZE 16
@@ -39,9 +38,10 @@
#define SE_SHA_256_SIZE 32
#define SE_SHA_384_SIZE 48
#define SE_SHA_512_SIZE 64
#define SE_RNG_IV_SIZE 16
#define SE_RNG_DT_SIZE 16
#define SE_RNG_KEY_SIZE 16
#define SE_RNG_BLOCK_SIZE 16
#define SE_RNG_IV_SIZE 16
#define SE_RNG_DT_SIZE 16
#define SE_RNG_KEY_SIZE 16
#define SE_RNG_SEED_SIZE (SE_RNG_IV_SIZE + SE_RNG_KEY_SIZE + SE_RNG_DT_SIZE)
#define SE_AES_CMAC_DIGEST_SIZE 16
@@ -50,6 +50,11 @@
#define SE_RSA1536_DIGEST_SIZE 192
#define SE_RSA2048_DIGEST_SIZE 256
#define SE_SHA2_MIN_BLOCK_SIZE 64
#define SE_SHA2_MAX_BLOCK_SIZE 128
#define SE_LL_MAX_SIZE ALIGN_DOWN(0xFFFFFF, SE_SHA2_MAX_BLOCK_SIZE)
#define DECRYPT 0
#define ENCRYPT 1
@@ -211,7 +216,7 @@
#define SE_CRYPTO_LINEAR_CTR_REG 0x308
#define SE_CRYPTO_LINEAR_CTR_REG_COUNT 4
#define SE_CRYPTO_BLOCK_COUNT_REG 0x318
#define SE_CRYPTO_LAST_BLOCK_REG 0x318
#define SE_CRYPTO_KEYTABLE_ADDR_REG 0x31C
#define SE_KEYTABLE_PKT(x) ((x) << 0)
@@ -321,8 +326,6 @@
#define SE_CLK_OVR_ON BIT(2)
#define SE_SPARE_REG 0x80C
#define SE_ERRATA_FIX_DISABLE 0
#define SE_ERRATA_FIX_ENABLE 1
#define SE_ECO(x) ((x) << 0)
#define SE_INPUT_NONCE_LE BIT(0)
#endif