Update BDK to Hekate 6.0.5
This commit is contained in:
246
bdk/sec/se.c
246
bdk/sec/se.c
@@ -23,8 +23,8 @@
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/timer.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
typedef struct _se_ll_t
|
||||
{
|
||||
@@ -33,7 +33,8 @@ typedef struct _se_ll_t
|
||||
vu32 size;
|
||||
} se_ll_t;
|
||||
|
||||
se_ll_t *ll_dst, *ll_src;
|
||||
se_ll_t ll_src, ll_dst;
|
||||
se_ll_t *ll_src_ptr, *ll_dst_ptr; // Must be u32 aligned.
|
||||
|
||||
static void _gf256_mul_x(void *block)
|
||||
{
|
||||
@@ -69,12 +70,12 @@ static void _gf256_mul_x_le(void *block)
|
||||
|
||||
static void _se_ll_init(se_ll_t *ll, u32 addr, u32 size)
|
||||
{
|
||||
ll->num = 0;
|
||||
ll->num = 0;
|
||||
ll->addr = addr;
|
||||
ll->size = size;
|
||||
}
|
||||
|
||||
static void _se_ll_set(se_ll_t *dst, se_ll_t *src)
|
||||
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;
|
||||
@@ -89,13 +90,16 @@ static int _se_wait()
|
||||
;
|
||||
|
||||
// Check for errors.
|
||||
if ((SE(SE_INT_STATUS_REG) & SE_INT_ERR_STAT) ||
|
||||
if ((SE(SE_INT_STATUS_REG) & SE_INT_ERR_STAT) ||
|
||||
(SE(SE_STATUS_REG) & SE_STATUS_STATE_MASK) != SE_STATUS_STATE_IDLE ||
|
||||
SE(SE_ERR_STATUS_REG) != 0)
|
||||
(SE(SE_ERR_STATUS_REG) != 0)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// T210B01: IRAM/TZRAM/DRAM AHB coherency WAR.
|
||||
if (!tegra_t210 && ll_dst)
|
||||
if (!tegra_t210 && ll_dst_ptr)
|
||||
{
|
||||
u32 timeout = get_tmr_us() + 1000000;
|
||||
// Ensure data is out from SE.
|
||||
@@ -107,7 +111,7 @@ static int _se_wait()
|
||||
}
|
||||
|
||||
// Ensure data is out from AHB.
|
||||
if(ll_dst->addr >= DRAM_START)
|
||||
if (ll_dst_ptr->addr >= DRAM_START)
|
||||
{
|
||||
timeout = get_tmr_us() + 200000;
|
||||
while (AHB_GIZMO(AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID) & MEM_WRQUE_SE_MST_ID)
|
||||
@@ -122,75 +126,52 @@ static int _se_wait()
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot)
|
||||
{
|
||||
ll_dst = NULL;
|
||||
ll_src = NULL;
|
||||
|
||||
if (dst)
|
||||
{
|
||||
ll_dst = (se_ll_t *)malloc(sizeof(se_ll_t));
|
||||
_se_ll_init(ll_dst, (u32)dst, dst_size);
|
||||
}
|
||||
|
||||
if (src)
|
||||
{
|
||||
ll_src = (se_ll_t *)malloc(sizeof(se_ll_t));
|
||||
_se_ll_init(ll_src, (u32)src, src_size);
|
||||
}
|
||||
|
||||
_se_ll_set(ll_dst, ll_src);
|
||||
|
||||
SE(SE_ERR_STATUS_REG) = SE(SE_ERR_STATUS_REG);
|
||||
SE(SE_INT_STATUS_REG) = SE(SE_INT_STATUS_REG);
|
||||
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
|
||||
SE(SE_OPERATION_REG) = op;
|
||||
|
||||
if (is_oneshot)
|
||||
{
|
||||
int res = _se_wait();
|
||||
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
|
||||
if (src)
|
||||
{
|
||||
free(ll_src);
|
||||
ll_src = NULL;
|
||||
}
|
||||
if (dst)
|
||||
{
|
||||
free(ll_dst);
|
||||
ll_dst = NULL;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _se_execute_finalize()
|
||||
{
|
||||
int res = _se_wait();
|
||||
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
// Invalidate data after OP is done.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
|
||||
|
||||
if (ll_src)
|
||||
{
|
||||
free(ll_src);
|
||||
ll_src = NULL;
|
||||
}
|
||||
if (ll_dst)
|
||||
{
|
||||
free(ll_dst);
|
||||
ll_dst = NULL;
|
||||
}
|
||||
ll_src_ptr = NULL;
|
||||
ll_dst_ptr = NULL;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot)
|
||||
{
|
||||
ll_src_ptr = NULL;
|
||||
ll_dst_ptr = NULL;
|
||||
|
||||
if (src)
|
||||
{
|
||||
ll_src_ptr = &ll_src;
|
||||
_se_ll_init(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_src_ptr, ll_dst_ptr);
|
||||
|
||||
SE(SE_ERR_STATUS_REG) = SE(SE_ERR_STATUS_REG);
|
||||
SE(SE_INT_STATUS_REG) = SE(SE_INT_STATUS_REG);
|
||||
|
||||
// Flush data before starting OP.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false);
|
||||
|
||||
SE(SE_OPERATION_REG) = op;
|
||||
|
||||
if (is_oneshot)
|
||||
return _se_execute_finalize();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _se_execute_oneshot(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||
{
|
||||
return _se_execute(op, dst, dst_size, src, src_size, true);
|
||||
@@ -201,8 +182,7 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
|
||||
if (!src || !dst)
|
||||
return 0;
|
||||
|
||||
u8 *block = (u8 *)malloc(SE_AES_BLOCK_SIZE);
|
||||
memset(block, 0, SE_AES_BLOCK_SIZE);
|
||||
u8 *block = (u8 *)calloc(1, SE_AES_BLOCK_SIZE);
|
||||
|
||||
SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1;
|
||||
|
||||
@@ -227,7 +207,7 @@ 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) =
|
||||
(((flags >> 4) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) |(flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG)) ^
|
||||
(((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)
|
||||
SE(SE_RSA_SECURITY_PERKEY_REG) &= ~BIT(rs);
|
||||
@@ -304,8 +284,8 @@ void se_aes_iv_clear(u32 ks)
|
||||
|
||||
int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input)
|
||||
{
|
||||
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_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_CRYPTO_KEYTABLE_DST_REG) = SE_KEYTABLE_DST_KEY_INDEX(ks_dst) | SE_KEYTABLE_DST_WORD_QUAD(KEYS_0_3);
|
||||
|
||||
@@ -333,14 +313,14 @@ int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src,
|
||||
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_VCTRAM_SEL(VCTRAM_AESOUT) |
|
||||
SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP);
|
||||
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_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_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;
|
||||
return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size);
|
||||
@@ -355,8 +335,9 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s
|
||||
{
|
||||
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_CRYPTO_CTR_CNTN(1);
|
||||
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);
|
||||
|
||||
u32 src_size_aligned = src_size & 0xFFFFFFF0;
|
||||
@@ -570,9 +551,9 @@ 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_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);
|
||||
SE(SE_RNG_RESEED_INTERVAL_REG) = 1;
|
||||
@@ -588,9 +569,9 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
||||
u8 *aligned_buf = (u8 *)ALIGN((u32)buf, 0x40);
|
||||
|
||||
// Set Secure Random Key.
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_SRK);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
|
||||
SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_FORCE_RESEED);
|
||||
SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_SRK);
|
||||
SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM);
|
||||
SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_FORCE_RESEED);
|
||||
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
||||
_se_execute_oneshot(SE_OP_START, NULL, 0, NULL, 0);
|
||||
|
||||
@@ -600,7 +581,7 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
||||
for (u32 i = 0; i < SE_AES_KEYSLOT_COUNT; i++)
|
||||
{
|
||||
SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(AES_KEYTABLE) | SE_KEYTABLE_DST_KEY_INDEX(i) |
|
||||
SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_0_3);
|
||||
SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_0_3);
|
||||
|
||||
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
||||
_se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0);
|
||||
@@ -609,7 +590,7 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
||||
if (keysize > SE_KEY_128_SIZE)
|
||||
{
|
||||
SE(SE_CONTEXT_SAVE_CONFIG_REG) = SE_CONTEXT_SRC(AES_KEYTABLE) | SE_KEYTABLE_DST_KEY_INDEX(i) |
|
||||
SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_4_7);
|
||||
SE_CONTEXT_AES_KEY_INDEX(0) | SE_CONTEXT_AES_WORD_QUAD(KEYS_4_7);
|
||||
|
||||
SE(SE_CRYPTO_LAST_BLOCK) = 0;
|
||||
_se_execute_oneshot(SE_OP_CTX_SAVE, aligned_buf, SE_AES_BLOCK_SIZE, NULL, 0);
|
||||
@@ -640,6 +621,51 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
|
||||
se_aes_key_clear(3);
|
||||
}
|
||||
|
||||
|
||||
int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size)
|
||||
{
|
||||
int res = 0;
|
||||
u8 *secret = (u8 *)malloc(0x40);
|
||||
u8 *ipad = (u8 *)malloc(0x40 + src_size);
|
||||
u8 *opad = (u8 *)malloc(0x60);
|
||||
|
||||
if (key_size > 0x40)
|
||||
{
|
||||
if (!se_calc_sha256_oneshot(secret, key, key_size))
|
||||
goto out;
|
||||
memset(secret + 0x20, 0, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(secret, key, key_size);
|
||||
memset(secret + key_size, 0, 0x40 - key_size);
|
||||
}
|
||||
|
||||
u32 *secret32 = (u32 *)secret;
|
||||
u32 *ipad32 = (u32 *)ipad;
|
||||
u32 *opad32 = (u32 *)opad;
|
||||
for (u32 i = 0; i < 0x10; i++)
|
||||
{
|
||||
ipad32[i] = secret32[i] ^ 0x36363636;
|
||||
opad32[i] = secret32[i] ^ 0x5C5C5C5C;
|
||||
}
|
||||
|
||||
memcpy(ipad + 0x40, src, src_size);
|
||||
if (!se_calc_sha256_oneshot(dst, ipad, 0x40 + src_size))
|
||||
goto out;
|
||||
memcpy(opad + 0x40, dst, 0x20);
|
||||
if (!se_calc_sha256_oneshot(dst, opad, 0x60))
|
||||
goto out;
|
||||
|
||||
res = 1;
|
||||
|
||||
out:;
|
||||
free(secret);
|
||||
free(ipad);
|
||||
free(opad);
|
||||
return res;
|
||||
}
|
||||
|
||||
// se_aes_cmac() was derived from Atmosphère's se_compute_aes_cmac
|
||||
int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||
{
|
||||
@@ -648,7 +674,7 @@ int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size)
|
||||
u8 *last_block = (u8 *)calloc(0x10, 1);
|
||||
|
||||
// generate derived key
|
||||
if (!se_aes_crypt_block_ecb(ks, 1, key, key))
|
||||
if (!se_aes_crypt_block_ecb(ks, ENCRYPT, key, key))
|
||||
goto out;
|
||||
_gf256_mul_x(key);
|
||||
if (src_size & 0xF)
|
||||
@@ -693,48 +719,4 @@ out:;
|
||||
free(key);
|
||||
free(last_block);
|
||||
return res;
|
||||
}
|
||||
|
||||
int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size)
|
||||
{
|
||||
int res = 0;
|
||||
u8 *secret = (u8 *)malloc(0x40);
|
||||
u8 *ipad = (u8 *)malloc(0x40 + src_size);
|
||||
u8 *opad = (u8 *)malloc(0x60);
|
||||
|
||||
if (key_size > 0x40)
|
||||
{
|
||||
if (!se_calc_sha256_oneshot(secret, key, key_size))
|
||||
goto out;
|
||||
memset(secret + 0x20, 0, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(secret, key, key_size);
|
||||
memset(secret + key_size, 0, 0x40 - key_size);
|
||||
}
|
||||
|
||||
u32 *secret32 = (u32 *)secret;
|
||||
u32 *ipad32 = (u32 *)ipad;
|
||||
u32 *opad32 = (u32 *)opad;
|
||||
for (u32 i = 0; i < 0x10; i++)
|
||||
{
|
||||
ipad32[i] = secret32[i] ^ 0x36363636;
|
||||
opad32[i] = secret32[i] ^ 0x5C5C5C5C;
|
||||
}
|
||||
|
||||
memcpy(ipad + 0x40, src, src_size);
|
||||
if (!se_calc_sha256_oneshot(dst, ipad, 0x40 + src_size))
|
||||
goto out;
|
||||
memcpy(opad + 0x40, dst, 0x20);
|
||||
if (!se_calc_sha256_oneshot(dst, opad, 0x60))
|
||||
goto out;
|
||||
|
||||
res = 1;
|
||||
|
||||
out:;
|
||||
free(secret);
|
||||
free(ipad);
|
||||
free(opad);
|
||||
return res;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u6
|
||||
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_gen_prng128(void *dst);
|
||||
int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||
int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size);
|
||||
int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size);
|
||||
int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2021 CTCaer
|
||||
* Copyright (c) 2018-2023 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -20,16 +20,17 @@
|
||||
|
||||
#include "tsec.h"
|
||||
#include "tsec_t210.h"
|
||||
#include <memory_map.h>
|
||||
#include <mem/heap.h>
|
||||
#include <mem/mc.h>
|
||||
#include <mem/smmu.h>
|
||||
#include <sec/se_t210.h>
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/kfuse.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/t210.h>
|
||||
#include <mem/heap.h>
|
||||
#include <mem/mc.h>
|
||||
#include <mem/smmu.h>
|
||||
#include <utils/util.h>
|
||||
#include <soc/timer.h>
|
||||
|
||||
// #include <gfx_utils.h>
|
||||
|
||||
@@ -57,9 +58,9 @@ static int _tsec_dma_pa_to_internal_100(int not_imem, int i_offset, int pa_offse
|
||||
else
|
||||
cmd = TSEC_DMATRFCMD_IMEM; // DMA IMEM (Instruction memmory)
|
||||
|
||||
TSEC(TSEC_DMATRFMOFFS) = i_offset;
|
||||
TSEC(TSEC_DMATRFMOFFS) = i_offset;
|
||||
TSEC(TSEC_DMATRFFBOFFS) = pa_offset;
|
||||
TSEC(TSEC_DMATRFCMD) = cmd;
|
||||
TSEC(TSEC_DMATRFCMD) = cmd;
|
||||
|
||||
return _tsec_dma_wait_idle();
|
||||
}
|
||||
@@ -76,16 +77,16 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
||||
|
||||
// Enable clocks.
|
||||
clock_enable_host1x();
|
||||
usleep(2);
|
||||
clock_enable_tsec();
|
||||
clock_enable_sor_safe();
|
||||
clock_enable_sor0();
|
||||
clock_enable_sor1();
|
||||
clock_enable_kfuse();
|
||||
|
||||
kfuse_wait_ready();
|
||||
|
||||
// Disable AHB aperture.
|
||||
mc_disable_ahb_redirect();
|
||||
|
||||
if (type == TSEC_FW_TYPE_NEW)
|
||||
{
|
||||
// Disable all CCPLEX core rails.
|
||||
@@ -95,23 +96,23 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
pmc_enable_partition(POWER_RAIL_CE3, DISABLE);
|
||||
|
||||
// Enable AHB aperture and set it to full mmio.
|
||||
mc_enable_ahb_redirect(true);
|
||||
mc_enable_ahb_redirect();
|
||||
}
|
||||
|
||||
// Configure Falcon.
|
||||
TSEC(TSEC_DMACTL) = 0;
|
||||
TSEC(TSEC_IRQMSET) =
|
||||
TSEC_IRQMSET_EXT(0xFF) |
|
||||
TSEC_IRQMSET_WDTMR |
|
||||
TSEC_IRQMSET_HALT |
|
||||
TSEC_IRQMSET_EXTERR |
|
||||
TSEC_IRQMSET_SWGEN0 |
|
||||
TSEC_IRQMSET_WDTMR |
|
||||
TSEC_IRQMSET_HALT |
|
||||
TSEC_IRQMSET_EXTERR |
|
||||
TSEC_IRQMSET_SWGEN0 |
|
||||
TSEC_IRQMSET_SWGEN1;
|
||||
TSEC(TSEC_IRQDEST) =
|
||||
TSEC_IRQDEST_EXT(0xFF) |
|
||||
TSEC_IRQDEST_HALT |
|
||||
TSEC_IRQDEST_EXTERR |
|
||||
TSEC_IRQDEST_SWGEN0 |
|
||||
TSEC_IRQDEST_HALT |
|
||||
TSEC_IRQDEST_EXTERR |
|
||||
TSEC_IRQDEST_SWGEN0 |
|
||||
TSEC_IRQDEST_SWGEN1;
|
||||
TSEC(TSEC_ITFEN) = TSEC_ITFEN_CTXEN | TSEC_ITFEN_MTHDEN;
|
||||
if (!_tsec_dma_wait_idle())
|
||||
@@ -128,6 +129,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
fwbuf = (u8 *)malloc(SZ_16K);
|
||||
u8 *fwbuf_aligned = (u8 *)ALIGN((u32)fwbuf, 0x100);
|
||||
memcpy(fwbuf_aligned, tsec_ctxt->fw, tsec_ctxt->size);
|
||||
|
||||
TSEC(TSEC_DMATRFBASE) = (u32)fwbuf_aligned >> 8;
|
||||
}
|
||||
|
||||
@@ -180,7 +182,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
mc = page_alloc(1);
|
||||
memcpy(mc, (void *)MC_BASE, SZ_PAGE);
|
||||
mc[MC_IRAM_BOM / 4] = 0;
|
||||
mc[MC_IRAM_TOM / 4] = 0x80000000;
|
||||
mc[MC_IRAM_TOM / 4] = DRAM_START;
|
||||
smmu_map(pdir, MC_BASE, (u32)mc, 1, _READABLE | _NONSECURE);
|
||||
|
||||
// IRAM
|
||||
@@ -197,15 +199,15 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
|
||||
// Execute firmware.
|
||||
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0x34C2E1DA;
|
||||
TSEC(TSEC_STATUS) = 0;
|
||||
TSEC(TSEC_BOOTKEYVER) = 1; // HOS uses key version 1.
|
||||
TSEC(TSEC_BOOTVEC) = 0;
|
||||
TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU;
|
||||
TSEC(TSEC_MAILBOX1) = 0;
|
||||
TSEC(TSEC_MAILBOX0) = 1; // Set HOS key version.
|
||||
TSEC(TSEC_BOOTVEC) = 0;
|
||||
TSEC(TSEC_CPUCTL) = TSEC_CPUCTL_STARTCPU;
|
||||
|
||||
if (type == TSEC_FW_TYPE_EMU)
|
||||
{
|
||||
u32 start = get_tmr_us();
|
||||
u32 k = se[SE_CRYPTO_KEYTABLE_DATA_REG / 4];
|
||||
u32 timeout = get_tmr_us() + 125000;
|
||||
u32 key[16] = {0};
|
||||
u32 kidx = 0;
|
||||
|
||||
@@ -220,7 +222,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
}
|
||||
|
||||
// Failsafe.
|
||||
if ((u32)get_tmr_us() - start > 125000)
|
||||
if ((u32)get_tmr_us() > timeout)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -243,7 +245,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
// for (int i = 0; i < kidx; i++)
|
||||
// gfx_printf("key %08X\n", key[i]);
|
||||
|
||||
// gfx_printf("cpuctl (%08X) mbox (%08X)\n", TSEC(TSEC_CPUCTL), TSEC(TSEC_STATUS));
|
||||
// gfx_printf("cpuctl (%08X) mbox (%08X)\n", TSEC(TSEC_CPUCTL), TSEC(TSEC_MAILBOX1));
|
||||
|
||||
// u32 errst = MC(MC_ERR_STATUS);
|
||||
// gfx_printf(" MC %08X %08X %08X\n", MC(MC_INTSTATUS), errst, MC(MC_ERR_ADR));
|
||||
@@ -259,14 +261,18 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
res = -3;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
u32 timeout = get_tmr_ms() + 2000;
|
||||
while (!TSEC(TSEC_STATUS))
|
||||
while (!TSEC(TSEC_MAILBOX1))
|
||||
{
|
||||
if (get_tmr_ms() > timeout)
|
||||
{
|
||||
res = -4;
|
||||
goto out_free;
|
||||
}
|
||||
if (TSEC(TSEC_STATUS) != 0xB0B0B0B0)
|
||||
}
|
||||
|
||||
if (TSEC(TSEC_MAILBOX1) != 0xB0B0B0B0)
|
||||
{
|
||||
res = -5;
|
||||
goto out_free;
|
||||
@@ -275,23 +281,22 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||
// Fetch result.
|
||||
HOST1X(HOST1X_CH0_SYNC_SYNCPT_160) = 0;
|
||||
u32 buf[4];
|
||||
buf[0] = SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB);
|
||||
buf[1] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB);
|
||||
buf[2] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB);
|
||||
buf[3] = SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB);
|
||||
SOR1(SOR_NV_PDISP_SOR_DP_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_MSB) = 0;
|
||||
SOR1(SOR_NV_PDISP_SOR_TMDS_HDCP_CN_LSB) = 0;
|
||||
buf[0] = SOR1(SOR_DP_HDCP_BKSV_LSB);
|
||||
buf[1] = SOR1(SOR_TMDS_HDCP_BKSV_LSB);
|
||||
buf[2] = SOR1(SOR_TMDS_HDCP_CN_MSB);
|
||||
buf[3] = SOR1(SOR_TMDS_HDCP_CN_LSB);
|
||||
SOR1(SOR_DP_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_TMDS_HDCP_BKSV_LSB) = 0;
|
||||
SOR1(SOR_TMDS_HDCP_CN_MSB) = 0;
|
||||
SOR1(SOR_TMDS_HDCP_CN_LSB) = 0;
|
||||
|
||||
memcpy(tsec_keys, &buf, SE_KEY_128_SIZE);
|
||||
}
|
||||
|
||||
out_free:;
|
||||
out_free:
|
||||
free(fwbuf);
|
||||
|
||||
out:;
|
||||
|
||||
out:
|
||||
// Disable clocks.
|
||||
clock_disable_kfuse();
|
||||
clock_disable_sor1();
|
||||
@@ -301,9 +306,10 @@ out:;
|
||||
bpmp_mmu_enable();
|
||||
bpmp_clk_rate_set(prev_fid);
|
||||
|
||||
// Disable AHB aperture.
|
||||
if (type == TSEC_FW_TYPE_NEW)
|
||||
mc_disable_ahb_redirect();
|
||||
#ifdef BDK_MC_ENABLE_AHB_REDIRECT
|
||||
// Re-enable AHB aperture.
|
||||
mc_enable_ahb_redirect();
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ enum tsec_fw_type
|
||||
{
|
||||
// Retail Hovi Keygen.
|
||||
TSEC_FW_TYPE_OLD = 0, // 1.0.0 - 6.1.0.
|
||||
TSEC_FW_TYPE_EMU = 1, // 6.2.0 emulated enviroment.
|
||||
TSEC_FW_TYPE_EMU = 1, // 6.2.0 emulated environment.
|
||||
TSEC_FW_TYPE_NEW = 2, // 7.0.0+.
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2023 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,
|
||||
@@ -17,8 +17,8 @@
|
||||
#ifndef _TSEC_T210_H_
|
||||
#define _TSEC_T210_H_
|
||||
|
||||
#define TSEC_BOOTKEYVER 0x1040
|
||||
#define TSEC_STATUS 0x1044
|
||||
#define TSEC_MAILBOX0 0x1040
|
||||
#define TSEC_MAILBOX1 0x1044
|
||||
#define TSEC_ITFEN 0x1048
|
||||
#define TSEC_ITFEN_CTXEN BIT(0)
|
||||
#define TSEC_ITFEN_MTHDEN BIT(1)
|
||||
|
||||
Reference in New Issue
Block a user