Support Mariko, patched Erista
This commit is contained in:
		
							
								
								
									
										314
									
								
								bdk/sec/se.c
									
									
									
									
									
								
							
							
						
						
									
										314
									
								
								bdk/sec/se.c
									
									
									
									
									
								
							| @@ -24,6 +24,7 @@ | |||||||
| #include <memory_map.h> | #include <memory_map.h> | ||||||
| #include <mem/heap.h> | #include <mem/heap.h> | ||||||
| #include <soc/bpmp.h> | #include <soc/bpmp.h> | ||||||
|  | #include <soc/pmc.h> | ||||||
| #include <soc/t210.h> | #include <soc/t210.h> | ||||||
| #include <utils/util.h> | #include <utils/util.h> | ||||||
|  |  | ||||||
| @@ -93,22 +94,21 @@ static int _se_wait() | |||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size) | se_ll_t *ll_dst, *ll_src; | ||||||
|  | static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot) | ||||||
| { | { | ||||||
| 	static se_ll_t *ll_dst = NULL, *ll_src = NULL; | 	ll_dst = NULL; | ||||||
| 	if (!ll_dst) | 	ll_src = NULL; | ||||||
| 	{ |  | ||||||
| 		ll_dst = (se_ll_t *)malloc(sizeof(se_ll_t)); |  | ||||||
| 		ll_src = (se_ll_t *)malloc(sizeof(se_ll_t)); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (dst) | 	if (dst) | ||||||
| 	{ | 	{ | ||||||
|  | 		ll_dst = (se_ll_t *)malloc(sizeof(se_ll_t)); | ||||||
| 		_se_ll_init(ll_dst, (u32)dst, dst_size); | 		_se_ll_init(ll_dst, (u32)dst, dst_size); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (src) | 	if (src) | ||||||
| 	{ | 	{ | ||||||
|  | 		ll_src = (se_ll_t *)malloc(sizeof(se_ll_t)); | ||||||
| 		_se_ll_init(ll_src, (u32)src, src_size); | 		_se_ll_init(ll_src, (u32)src, src_size); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -120,13 +120,49 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src | |||||||
| 	bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); | 	bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); | ||||||
|  |  | ||||||
| 	SE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op); | 	SE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op); | ||||||
|  |  | ||||||
|  | 	if (is_oneshot) | ||||||
|  | 	{ | ||||||
| 		int res = _se_wait(); | 		int res = _se_wait(); | ||||||
|  |  | ||||||
| 		bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); | 		bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); | ||||||
|  |  | ||||||
|  | 		if (src) | ||||||
|  | 			free(ll_src); | ||||||
|  | 		if (dst) | ||||||
|  | 			free(ll_dst); | ||||||
|  |  | ||||||
| 		return res; | 		return res; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int _se_execute_finalize() | ||||||
|  | { | ||||||
|  | 	int res = _se_wait(); | ||||||
|  |  | ||||||
|  | 	bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); | ||||||
|  |  | ||||||
|  | 	if (ll_src) | ||||||
|  | 	{ | ||||||
|  | 		free(ll_src); | ||||||
|  | 		ll_src = NULL; | ||||||
|  | 	} | ||||||
|  | 	if (ll_dst) | ||||||
|  | 	{ | ||||||
|  | 		free(ll_dst); | ||||||
|  | 		ll_dst = NULL; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return res; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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); | ||||||
|  | } | ||||||
|  |  | ||||||
| static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size) | static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size) | ||||||
| { | { | ||||||
| 	if (!src || !dst) | 	if (!src || !dst) | ||||||
| @@ -138,7 +174,7 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr | |||||||
| 	SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; | 	SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; | ||||||
|  |  | ||||||
| 	memcpy(block, src, src_size); | 	memcpy(block, src, src_size); | ||||||
| 	int res = _se_execute(op, block, 0x10, block, 0x10); | 	int res = _se_execute_oneshot(op, block, 0x10, block, 0x10); | ||||||
| 	memcpy(dst, block, dst_size); | 	memcpy(dst, block, dst_size); | ||||||
|  |  | ||||||
| 	free(block); | 	free(block); | ||||||
| @@ -147,9 +183,11 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr | |||||||
|  |  | ||||||
| static void _se_aes_ctr_set(void *ctr) | static void _se_aes_ctr_set(void *ctr) | ||||||
| { | { | ||||||
| 	u32 *data = (u32 *)ctr; | 	u32 data[TEGRA_SE_AES_BLOCK_SIZE / 4]; | ||||||
| 	for (u32 i = 0; i < 4; i++) | 	memcpy(data, ctr, TEGRA_SE_AES_BLOCK_SIZE); | ||||||
| 		SE(SE_CRYPTO_CTR_REG_OFFSET + 4 * i) = data[i]; |  | ||||||
|  | 	for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++) | ||||||
|  | 		SE(SE_CRYPTO_CTR_REG_OFFSET + (4 * i)) = data[i]; | ||||||
| } | } | ||||||
|  |  | ||||||
| void se_rsa_acc_ctrl(u32 rs, u32 flags) | void se_rsa_acc_ctrl(u32 rs, u32 flags) | ||||||
| @@ -159,7 +197,7 @@ void se_rsa_acc_ctrl(u32 rs, u32 flags) | |||||||
| 			((flags >> SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) | | 			((flags >> SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) | | ||||||
| 			((flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG) ^ SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG); | 			((flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG) ^ SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG); | ||||||
| 	if (flags & SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG) | 	if (flags & SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG) | ||||||
| 		SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~(1 << rs); | 		SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~BIT(rs); | ||||||
| } | } | ||||||
|  |  | ||||||
| // se_rsa_key_set() was derived from Atmosphère's set_rsa_keyslot | // se_rsa_key_set() was derived from Atmosphère's set_rsa_keyslot | ||||||
| @@ -212,7 +250,7 @@ int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_siz | |||||||
| 	SE(SE_RSA_KEY_SIZE_REG_OFFSET) = (_se_rsa_mod_sizes[ks] >> 6) - 1; | 	SE(SE_RSA_KEY_SIZE_REG_OFFSET) = (_se_rsa_mod_sizes[ks] >> 6) - 1; | ||||||
| 	SE(SE_RSA_EXP_SIZE_REG_OFFSET) = _se_rsa_exp_sizes[ks] >> 2; | 	SE(SE_RSA_EXP_SIZE_REG_OFFSET) = _se_rsa_exp_sizes[ks] >> 2; | ||||||
|  |  | ||||||
| 	res = _se_execute(OP_START, NULL, 0, stack_buf, src_size); | 	res = _se_execute_oneshot(OP_START, NULL, 0, stack_buf, src_size); | ||||||
|  |  | ||||||
| 	// Copy output hash. | 	// Copy output hash. | ||||||
| 	u32 *dst32 = (u32 *)dst; | 	u32 *dst32 = (u32 *)dst; | ||||||
| @@ -227,7 +265,7 @@ void se_key_acc_ctrl(u32 ks, u32 flags) | |||||||
| 	if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG) | 	if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG) | ||||||
| 		SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags; | 		SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags; | ||||||
| 	if (flags & SE_KEY_TBL_DIS_KEY_LOCK_FLAG) | 	if (flags & SE_KEY_TBL_DIS_KEY_LOCK_FLAG) | ||||||
| 		SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~(1 << ks); | 		SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~BIT(ks); | ||||||
| } | } | ||||||
|  |  | ||||||
| u32 se_key_acc_ctrl_get(u32 ks) | u32 se_key_acc_ctrl_get(u32 ks) | ||||||
| @@ -237,48 +275,55 @@ u32 se_key_acc_ctrl_get(u32 ks) | |||||||
|  |  | ||||||
| void se_aes_key_set(u32 ks, const void *key, u32 size) | void se_aes_key_set(u32 ks, const void *key, u32 size) | ||||||
| { | { | ||||||
| 	u32 *data = (u32 *)key; | 	u32 data[TEGRA_SE_AES_MAX_KEY_SIZE / 4]; | ||||||
| 	for (u32 i = 0; i < size / 4; i++) | 	memcpy(data, key, size); | ||||||
|  |  | ||||||
|  | 	for (u32 i = 0; i < (size / 4); i++) | ||||||
| 	{ | 	{ | ||||||
| 		SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i; | 		SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i; | ||||||
| 		SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i]; | 		SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i]; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void se_aes_iv_set(u32 ks, const void *iv, u32 size) | void se_aes_iv_set(u32 ks, const void *iv) | ||||||
| { | { | ||||||
| 	u32 *data = (u32 *)iv; | 	u32 data[TEGRA_SE_AES_BLOCK_SIZE / 4]; | ||||||
| 	for (u32 i = 0; i < size / 4; i++) | 	memcpy(data, iv, TEGRA_SE_AES_BLOCK_SIZE); | ||||||
|  |  | ||||||
|  | 	for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++) | ||||||
| 	{ | 	{ | ||||||
| 		SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | 8 | i; | 		SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i; | ||||||
| 		SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i]; | 		SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i]; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void se_aes_key_read(u32 ks, void *key, u32 size) | void se_aes_key_get(u32 ks, void *key, u32 size) | ||||||
| { | { | ||||||
| 	u32 *data = (u32 *)key; | 	u32 data[TEGRA_SE_AES_MAX_KEY_SIZE / 4]; | ||||||
| 	for (u32 i = 0; i < size / 4; i++) |  | ||||||
|  | 	for (u32 i = 0; i < (size / 4); i++) | ||||||
| 	{ | 	{ | ||||||
| 		SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i; | 		SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i; | ||||||
| 		data[i] = SE(SE_KEYTABLE_DATA0_REG_OFFSET); | 		data[i] = SE(SE_KEYTABLE_DATA0_REG_OFFSET); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	memcpy(key, data, size); | ||||||
| } | } | ||||||
|  |  | ||||||
| void se_aes_key_clear(u32 ks) | void se_aes_key_clear(u32 ks) | ||||||
| { | { | ||||||
| 	for (u32 i = 0; i < TEGRA_SE_AES_MAX_KEY_SIZE / 4; i++) | 	for (u32 i = 0; i < (TEGRA_SE_AES_MAX_KEY_SIZE / 4); i++) | ||||||
| 	{ | 	{ | ||||||
| 		SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i; | 		SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i; | ||||||
| 		SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0; | 		SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void se_aes_key_iv_clear(u32 ks) | void se_aes_iv_clear(u32 ks) | ||||||
| { | { | ||||||
| 	for (u32 i = 0; i < TEGRA_SE_AES_MAX_KEY_SIZE / 4; i++) | 	for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++) | ||||||
| 	{ | 	{ | ||||||
| 		SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | 8 | i; | 		SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i; | ||||||
| 		SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0; | 		SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -290,7 +335,7 @@ int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input) | |||||||
| 	SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; | 	SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; | ||||||
| 	SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst); | 	SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst); | ||||||
|  |  | ||||||
| 	return _se_execute(OP_START, NULL, 0, input, 0x10); | 	return _se_execute_oneshot(OP_START, NULL, 0, input, 0x10); | ||||||
| } | } | ||||||
|  |  | ||||||
| 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, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size) | ||||||
| @@ -306,7 +351,25 @@ int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, | |||||||
| 		SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT); | 		SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT); | ||||||
| 	} | 	} | ||||||
| 	SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1; | 	SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1; | ||||||
| 	return _se_execute(OP_START, dst, dst_size, src, src_size); | 	return _se_execute_oneshot(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) | ||||||
|  | { | ||||||
|  | 	if (enc) | ||||||
|  | 	{ | ||||||
|  | 		SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); | ||||||
|  | 		SE(SE_CRYPTO_REG_OFFSET) = 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_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY); | ||||||
|  | 		SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVAHB) | | ||||||
|  | 			SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM); | ||||||
|  | 	} | ||||||
|  | 	SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1; | ||||||
|  | 	return _se_execute_oneshot(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, u32 enc, void *dst, const void *src) | ||||||
| @@ -319,8 +382,7 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s | |||||||
| 	SE(SE_SPARE_0_REG_OFFSET) = 1; | 	SE(SE_SPARE_0_REG_OFFSET) = 1; | ||||||
| 	SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); | 	SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); | ||||||
| 	SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | | 	SE(SE_CRYPTO_REG_OFFSET) = 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_VAL(1) | | 		SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | SE_CRYPTO_CTR_VAL(1); | ||||||
| 		SE_CRYPTO_VCTRAM_SEL(VCTRAM_AHB); |  | ||||||
| 	_se_aes_ctr_set(ctr); | 	_se_aes_ctr_set(ctr); | ||||||
|  |  | ||||||
| 	u32 src_size_aligned = src_size & 0xFFFFFFF0; | 	u32 src_size_aligned = src_size & 0xFFFFFFF0; | ||||||
| @@ -329,7 +391,7 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s | |||||||
| 	if (src_size_aligned) | 	if (src_size_aligned) | ||||||
| 	{ | 	{ | ||||||
| 		SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1; | 		SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1; | ||||||
| 		if (!_se_execute(OP_START, dst, dst_size, src, src_size_aligned)) | 		if (!_se_execute_oneshot(OP_START, dst, dst_size, src, src_size_aligned)) | ||||||
| 			return 0; | 			return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -359,7 +421,7 @@ int se_initialize_rng() | |||||||
| 		SE_RNG_SRC_CONFIG_ENT_SRC_LOCK(RNG_SRC_RO_ENT_LOCK_ENABLE); | 		SE_RNG_SRC_CONFIG_ENT_SRC_LOCK(RNG_SRC_RO_ENT_LOCK_ENABLE); | ||||||
| 	SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; | 	SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; | ||||||
|  |  | ||||||
| 	int res =_se_execute(OP_START, output_buf, 0x10, NULL, 0); | 	int res =_se_execute_oneshot(OP_START, output_buf, 0x10, NULL, 0); | ||||||
|  |  | ||||||
| 	free(output_buf); | 	free(output_buf); | ||||||
| 	if (res) | 	if (res) | ||||||
| @@ -378,7 +440,7 @@ int se_generate_random(void *dst, u32 size) | |||||||
| 	if (num_blocks) | 	if (num_blocks) | ||||||
| 	{ | 	{ | ||||||
| 		SE(SE_BLOCK_COUNT_REG_OFFSET) = num_blocks - 1; | 		SE(SE_BLOCK_COUNT_REG_OFFSET) = num_blocks - 1; | ||||||
| 		if (!_se_execute(OP_START, dst, aligned_size, NULL, 0)) | 		if (!_se_execute_oneshot(OP_START, dst, aligned_size, NULL, 0)) | ||||||
| 			return 0; | 			return 0; | ||||||
| 	} | 	} | ||||||
| 	if (size > aligned_size) | 	if (size > aligned_size) | ||||||
| @@ -394,35 +456,15 @@ int se_generate_random_key(u32 ks_dst, u32 ks_src) | |||||||
| 	SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_MODE(RNG_MODE_NORMAL) | SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY); | 	SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_MODE(RNG_MODE_NORMAL) | SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY); | ||||||
|  |  | ||||||
| 	SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst); | 	SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst); | ||||||
| 	if (!_se_execute(OP_START, NULL, 0, NULL, 0)) | 	if (!_se_execute_oneshot(OP_START, NULL, 0, NULL, 0)) | ||||||
| 		return 0; | 		return 0; | ||||||
| 	SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst) | 1; | 	SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst) | 1; | ||||||
| 	if (!_se_execute(OP_START, NULL, 0, NULL, 0)) | 	if (!_se_execute_oneshot(OP_START, NULL, 0, NULL, 0)) | ||||||
| 		return 0; | 		return 0; | ||||||
|  |  | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size) |  | ||||||
| { |  | ||||||
| 	if (enc) |  | ||||||
| 	{ |  | ||||||
| 		SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); |  | ||||||
| 		SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | |  | ||||||
| 			SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP) | SE_CRYPTO_INPUT_SEL(INPUT_AHB) | |  | ||||||
| 			SE_CRYPTO_IV_SEL(IV_ORIGINAL); |  | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY); |  | ||||||
| 		SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVAHB) | |  | ||||||
| 			SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_AHB) | |  | ||||||
| 			SE_CRYPTO_IV_SEL(IV_ORIGINAL); |  | ||||||
| 	} |  | ||||||
| 	SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1; |  | ||||||
| 	return _se_execute(OP_START, dst, dst_size, src, src_size); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, const void *src, u32 sec_size) | int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, const void *src, u32 sec_size) | ||||||
| { | { | ||||||
| 	u8 tweak[0x10]; | 	u8 tweak[0x10]; | ||||||
| @@ -500,13 +542,13 @@ int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size) | |||||||
| 	SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_AHB) | | 	SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_AHB) | | ||||||
| 		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_key_iv_clear(ks); | 	se_aes_iv_clear(ks); | ||||||
|  |  | ||||||
| 	u32 num_blocks = (src_size + 0xf) >> 4; | 	u32 num_blocks = (src_size + 0xf) >> 4; | ||||||
| 	if (num_blocks > 1) | 	if (num_blocks > 1) | ||||||
| 	{ | 	{ | ||||||
| 		SE(SE_BLOCK_COUNT_REG_OFFSET) = num_blocks - 2; | 		SE(SE_BLOCK_COUNT_REG_OFFSET) = num_blocks - 2; | ||||||
| 		if (!_se_execute(OP_START, NULL, 0, src, src_size)) | 		if (!_se_execute_oneshot(OP_START, NULL, 0, src, src_size)) | ||||||
| 			goto out; | 			goto out; | ||||||
| 		SE(SE_CRYPTO_REG_OFFSET) |= SE_CRYPTO_IV_SEL(IV_UPDATED); | 		SE(SE_CRYPTO_REG_OFFSET) |= SE_CRYPTO_IV_SEL(IV_UPDATED); | ||||||
| 	} | 	} | ||||||
| @@ -525,7 +567,7 @@ int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size) | |||||||
| 		last_block[i] ^= key[i]; | 		last_block[i] ^= key[i]; | ||||||
|  |  | ||||||
| 	SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; | 	SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; | ||||||
| 	res = _se_execute(OP_START, NULL, 0, last_block, 0x10); | 	res = _se_execute_oneshot(OP_START, NULL, 0, last_block, 0x10); | ||||||
|  |  | ||||||
| 	u32 *dst32 = (u32 *)dst; | 	u32 *dst32 = (u32 *)dst; | ||||||
| 	for (u32 i = 0; i < (dst_size >> 2); i++) | 	for (u32 i = 0; i < (dst_size >> 2); i++) | ||||||
| @@ -537,29 +579,91 @@ out:; | |||||||
| 	return res; | 	return res; | ||||||
| } | } | ||||||
|  |  | ||||||
| // se_calc_sha256() was derived from Atmosphère's se_calculate_sha256. | 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(void *dst, const void *src, u32 src_size) |  | ||||||
| { | { | ||||||
| 	int res; | 	int res; | ||||||
| 	// Setup config for SHA256, size = BITS(src_size). | 	u32 hash32[TEGRA_SE_SHA_256_SIZE / 4]; | ||||||
|  |  | ||||||
|  | 	//! TODO: src_size must be 512 bit aligned if continuing and not last block for SHA256. | ||||||
|  | 	if (src_size > 0xFFFFFF || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer. | ||||||
|  | 		return 0; | ||||||
|  |  | ||||||
|  | 	// Setup config for SHA256. | ||||||
| 	SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG); | 	SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG); | ||||||
| 	SE(SE_SHA_CONFIG_REG_OFFSET) = SHA_INIT_HASH; | 	SE(SE_SHA_CONFIG_REG_OFFSET) = sha_cfg; | ||||||
| 	SE(SE_SHA_MSG_LENGTH_0_REG_OFFSET) = (u32)(src_size << 3); | 	SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; | ||||||
| 	SE(SE_SHA_MSG_LENGTH_1_REG_OFFSET) = 0; |  | ||||||
|  | 	// Set total size to current buffer size if empty. | ||||||
|  | 	if (!total_size) | ||||||
|  | 		total_size = src_size; | ||||||
|  |  | ||||||
|  | 	// Set total size: BITS(src_size), up to 2 EB. | ||||||
|  | 	SE(SE_SHA_MSG_LENGTH_0_REG_OFFSET) = (u32)(total_size << 3); | ||||||
|  | 	SE(SE_SHA_MSG_LENGTH_1_REG_OFFSET) = (u32)(total_size >> 29); | ||||||
| 	SE(SE_SHA_MSG_LENGTH_2_REG_OFFSET) = 0; | 	SE(SE_SHA_MSG_LENGTH_2_REG_OFFSET) = 0; | ||||||
| 	SE(SE_SHA_MSG_LENGTH_3_REG_OFFSET) = 0; | 	SE(SE_SHA_MSG_LENGTH_3_REG_OFFSET) = 0; | ||||||
| 	SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = (u32)(src_size << 3); |  | ||||||
| 	SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = 0; | 	// Set size left to hash. | ||||||
|  | 	SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = (u32)(total_size << 3); | ||||||
|  | 	SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = (u32)(total_size >> 29); | ||||||
| 	SE(SE_SHA_MSG_LEFT_2_REG_OFFSET) = 0; | 	SE(SE_SHA_MSG_LEFT_2_REG_OFFSET) = 0; | ||||||
| 	SE(SE_SHA_MSG_LEFT_3_REG_OFFSET) = 0; | 	SE(SE_SHA_MSG_LEFT_3_REG_OFFSET) = 0; | ||||||
|  |  | ||||||
|  | 	// If we hash in chunks, copy over the intermediate. | ||||||
|  | 	if (sha_cfg == SHA_CONTINUE && msg_left) | ||||||
|  | 	{ | ||||||
|  | 		// Restore message left to process. | ||||||
|  | 		SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = msg_left[0]; | ||||||
|  | 		SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = msg_left[1]; | ||||||
|  |  | ||||||
|  | 		// Restore hash reg. | ||||||
|  | 		memcpy(hash32, hash, TEGRA_SE_SHA_256_SIZE); | ||||||
|  | 		for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++) | ||||||
|  | 			SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)) = byte_swap_32(hash32[i]); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Trigger the operation. | 	// Trigger the operation. | ||||||
| 	res = _se_execute(OP_START, NULL, 0, src, src_size); | 	res = _se_execute(OP_START, NULL, 0, src, src_size, is_oneshot); | ||||||
|  |  | ||||||
|  | 	if (is_oneshot) | ||||||
|  | 	{ | ||||||
|  | 		// Backup message left. | ||||||
|  | 		if (msg_left) | ||||||
|  | 		{ | ||||||
|  | 			msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET); | ||||||
|  | 			msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET); | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		// Copy output hash. | 		// Copy output hash. | ||||||
| 	u32 *dst32 = (u32 *)dst; | 		for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++) | ||||||
| 	for (u32 i = 0; i < 8; i++) | 			hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2))); | ||||||
| 		dst32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2))); | 		memcpy(hash, hash32, TEGRA_SE_SHA_256_SIZE); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return res; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size) | ||||||
|  | { | ||||||
|  | 	return se_calc_sha256(hash, NULL, src, src_size, 0, SHA_INIT_HASH, true); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int se_calc_sha256_finalize(void *hash, u32 *msg_left) | ||||||
|  | { | ||||||
|  | 	u32 hash32[TEGRA_SE_SHA_256_SIZE / 4]; | ||||||
|  | 	int res = _se_execute_finalize(); | ||||||
|  |  | ||||||
|  | 	// Backup message left. | ||||||
|  | 	if (msg_left) | ||||||
|  | 	{ | ||||||
|  | 		msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET); | ||||||
|  | 		msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Copy output hash. | ||||||
|  | 	for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++) | ||||||
|  | 		hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2))); | ||||||
|  | 	memcpy(hash, hash32, TEGRA_SE_SHA_256_SIZE); | ||||||
|  |  | ||||||
| 	return res; | 	return res; | ||||||
| } | } | ||||||
| @@ -573,7 +677,7 @@ int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *ke | |||||||
|  |  | ||||||
| 	if (key_size > 0x40) | 	if (key_size > 0x40) | ||||||
| 	{ | 	{ | ||||||
| 		if (!se_calc_sha256(secret, key, key_size)) | 		if (!se_calc_sha256_oneshot(secret, key, key_size)) | ||||||
| 			goto out; | 			goto out; | ||||||
| 		memset(secret + 0x20, 0, 0x20); | 		memset(secret + 0x20, 0, 0x20); | ||||||
| 	} | 	} | ||||||
| @@ -593,10 +697,10 @@ int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *ke | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	memcpy(ipad + 0x40, src, src_size); | 	memcpy(ipad + 0x40, src, src_size); | ||||||
| 	if (!se_calc_sha256(dst, ipad, 0x40 + src_size)) | 	if (!se_calc_sha256_oneshot(dst, ipad, 0x40 + src_size)) | ||||||
| 		goto out; | 		goto out; | ||||||
| 	memcpy(opad + 0x40, dst, 0x20); | 	memcpy(opad + 0x40, dst, 0x20); | ||||||
| 	if (!se_calc_sha256(dst, opad, 0x60)) | 	if (!se_calc_sha256_oneshot(dst, opad, 0x60)) | ||||||
| 		goto out; | 		goto out; | ||||||
|  |  | ||||||
| 	res = 1; | 	res = 1; | ||||||
| @@ -611,8 +715,8 @@ out:; | |||||||
| // _mgf1_xor() and rsa_oaep_decode were derived from Atmosphère | // _mgf1_xor() and rsa_oaep_decode were derived from Atmosphère | ||||||
| static void _mgf1_xor(void *masked, u32 masked_size, const void *seed, u32 seed_size) | static void _mgf1_xor(void *masked, u32 masked_size, const void *seed, u32 seed_size) | ||||||
| { | { | ||||||
|     u8 cur_hash[0x20]; |     u8 cur_hash[0x20] __attribute__((aligned(4))); | ||||||
|     u8 hash_buf[0xe4]; |     u8 hash_buf[0xe4] __attribute__((aligned(4))); | ||||||
|  |  | ||||||
|     u32 hash_buf_size = seed_size + 4; |     u32 hash_buf_size = seed_size + 4; | ||||||
|     memcpy(hash_buf, seed, seed_size); |     memcpy(hash_buf, seed, seed_size); | ||||||
| @@ -627,7 +731,7 @@ static void _mgf1_xor(void *masked, u32 masked_size, const void *seed, u32 seed_ | |||||||
|             hash_buf[seed_size + 3 - i] = (round_num >> (8 * i)) & 0xff; |             hash_buf[seed_size + 3 - i] = (round_num >> (8 * i)) & 0xff; | ||||||
|         round_num++; |         round_num++; | ||||||
|  |  | ||||||
|         se_calc_sha256(cur_hash, hash_buf, hash_buf_size); |         se_calc_sha256_oneshot(cur_hash, hash_buf, hash_buf_size); | ||||||
|  |  | ||||||
|         for (unsigned int i = 0; i < cur_size; i++) { |         for (unsigned int i = 0; i < cur_size; i++) { | ||||||
|             *p_out ^= cur_hash[i]; |             *p_out ^= cur_hash[i]; | ||||||
| @@ -678,3 +782,59 @@ u32 se_rsa_oaep_decode(void *dst, u32 dst_size, const void *label_digest, u32 la | |||||||
| 	return msg_size; | 	return msg_size; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | 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_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_SRK); | ||||||
|  | 	SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(0) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); | ||||||
|  | 	SE(SE_RNG_CONFIG_REG_OFFSET) = SE_RNG_CONFIG_SRC(RNG_SRC_ENTROPY) | SE_RNG_CONFIG_MODE(RNG_MODE_FORCE_RESEED); | ||||||
|  | 	SE(SE_CRYPTO_LAST_BLOCK) = 0; | ||||||
|  | 	_se_execute_oneshot(OP_START, NULL, 0, NULL, 0); | ||||||
|  |  | ||||||
|  | 	// Save AES keys. | ||||||
|  | 	SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); | ||||||
|  |  | ||||||
|  | 	for (u32 i = 0; i < TEGRA_SE_KEYSLOT_COUNT; i++) | ||||||
|  | 	{ | ||||||
|  | 		SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(AES_KEYTABLE) | | ||||||
|  | 			(i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_0_3); | ||||||
|  |  | ||||||
|  | 		SE(SE_CRYPTO_LAST_BLOCK) = 0; | ||||||
|  | 		_se_execute_oneshot(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0); | ||||||
|  | 		memcpy(keys + i * keysize, aligned_buf, 0x10); | ||||||
|  |  | ||||||
|  | 		if (keysize > 0x10) | ||||||
|  | 		{ | ||||||
|  | 			SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(AES_KEYTABLE) | | ||||||
|  | 				(i << SE_KEY_INDEX_SHIFT) | SE_CONTEXT_SAVE_WORD_QUAD(KEYS_4_7); | ||||||
|  |  | ||||||
|  | 			SE(SE_CRYPTO_LAST_BLOCK) = 0; | ||||||
|  | 			_se_execute_oneshot(OP_CTX_SAVE, aligned_buf, 0x10, NULL, 0); | ||||||
|  | 			memcpy(keys + i * keysize + 0x10, aligned_buf, 0x10); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Save SRK to PMC secure scratches. | ||||||
|  | 	SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(SRK); | ||||||
|  | 	SE(SE_CRYPTO_LAST_BLOCK) = 0; | ||||||
|  | 	_se_execute_oneshot(OP_CTX_SAVE, NULL, 0, NULL, 0); | ||||||
|  |  | ||||||
|  | 	// End context save. | ||||||
|  | 	SE(SE_CONFIG_REG_OFFSET) = 0; | ||||||
|  | 	_se_execute_oneshot(OP_CTX_SAVE, NULL, 0, NULL, 0); | ||||||
|  |  | ||||||
|  | 	// Get SRK. | ||||||
|  | 	u32 srk[4]; | ||||||
|  | 	srk[0] = PMC(APBDEV_PMC_SECURE_SCRATCH4); | ||||||
|  | 	srk[1] = PMC(APBDEV_PMC_SECURE_SCRATCH5); | ||||||
|  | 	srk[2] = PMC(APBDEV_PMC_SECURE_SCRATCH6); | ||||||
|  | 	srk[3] = PMC(APBDEV_PMC_SECURE_SCRATCH7); | ||||||
|  |  | ||||||
|  | 	// Decrypt context. | ||||||
|  | 	se_aes_key_clear(3); | ||||||
|  | 	se_aes_key_set(3, srk, 0x10); | ||||||
|  | 	se_aes_crypt_cbc(3, 0, keys, TEGRA_SE_KEYSLOT_COUNT * keysize, keys, TEGRA_SE_KEYSLOT_COUNT * keysize); | ||||||
|  | 	se_aes_key_clear(3); | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								bdk/sec/se.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								bdk/sec/se.h
									
									
									
									
									
								
							| @@ -26,9 +26,10 @@ int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_siz | |||||||
| void se_key_acc_ctrl(u32 ks, u32 flags); | void se_key_acc_ctrl(u32 ks, u32 flags); | ||||||
| u32  se_key_acc_ctrl_get(u32 ks); | u32  se_key_acc_ctrl_get(u32 ks); | ||||||
| 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, u32 size); | void se_aes_iv_set(u32 ks, const void *iv); | ||||||
| void se_aes_key_read(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); | ||||||
| int se_initialize_rng(); | int se_initialize_rng(); | ||||||
| int se_generate_random(void *dst, u32 size); | int se_generate_random(void *dst, u32 size); | ||||||
| int se_generate_random_key(u32 ks_dst, u32 ks_src); | int se_generate_random_key(u32 ks_dst, u32 ks_src); | ||||||
| @@ -40,8 +41,11 @@ int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, | |||||||
| int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, const void *src, u32 sec_size); | int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, const void *src, u32 sec_size); | ||||||
| int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, const void *src, u32 sec_size, u32 num_secs); | int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, const void *src, u32 sec_size, u32 num_secs); | ||||||
| int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size); | int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size); | ||||||
| int se_calc_sha256(void *dst, const void *src, u32 src_size); | 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_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size); | int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size); | ||||||
| u32 se_rsa_oaep_decode(void *dst, u32 dst_size, const void *label_digest, u32 label_digest_size, u8 *buf, u32 buf_size); | u32 se_rsa_oaep_decode(void *dst, u32 dst_size, const void *label_digest, u32 label_digest_size, u8 *buf, u32 buf_size); | ||||||
|  | void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize); | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -265,6 +265,10 @@ | |||||||
| #define TEGRA_SE_AES_MIN_KEY_SIZE	16 | #define TEGRA_SE_AES_MIN_KEY_SIZE	16 | ||||||
| #define TEGRA_SE_AES_MAX_KEY_SIZE	32 | #define TEGRA_SE_AES_MAX_KEY_SIZE	32 | ||||||
| #define TEGRA_SE_AES_IV_SIZE		16 | #define TEGRA_SE_AES_IV_SIZE		16 | ||||||
|  | #define TEGRA_SE_SHA_512_SIZE		64 | ||||||
|  | #define TEGRA_SE_SHA_384_SIZE		48 | ||||||
|  | #define TEGRA_SE_SHA_256_SIZE		32 | ||||||
|  | #define TEGRA_SE_SHA_192_SIZE		24 | ||||||
| #define TEGRA_SE_RNG_IV_SIZE		16 | #define TEGRA_SE_RNG_IV_SIZE		16 | ||||||
| #define TEGRA_SE_RNG_DT_SIZE		16 | #define TEGRA_SE_RNG_DT_SIZE		16 | ||||||
| #define TEGRA_SE_RNG_KEY_SIZE		16 | #define TEGRA_SE_RNG_KEY_SIZE		16 | ||||||
|   | |||||||
| @@ -40,6 +40,8 @@ | |||||||
| #define  PMC_SCRATCH0_MODE_CUSTOM_ALL (PMC_SCRATCH0_MODE_RECOVERY | PMC_SCRATCH0_MODE_FASTBOOT | PMC_SCRATCH0_MODE_PAYLOAD) | #define  PMC_SCRATCH0_MODE_CUSTOM_ALL (PMC_SCRATCH0_MODE_RECOVERY | PMC_SCRATCH0_MODE_FASTBOOT | PMC_SCRATCH0_MODE_PAYLOAD) | ||||||
| #define APBDEV_PMC_SCRATCH1 0x54 | #define APBDEV_PMC_SCRATCH1 0x54 | ||||||
| #define APBDEV_PMC_SCRATCH20 0xA0 | #define APBDEV_PMC_SCRATCH20 0xA0 | ||||||
|  | #define APBDEV_PMC_SECURE_SCRATCH4 0xC0 | ||||||
|  | #define APBDEV_PMC_SECURE_SCRATCH5 0xC4 | ||||||
| #define APBDEV_PMC_PWR_DET_VAL 0xE4 | #define APBDEV_PMC_PWR_DET_VAL 0xE4 | ||||||
| #define  PMC_PWR_DET_SDMMC1_IO_EN BIT(12) | #define  PMC_PWR_DET_SDMMC1_IO_EN BIT(12) | ||||||
| #define  PMC_PWR_DET_AUDIO_HV     BIT(18) | #define  PMC_PWR_DET_AUDIO_HV     BIT(18) | ||||||
| @@ -63,6 +65,8 @@ | |||||||
| #define APBDEV_PMC_IO_DPD2_REQ 0x1C0 | #define APBDEV_PMC_IO_DPD2_REQ 0x1C0 | ||||||
| #define APBDEV_PMC_VDDP_SEL 0x1CC | #define APBDEV_PMC_VDDP_SEL 0x1CC | ||||||
| #define APBDEV_PMC_DDR_CFG 0x1D0 | #define APBDEV_PMC_DDR_CFG 0x1D0 | ||||||
|  | #define APBDEV_PMC_SECURE_SCRATCH6 0x224 | ||||||
|  | #define APBDEV_PMC_SECURE_SCRATCH7 0x228 | ||||||
| #define APBDEV_PMC_SCRATCH45 0x234 | #define APBDEV_PMC_SCRATCH45 0x234 | ||||||
| #define APBDEV_PMC_SCRATCH46 0x238 | #define APBDEV_PMC_SCRATCH46 0x238 | ||||||
| #define APBDEV_PMC_SCRATCH49 0x244 | #define APBDEV_PMC_SCRATCH49 0x244 | ||||||
|   | |||||||
| @@ -23,6 +23,19 @@ | |||||||
| #define PKG1_OFFSET    0x100000 | #define PKG1_OFFSET    0x100000 | ||||||
| #define KEYBLOB_OFFSET 0x180000 | #define KEYBLOB_OFFSET 0x180000 | ||||||
|  |  | ||||||
|  | typedef struct _bl_hdr_t210b01_t | ||||||
|  | { | ||||||
|  | 	u8  aes_mac[0x10]; | ||||||
|  | 	u8  rsa_sig[0x100]; | ||||||
|  | 	u8  salt[0x20]; | ||||||
|  | 	u8  sha256[0x20]; | ||||||
|  | 	u32 version; | ||||||
|  | 	u32 size; | ||||||
|  | 	u32 load_addr; | ||||||
|  | 	u32 entrypoint; | ||||||
|  | 	u8  rsvd[0x10]; | ||||||
|  | } bl_hdr_t210b01_t; | ||||||
|  |  | ||||||
| typedef struct _pkg1_id_t | typedef struct _pkg1_id_t | ||||||
| { | { | ||||||
| 	const char *id; | 	const char *id; | ||||||
|   | |||||||
| @@ -15,11 +15,11 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| // Sha256 hash of the null string. | // Sha256 hash of the null string. | ||||||
| static u8 null_hash[0x20] = { | static const u8 null_hash[0x20] __attribute__((aligned(4))) = { | ||||||
|     0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24, |     0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24, | ||||||
|     0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55}; |     0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55}; | ||||||
|  |  | ||||||
| static const u8 keyblob_key_source[][0x10] = { | static const u8 keyblob_key_source[][0x10] __attribute__((aligned(4))) = { | ||||||
|     {0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3}, //1.0.0 |     {0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3}, //1.0.0 | ||||||
|     {0x0C, 0x25, 0x61, 0x5D, 0x68, 0x4C, 0xEB, 0x42, 0x1C, 0x23, 0x79, 0xEA, 0x82, 0x25, 0x12, 0xAC}, //3.0.0 |     {0x0C, 0x25, 0x61, 0x5D, 0x68, 0x4C, 0xEB, 0x42, 0x1C, 0x23, 0x79, 0xEA, 0x82, 0x25, 0x12, 0xAC}, //3.0.0 | ||||||
|     {0x33, 0x76, 0x85, 0xEE, 0x88, 0x4A, 0xAE, 0x0A, 0xC2, 0x8A, 0xFD, 0x7D, 0x63, 0xC0, 0x43, 0x3B}, //3.0.1 |     {0x33, 0x76, 0x85, 0xEE, 0x88, 0x4A, 0xAE, 0x0A, 0xC2, 0x8A, 0xFD, 0x7D, 0x63, 0xC0, 0x43, 0x3B}, //3.0.1 | ||||||
| @@ -28,7 +28,7 @@ static const u8 keyblob_key_source[][0x10] = { | |||||||
|     {0xD8, 0xCC, 0xE1, 0x26, 0x6A, 0x35, 0x3F, 0xCC, 0x20, 0xF3, 0x2D, 0x3B, 0x51, 0x7D, 0xE9, 0xC0}  //6.0.0 |     {0xD8, 0xCC, 0xE1, 0x26, 0x6A, 0x35, 0x3F, 0xCC, 0x20, 0xF3, 0x2D, 0x3B, 0x51, 0x7D, 0xE9, 0xC0}  //6.0.0 | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static const u8 master_kek_sources[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_620 + 1][0x10] = { | static const u8 master_kek_sources[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_620 + 1][0x10] __attribute__((aligned(4))) = { | ||||||
|     {0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A}, //6.2.0 |     {0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A}, //6.2.0 | ||||||
|     {0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C}, //7.0.0 |     {0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C}, //7.0.0 | ||||||
|     {0xDE, 0xDC, 0xE3, 0x39, 0x30, 0x88, 0x16, 0xF8, 0xAE, 0x97, 0xAD, 0xEC, 0x64, 0x2D, 0x41, 0x41}, //8.1.0 |     {0xDE, 0xDC, 0xE3, 0x39, 0x30, 0x88, 0x16, 0xF8, 0xAE, 0x97, 0xAD, 0xEC, 0x64, 0x2D, 0x41, 0x41}, //8.1.0 | ||||||
| @@ -36,7 +36,7 @@ static const u8 master_kek_sources[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION | |||||||
|     {0x30, 0x3F, 0x02, 0x7E, 0xD8, 0x38, 0xEC, 0xD7, 0x93, 0x25, 0x34, 0xB5, 0x30, 0xEB, 0xCA, 0x7A}, //9.1.0 |     {0x30, 0x3F, 0x02, 0x7E, 0xD8, 0x38, 0xEC, 0xD7, 0x93, 0x25, 0x34, 0xB5, 0x30, 0xEB, 0xCA, 0x7A}, //9.1.0 | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static const u8 master_key_vectors[KB_FIRMWARE_VERSION_MAX + 1][0x10] = { | static const u8 master_key_vectors[KB_FIRMWARE_VERSION_MAX + 1][0x10] __attribute__((aligned(4))) = { | ||||||
|     {0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D}, /* Zeroes encrypted with Master Key 00. */ |     {0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D}, /* Zeroes encrypted with Master Key 00. */ | ||||||
|     {0x29, 0x4C, 0x04, 0xC8, 0xEB, 0x10, 0xED, 0x9D, 0x51, 0x64, 0x97, 0xFB, 0xF3, 0x4D, 0x50, 0xDD}, /* Master key 00 encrypted with Master key 01. */ |     {0x29, 0x4C, 0x04, 0xC8, 0xEB, 0x10, 0xED, 0x9D, 0x51, 0x64, 0x97, 0xFB, 0xF3, 0x4D, 0x50, 0xDD}, /* Master key 00 encrypted with Master key 01. */ | ||||||
|     {0xDE, 0xCF, 0xEB, 0xEB, 0x10, 0xAE, 0x74, 0xD8, 0xAD, 0x7C, 0xF4, 0x9E, 0x62, 0xE0, 0xE8, 0x72}, /* Master key 01 encrypted with Master key 02. */ |     {0xDE, 0xCF, 0xEB, 0xEB, 0x10, 0xAE, 0x74, 0xD8, 0xAD, 0x7C, 0xF4, 0x9E, 0x62, 0xE0, 0xE8, 0x72}, /* Master key 01 encrypted with Master key 02. */ | ||||||
| @@ -52,29 +52,29 @@ static const u8 master_key_vectors[KB_FIRMWARE_VERSION_MAX + 1][0x10] = { | |||||||
|  |  | ||||||
| //======================================Keys======================================// | //======================================Keys======================================// | ||||||
| // from Package1 -> Secure_Monitor | // from Package1 -> Secure_Monitor | ||||||
| static const u8 aes_kek_generation_source[0x10] = { | static const u8 aes_kek_generation_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0x4D, 0x87, 0x09, 0x86, 0xC4, 0x5D, 0x20, 0x72, 0x2F, 0xBA, 0x10, 0x53, 0xDA, 0x92, 0xE8, 0xA9}; |     0x4D, 0x87, 0x09, 0x86, 0xC4, 0x5D, 0x20, 0x72, 0x2F, 0xBA, 0x10, 0x53, 0xDA, 0x92, 0xE8, 0xA9}; | ||||||
| static const u8 aes_kek_seed_01[0x10] = { | static const u8 aes_kek_seed_01[0x10] __attribute__((aligned(4))) = { | ||||||
|     0xA2, 0xAB, 0xBF, 0x9C, 0x92, 0x2F, 0xBB, 0xE3, 0x78, 0x79, 0x9B, 0xC0, 0xCC, 0xEA, 0xA5, 0x74}; |     0xA2, 0xAB, 0xBF, 0x9C, 0x92, 0x2F, 0xBB, 0xE3, 0x78, 0x79, 0x9B, 0xC0, 0xCC, 0xEA, 0xA5, 0x74}; | ||||||
| static const u8 aes_kek_seed_03[0x10] = { | static const u8 aes_kek_seed_03[0x10] __attribute__((aligned(4))) = { | ||||||
|     0xE5, 0x4D, 0x9A, 0x02, 0xF0, 0x4F, 0x5F, 0xA8, 0xAD, 0x76, 0x0A, 0xF6, 0x32, 0x95, 0x59, 0xBB}; |     0xE5, 0x4D, 0x9A, 0x02, 0xF0, 0x4F, 0x5F, 0xA8, 0xAD, 0x76, 0x0A, 0xF6, 0x32, 0x95, 0x59, 0xBB}; | ||||||
| static const u8 package2_key_source[0x10] = { | static const u8 package2_key_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7}; |     0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7}; | ||||||
| static const u8 titlekek_source[0x10] = { | static const u8 titlekek_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0x1E, 0xDC, 0x7B, 0x3B, 0x60, 0xE6, 0xB4, 0xD8, 0x78, 0xB8, 0x17, 0x15, 0x98, 0x5E, 0x62, 0x9B}; |     0x1E, 0xDC, 0x7B, 0x3B, 0x60, 0xE6, 0xB4, 0xD8, 0x78, 0xB8, 0x17, 0x15, 0x98, 0x5E, 0x62, 0x9B}; | ||||||
| static const u8 retail_specific_aes_key_source[0x10] = { | static const u8 retail_specific_aes_key_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0xE2, 0xD6, 0xB8, 0x7A, 0x11, 0x9C, 0xB8, 0x80, 0xE8, 0x22, 0x88, 0x8A, 0x46, 0xFB, 0xA1, 0x95}; |     0xE2, 0xD6, 0xB8, 0x7A, 0x11, 0x9C, 0xB8, 0x80, 0xE8, 0x22, 0x88, 0x8A, 0x46, 0xFB, 0xA1, 0x95}; | ||||||
|  |  | ||||||
| // from Package1ldr (or Secure_Monitor on 6.2.0+) | // from Package1ldr (or Secure_Monitor on 6.2.0+) | ||||||
| static const u8 keyblob_mac_key_source[0x10] = { | static const u8 keyblob_mac_key_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0x59, 0xC7, 0xFB, 0x6F, 0xBE, 0x9B, 0xBE, 0x87, 0x65, 0x6B, 0x15, 0xC0, 0x53, 0x73, 0x36, 0xA5}; |     0x59, 0xC7, 0xFB, 0x6F, 0xBE, 0x9B, 0xBE, 0x87, 0x65, 0x6B, 0x15, 0xC0, 0x53, 0x73, 0x36, 0xA5}; | ||||||
| static const u8 master_key_source[0x10] = { | static const u8 master_key_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C}; |     0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C}; | ||||||
| static const u8 per_console_key_source[0x10] = { | static const u8 per_console_key_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78}; |     0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78}; | ||||||
| static const u8 device_master_key_source_kek_source[0x10] = { | static const u8 device_master_key_source_kek_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28}; |     0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28}; | ||||||
| static const u8 mariko_master_kek_sources[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_600 + 1][0x10] = { | static const u8 mariko_master_kek_sources[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_600 + 1][0x10] __attribute__((aligned(4))) = { | ||||||
|     {0x77, 0x60, 0x5A, 0xD2, 0xEE, 0x6E, 0xF8, 0x3C, 0x3F, 0x72, 0xE2, 0x59, 0x9D, 0xAC, 0x5E, 0x56}, // 6.0.0. |     {0x77, 0x60, 0x5A, 0xD2, 0xEE, 0x6E, 0xF8, 0x3C, 0x3F, 0x72, 0xE2, 0x59, 0x9D, 0xAC, 0x5E, 0x56}, // 6.0.0. | ||||||
|     {0x1E, 0x80, 0xB8, 0x17, 0x3E, 0xC0, 0x60, 0xAA, 0x11, 0xBE, 0x1A, 0x4A, 0xA6, 0x6F, 0xE4, 0xAE}, // 6.2.0. |     {0x1E, 0x80, 0xB8, 0x17, 0x3E, 0xC0, 0x60, 0xAA, 0x11, 0xBE, 0x1A, 0x4A, 0xA6, 0x6F, 0xE4, 0xAE}, // 6.2.0. | ||||||
|     {0x94, 0x08, 0x67, 0xBD, 0x0A, 0x00, 0x38, 0x84, 0x11, 0xD3, 0x1A, 0xDB, 0xDD, 0x8D, 0xF1, 0x8A}, // 7.0.0. |     {0x94, 0x08, 0x67, 0xBD, 0x0A, 0x00, 0x38, 0x84, 0x11, 0xD3, 0x1A, 0xDB, 0xDD, 0x8D, 0xF1, 0x8A}, // 7.0.0. | ||||||
| @@ -83,7 +83,7 @@ static const u8 mariko_master_kek_sources[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_ | |||||||
|     {0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82}, // 9.1.0. |     {0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82}, // 9.1.0. | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static const u8 device_master_key_source_sources[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_400 + 1][0x10] = { | static const u8 device_master_key_source_sources[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_400 + 1][0x10] __attribute__((aligned(4))) = { | ||||||
|     {0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D}, /* 4.0.0 Device Master Key Source Source. */ |     {0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D}, /* 4.0.0 Device Master Key Source Source. */ | ||||||
|     {0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C}, /* 5.0.0 Device Master Key Source Source. */ |     {0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C}, /* 5.0.0 Device Master Key Source Source. */ | ||||||
|     {0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4}, /* 6.0.0 Device Master Key Source Source. */ |     {0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4}, /* 6.0.0 Device Master Key Source Source. */ | ||||||
| @@ -95,18 +95,18 @@ static const u8 device_master_key_source_sources[KB_FIRMWARE_VERSION_MAX - KB_FI | |||||||
| }; | }; | ||||||
|  |  | ||||||
| // from ES | // from ES | ||||||
| static const u8 eticket_rsa_kek_source[0x10] = { | static const u8 eticket_rsa_kek_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0XDB, 0XA4, 0X51, 0X12, 0X4C, 0XA0, 0XA9, 0X83, 0X68, 0X14, 0XF5, 0XED, 0X95, 0XE3, 0X12, 0X5B}; |     0XDB, 0XA4, 0X51, 0X12, 0X4C, 0XA0, 0XA9, 0X83, 0X68, 0X14, 0XF5, 0XED, 0X95, 0XE3, 0X12, 0X5B}; | ||||||
| static const u8 eticket_rsa_kekek_source[0x10] = { | static const u8 eticket_rsa_kekek_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0X46, 0X6E, 0X57, 0XB7, 0X4A, 0X44, 0X7F, 0X02, 0XF3, 0X21, 0XCD, 0XE5, 0X8F, 0X2F, 0X55, 0X35}; |     0X46, 0X6E, 0X57, 0XB7, 0X4A, 0X44, 0X7F, 0X02, 0XF3, 0X21, 0XCD, 0XE5, 0X8F, 0X2F, 0X55, 0X35}; | ||||||
|  |  | ||||||
| // from SSL | // from SSL | ||||||
| static const u8 ssl_rsa_kek_source_x[0x10] = { | static const u8 ssl_rsa_kek_source_x[0x10] __attribute__((aligned(4))) = { | ||||||
|     0X7F, 0X5B, 0XB0, 0X84, 0X7B, 0X25, 0XAA, 0X67, 0XFA, 0XC8, 0X4B, 0XE2, 0X3D, 0X7B, 0X69, 0X03}; |     0X7F, 0X5B, 0XB0, 0X84, 0X7B, 0X25, 0XAA, 0X67, 0XFA, 0XC8, 0X4B, 0XE2, 0X3D, 0X7B, 0X69, 0X03}; | ||||||
| static const u8 ssl_rsa_kek_source_y[0x10] = { | static const u8 ssl_rsa_kek_source_y[0x10] __attribute__((aligned(4))) = { | ||||||
|     0X9A, 0X38, 0X3B, 0XF4, 0X31, 0XD0, 0XBD, 0X81, 0X32, 0X53, 0X4B, 0XA9, 0X64, 0X39, 0X7D, 0XE3}; |     0X9A, 0X38, 0X3B, 0XF4, 0X31, 0XD0, 0XBD, 0X81, 0X32, 0X53, 0X4B, 0XA9, 0X64, 0X39, 0X7D, 0XE3}; | ||||||
|  |  | ||||||
| static const u8 device_master_kek_sources[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_400 + 1][0x10] = { | static const u8 device_master_kek_sources[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_VERSION_400 + 1][0x10] __attribute__((aligned(4))) = { | ||||||
|     {0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D}, /* 4.0.0 Device Master Kek Source. */ |     {0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D}, /* 4.0.0 Device Master Kek Source. */ | ||||||
|     {0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E}, /* 5.0.0 Device Master Kek Source. */ |     {0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E}, /* 5.0.0 Device Master Kek Source. */ | ||||||
|     {0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF}, /* 6.0.0 Device Master Kek Source. */ |     {0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF}, /* 6.0.0 Device Master Kek Source. */ | ||||||
| @@ -118,13 +118,13 @@ static const u8 device_master_kek_sources[KB_FIRMWARE_VERSION_MAX - KB_FIRMWARE_ | |||||||
| }; | }; | ||||||
|  |  | ||||||
| // from SPL | // from SPL | ||||||
| static const u8 aes_key_generation_source[0x10] = { | static const u8 aes_key_generation_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0x89, 0x61, 0x5E, 0xE0, 0x5C, 0x31, 0xB6, 0x80, 0x5F, 0xE5, 0x8F, 0x3D, 0xA2, 0x4F, 0x7A, 0xA8}; |     0x89, 0x61, 0x5E, 0xE0, 0x5C, 0x31, 0xB6, 0x80, 0x5F, 0xE5, 0x8F, 0x3D, 0xA2, 0x4F, 0x7A, 0xA8}; | ||||||
|  |  | ||||||
| // from FS | // from FS | ||||||
| static const u8 bis_kek_source[0x10] = { | static const u8 bis_kek_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0x34, 0xC1, 0xA0, 0xC4, 0x82, 0x58, 0xF8, 0xB4, 0xFA, 0x9E, 0x5E, 0x6A, 0xDA, 0xFC, 0x7E, 0x4F}; |     0x34, 0xC1, 0xA0, 0xC4, 0x82, 0x58, 0xF8, 0xB4, 0xFA, 0x9E, 0x5E, 0x6A, 0xDA, 0xFC, 0x7E, 0x4F}; | ||||||
| static const u8 bis_key_source[3][0x20] = { | static const u8 bis_key_source[3][0x20] __attribute__((aligned(4))) = { | ||||||
|     {0xF8, 0x3F, 0x38, 0x6E, 0x2C, 0xD2, 0xCA, 0x32, 0xA8, 0x9A, 0xB9, 0xAA, 0x29, 0xBF, 0xC7, 0x48, |     {0xF8, 0x3F, 0x38, 0x6E, 0x2C, 0xD2, 0xCA, 0x32, 0xA8, 0x9A, 0xB9, 0xAA, 0x29, 0xBF, 0xC7, 0x48, | ||||||
|      0x7D, 0x92, 0xB0, 0x3A, 0xA8, 0xBF, 0xDE, 0xE1, 0xA7, 0x4C, 0x3B, 0x6E, 0x35, 0xCB, 0x71, 0x06}, |      0x7D, 0x92, 0xB0, 0x3A, 0xA8, 0xBF, 0xDE, 0xE1, 0xA7, 0x4C, 0x3B, 0x6E, 0x35, 0xCB, 0x71, 0x06}, | ||||||
|     {0x41, 0x00, 0x30, 0x49, 0xDD, 0xCC, 0xC0, 0x65, 0x64, 0x7A, 0x7E, 0xB4, 0x1E, 0xED, 0x9C, 0x5F, |     {0x41, 0x00, 0x30, 0x49, 0xDD, 0xCC, 0xC0, 0x65, 0x64, 0x7A, 0x7E, 0xB4, 0x1E, 0xED, 0x9C, 0x5F, | ||||||
| @@ -132,32 +132,32 @@ static const u8 bis_key_source[3][0x20] = { | |||||||
|     {0x52, 0xC2, 0xE9, 0xEB, 0x09, 0xE3, 0xEE, 0x29, 0x32, 0xA1, 0x0C, 0x1F, 0xB6, 0xA0, 0x92, 0x6C, |     {0x52, 0xC2, 0xE9, 0xEB, 0x09, 0xE3, 0xEE, 0x29, 0x32, 0xA1, 0x0C, 0x1F, 0xB6, 0xA0, 0x92, 0x6C, | ||||||
|      0x4D, 0x12, 0xE1, 0x4B, 0x2A, 0x47, 0x4C, 0x1C, 0x09, 0xCB, 0x03, 0x59, 0xF0, 0x15, 0xF4, 0xE4} |      0x4D, 0x12, 0xE1, 0x4B, 0x2A, 0x47, 0x4C, 0x1C, 0x09, 0xCB, 0x03, 0x59, 0xF0, 0x15, 0xF4, 0xE4} | ||||||
| }; | }; | ||||||
| static const u8 header_kek_source[0x10] = { | static const u8 header_kek_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0x1F, 0x12, 0x91, 0x3A, 0x4A, 0xCB, 0xF0, 0x0D, 0x4C, 0xDE, 0x3A, 0xF6, 0xD5, 0x23, 0x88, 0x2A}; |     0x1F, 0x12, 0x91, 0x3A, 0x4A, 0xCB, 0xF0, 0x0D, 0x4C, 0xDE, 0x3A, 0xF6, 0xD5, 0x23, 0x88, 0x2A}; | ||||||
| static const u8 header_key_source[0x20] = { | static const u8 header_key_source[0x20] __attribute__((aligned(4))) = { | ||||||
|     0x5A, 0x3E, 0xD8, 0x4F, 0xDE, 0xC0, 0xD8, 0x26, 0x31, 0xF7, 0xE2, 0x5D, 0x19, 0x7B, 0xF5, 0xD0, |     0x5A, 0x3E, 0xD8, 0x4F, 0xDE, 0xC0, 0xD8, 0x26, 0x31, 0xF7, 0xE2, 0x5D, 0x19, 0x7B, 0xF5, 0xD0, | ||||||
|     0x1C, 0x9B, 0x7B, 0xFA, 0xF6, 0x28, 0x18, 0x3D, 0x71, 0xF6, 0x4D, 0x73, 0xF1, 0x50, 0xB9, 0xD2}; |     0x1C, 0x9B, 0x7B, 0xFA, 0xF6, 0x28, 0x18, 0x3D, 0x71, 0xF6, 0x4D, 0x73, 0xF1, 0x50, 0xB9, 0xD2}; | ||||||
| static const u8 key_area_key_sources[3][0x10] = { | static const u8 key_area_key_sources[3][0x10] __attribute__((aligned(4))) = { | ||||||
|     {0x7F, 0x59, 0x97, 0x1E, 0x62, 0x9F, 0x36, 0xA1, 0x30, 0x98, 0x06, 0x6F, 0x21, 0x44, 0xC3, 0x0D}, // application |     {0x7F, 0x59, 0x97, 0x1E, 0x62, 0x9F, 0x36, 0xA1, 0x30, 0x98, 0x06, 0x6F, 0x21, 0x44, 0xC3, 0x0D}, // application | ||||||
|     {0x32, 0x7D, 0x36, 0x08, 0x5A, 0xD1, 0x75, 0x8D, 0xAB, 0x4E, 0x6F, 0xBA, 0xA5, 0x55, 0xD8, 0x82}, // ocean |     {0x32, 0x7D, 0x36, 0x08, 0x5A, 0xD1, 0x75, 0x8D, 0xAB, 0x4E, 0x6F, 0xBA, 0xA5, 0x55, 0xD8, 0x82}, // ocean | ||||||
|     {0x87, 0x45, 0xF1, 0xBB, 0xA6, 0xBE, 0x79, 0x64, 0x7D, 0x04, 0x8B, 0xA6, 0x7B, 0x5F, 0xDA, 0x4A}, // system |     {0x87, 0x45, 0xF1, 0xBB, 0xA6, 0xBE, 0x79, 0x64, 0x7D, 0x04, 0x8B, 0xA6, 0x7B, 0x5F, 0xDA, 0x4A}, // system | ||||||
| }; | }; | ||||||
| static const u8 save_mac_kek_source[0x10] = { | static const u8 save_mac_kek_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0XD8, 0X9C, 0X23, 0X6E, 0XC9, 0X12, 0X4E, 0X43, 0XC8, 0X2B, 0X03, 0X87, 0X43, 0XF9, 0XCF, 0X1B}; |     0XD8, 0X9C, 0X23, 0X6E, 0XC9, 0X12, 0X4E, 0X43, 0XC8, 0X2B, 0X03, 0X87, 0X43, 0XF9, 0XCF, 0X1B}; | ||||||
| static const u8 save_mac_key_source[0x10] = { | static const u8 save_mac_key_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0XE4, 0XCD, 0X3D, 0X4A, 0XD5, 0X0F, 0X74, 0X28, 0X45, 0XA4, 0X87, 0XE5, 0XA0, 0X63, 0XEA, 0X1F}; |     0XE4, 0XCD, 0X3D, 0X4A, 0XD5, 0X0F, 0X74, 0X28, 0X45, 0XA4, 0X87, 0XE5, 0XA0, 0X63, 0XEA, 0X1F}; | ||||||
| static const u8 save_mac_sd_card_kek_source[0x10] = { | static const u8 save_mac_sd_card_kek_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0X04, 0X89, 0XEF, 0X5D, 0X32, 0X6E, 0X1A, 0X59, 0XC4, 0XB7, 0XAB, 0X8C, 0X36, 0X7A, 0XAB, 0X17}; |     0X04, 0X89, 0XEF, 0X5D, 0X32, 0X6E, 0X1A, 0X59, 0XC4, 0XB7, 0XAB, 0X8C, 0X36, 0X7A, 0XAB, 0X17}; | ||||||
| static const u8 save_mac_sd_card_key_source[0x10] = { | static const u8 save_mac_sd_card_key_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0X6F, 0X64, 0X59, 0X47, 0XC5, 0X61, 0X46, 0XF9, 0XFF, 0XA0, 0X45, 0XD5, 0X95, 0X33, 0X29, 0X18}; |     0X6F, 0X64, 0X59, 0X47, 0XC5, 0X61, 0X46, 0XF9, 0XFF, 0XA0, 0X45, 0XD5, 0X95, 0X33, 0X29, 0X18}; | ||||||
| static const u8 sd_card_custom_storage_key_source[0x20] = { | static const u8 sd_card_custom_storage_key_source[0x20] __attribute__((aligned(4))) = { | ||||||
|     0X37, 0X0C, 0X34, 0X5E, 0X12, 0XE4, 0XCE, 0XFE, 0X21, 0XB5, 0X8E, 0X64, 0XDB, 0X52, 0XAF, 0X35, |     0X37, 0X0C, 0X34, 0X5E, 0X12, 0XE4, 0XCE, 0XFE, 0X21, 0XB5, 0X8E, 0X64, 0XDB, 0X52, 0XAF, 0X35, | ||||||
|     0X4F, 0X2C, 0XA5, 0XA3, 0XFC, 0X99, 0X9A, 0X47, 0XC0, 0X3E, 0XE0, 0X04, 0X48, 0X5B, 0X2F, 0XD0}; |     0X4F, 0X2C, 0XA5, 0XA3, 0XFC, 0X99, 0X9A, 0X47, 0XC0, 0X3E, 0XE0, 0X04, 0X48, 0X5B, 0X2F, 0XD0}; | ||||||
| static const u8 sd_card_kek_source[0x10] = { | static const u8 sd_card_kek_source[0x10] __attribute__((aligned(4))) = { | ||||||
|     0X88, 0X35, 0X8D, 0X9C, 0X62, 0X9B, 0XA1, 0XA0, 0X01, 0X47, 0XDB, 0XE0, 0X62, 0X1B, 0X54, 0X32}; |     0X88, 0X35, 0X8D, 0X9C, 0X62, 0X9B, 0XA1, 0XA0, 0X01, 0X47, 0XDB, 0XE0, 0X62, 0X1B, 0X54, 0X32}; | ||||||
| static const u8 sd_card_nca_key_source[0x20] = { | static const u8 sd_card_nca_key_source[0x20] __attribute__((aligned(4))) = { | ||||||
|     0X58, 0X41, 0XA2, 0X84, 0X93, 0X5B, 0X56, 0X27, 0X8B, 0X8E, 0X1F, 0XC5, 0X18, 0XE9, 0X9F, 0X2B, |     0X58, 0X41, 0XA2, 0X84, 0X93, 0X5B, 0X56, 0X27, 0X8B, 0X8E, 0X1F, 0XC5, 0X18, 0XE9, 0X9F, 0X2B, | ||||||
|     0X67, 0XC7, 0X93, 0XF0, 0XF2, 0X4F, 0XDE, 0XD0, 0X75, 0X49, 0X5D, 0XCA, 0X00, 0X6D, 0X99, 0XC2}; |     0X67, 0XC7, 0X93, 0XF0, 0XF2, 0X4F, 0XDE, 0XD0, 0X75, 0X49, 0X5D, 0XCA, 0X00, 0X6D, 0X99, 0XC2}; | ||||||
| static const u8 sd_card_save_key_source[0x20] = { | static const u8 sd_card_save_key_source[0x20] __attribute__((aligned(4))) = { | ||||||
|     0X24, 0X49, 0XB7, 0X22, 0X72, 0X67, 0X03, 0XA8, 0X19, 0X65, 0XE6, 0XE3, 0XEA, 0X58, 0X2F, 0XDD, |     0X24, 0X49, 0XB7, 0X22, 0X72, 0X67, 0X03, 0XA8, 0X19, 0X65, 0XE6, 0XE3, 0XEA, 0X58, 0X2F, 0XDD, | ||||||
|     0X9A, 0X95, 0X15, 0X17, 0XB1, 0X6E, 0X8F, 0X7F, 0X1F, 0X68, 0X26, 0X31, 0X52, 0XEA, 0X29, 0X6A}; |     0X9A, 0X95, 0X15, 0X17, 0XB1, 0X6E, 0X8F, 0X7F, 0X1F, 0X68, 0X26, 0X31, 0X52, 0XEA, 0X29, 0X6A}; | ||||||
|   | |||||||
| @@ -74,7 +74,7 @@ static int   _key_exists(const void *data) { return memcmp(data, "\x00\x00\x00\x | |||||||
| static void  _save_key(const char *name, const void *data, u32 len, char *outbuf); | static void  _save_key(const char *name, const void *data, u32 len, char *outbuf); | ||||||
| static void  _save_key_family(const char *name, const void *data, u32 start_key, u32 num_keys, u32 len, char *outbuf); | static void  _save_key_family(const char *name, const void *data, u32 start_key, u32 num_keys, u32 len, char *outbuf); | ||||||
| static void  _generate_kek(u32 ks, const void *key_source, void *master_key, const void *kek_seed, const void *key_seed); | static void  _generate_kek(u32 ks, const void *key_source, void *master_key, const void *kek_seed, const void *key_seed); | ||||||
| static void  _get_device_key(u32 ks, void *out_device_key, u32 revision, const void *device_key, const void *master_key); | static void  _get_device_key(u32 ks, void *out_device_key, u32 revision, const void *device_key, const void *new_device_key, const void *master_key); | ||||||
| // titlekey functions | // titlekey functions | ||||||
| static bool  _test_key_pair(const void *E, const void *D, const void *N); | static bool  _test_key_pair(const void *E, const void *D, const void *N); | ||||||
|  |  | ||||||
| @@ -112,9 +112,12 @@ static u8 *_read_pkg1(sdmmc_t *sdmmc, const pkg1_id_t **pkg1_id) { | |||||||
|         EPRINTF("Unable to read pkg1."); |         EPRINTF("Unable to read pkg1."); | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
|     *pkg1_id = pkg1_identify(pkg1); |  | ||||||
|  |     u32 pk1_offset = h_cfg.t210b01 ? sizeof(bl_hdr_t210b01_t) : 0; // Skip T210B01 OEM header. | ||||||
|  |     *pkg1_id = pkg1_identify(pkg1 + pk1_offset); | ||||||
|     if (!*pkg1_id) { |     if (!*pkg1_id) { | ||||||
|         EPRINTF("Unknown pkg1 version.\n Make sure you have the latest Lockpick_RCM.\n If a new firmware version just came out,\n Lockpick_RCM must be updated.\n Check Github for new release."); |         EPRINTF("Unknown pkg1 version.\n Make sure you have the latest Lockpick_RCM.\n If a new firmware version just came out,\n Lockpick_RCM must be updated.\n Check Github for new release."); | ||||||
|  |         gfx_hexdump(0, pkg1, 0x20); | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -169,7 +172,7 @@ static bool _handle_sept(void *tsec_fw, u32 tsec_size, u32 kb, void *out_key) { | |||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|     } else { |     } else { | ||||||
|         se_aes_key_read(se_key_acc_ctrl_get(12) == 0x6A ? 13 : 12, out_key, AES_128_KEY_SIZE); |         se_aes_key_get(se_key_acc_ctrl_get(12) == 0x6A ? 13 : 12, out_key, AES_128_KEY_SIZE); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return true; |     return true; | ||||||
| @@ -225,8 +228,15 @@ static bool _derive_tsec_keys(tsec_ctxt_t *tsec_ctxt, u32 kb, key_derivation_ctx | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void _derive_master_keys_post_620_erista(u32 pkg1_kb, key_derivation_ctx_t *keys) { | static void _derive_master_key_mariko(u32 kb, key_derivation_ctx_t *keys) { | ||||||
|     u8 temp_key[AES_128_KEY_SIZE]; |     // Relies on the SBK being properly set in slot 14 | ||||||
|  |     se_aes_crypt_block_ecb(14, 0, keys->device_key_4x, device_master_key_source_kek_source); | ||||||
|  |     // Relies on the Mariko KEK being properly set in slot 12 | ||||||
|  |     se_aes_unwrap_key(8, 12, &mariko_master_kek_sources[kb - KB_FIRMWARE_VERSION_600]); | ||||||
|  |     se_aes_crypt_block_ecb(8, 0, keys->master_key[kb], master_key_source); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void _derive_master_keys_post_620(u32 pkg1_kb, key_derivation_ctx_t *keys) { | ||||||
|     // on firmware 6.2.0 only, the tsec_root_key is available |     // on firmware 6.2.0 only, the tsec_root_key is available | ||||||
|     if (pkg1_kb == KB_FIRMWARE_VERSION_620 && _key_exists(keys->tsec_keys + AES_128_KEY_SIZE)) { |     if (pkg1_kb == KB_FIRMWARE_VERSION_620 && _key_exists(keys->tsec_keys + AES_128_KEY_SIZE)) { | ||||||
|         se_aes_key_set(8, keys->tsec_keys + AES_128_KEY_SIZE, AES_128_KEY_SIZE); // mkek6 = unwrap(mkeks6, tsecroot) |         se_aes_key_set(8, keys->tsec_keys + AES_128_KEY_SIZE, AES_128_KEY_SIZE); // mkek6 = unwrap(mkeks6, tsecroot) | ||||||
| @@ -244,15 +254,15 @@ static void _derive_master_keys_post_620_erista(u32 pkg1_kb, key_derivation_ctx_ | |||||||
|                 se_aes_crypt_block_ecb(8, 0, keys->master_key[i - 1], master_key_vectors[i]); |                 se_aes_crypt_block_ecb(8, 0, keys->master_key[i - 1], master_key_vectors[i]); | ||||||
|             } |             } | ||||||
|             se_aes_key_set(8, keys->master_key[0], AES_128_KEY_SIZE); |             se_aes_key_set(8, keys->master_key[0], AES_128_KEY_SIZE); | ||||||
|             se_aes_crypt_block_ecb(8, 0, temp_key, master_key_vectors[0]); |             se_aes_crypt_block_ecb(8, 0, keys->temp_key, master_key_vectors[0]); | ||||||
|             if (!_key_exists(temp_key)) { |             if (!_key_exists(keys->temp_key)) { | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             memcpy(keys->master_key[kb - 1], keys->master_key[kb], AES_128_KEY_SIZE); |             memcpy(keys->master_key[kb - 1], keys->master_key[kb], AES_128_KEY_SIZE); | ||||||
|             memset(keys->master_key[kb], 0, AES_128_KEY_SIZE); |             memset(keys->master_key[kb], 0, AES_128_KEY_SIZE); | ||||||
|         } |         } | ||||||
|         if (_key_exists(temp_key)) { |         if (_key_exists(keys->temp_key)) { | ||||||
|             EPRINTFARGS("Unable to derive master key. kb = %d.\n Put current sept files on SD and retry.", pkg1_kb); |             EPRINTFARGS("Unable to derive master key. kb = %d.\n Check sept files on SD and retry.", pkg1_kb); | ||||||
|             memset(keys->master_key, 0, sizeof(keys->master_key)); |             memset(keys->master_key, 0, sizeof(keys->master_key)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -261,11 +271,20 @@ static void _derive_master_keys_post_620_erista(u32 pkg1_kb, key_derivation_ctx_ | |||||||
| static void _derive_master_keys_from_keyblobs(key_derivation_ctx_t *keys) { | static void _derive_master_keys_from_keyblobs(key_derivation_ctx_t *keys) { | ||||||
|     u8 *keyblob_block = (u8 *)calloc(KB_FIRMWARE_VERSION_600 + 1, NX_EMMC_BLOCKSIZE); |     u8 *keyblob_block = (u8 *)calloc(KB_FIRMWARE_VERSION_600 + 1, NX_EMMC_BLOCKSIZE); | ||||||
|     encrypted_keyblob_t *current_keyblob = (encrypted_keyblob_t *)keyblob_block; |     encrypted_keyblob_t *current_keyblob = (encrypted_keyblob_t *)keyblob_block; | ||||||
|     u8 keyblob_mac[AES_128_KEY_SIZE] = {0}; |     u32 keyblob_mac[AES_128_KEY_SIZE / 4] = {0}; | ||||||
|  |  | ||||||
|     keys->sbk[0] = FUSE(FUSE_PRIVATE_KEY0); |     keys->sbk[0] = FUSE(FUSE_PRIVATE_KEY0); | ||||||
|     keys->sbk[1] = FUSE(FUSE_PRIVATE_KEY1); |     keys->sbk[1] = FUSE(FUSE_PRIVATE_KEY1); | ||||||
|     keys->sbk[2] = FUSE(FUSE_PRIVATE_KEY2); |     keys->sbk[2] = FUSE(FUSE_PRIVATE_KEY2); | ||||||
|     keys->sbk[3] = FUSE(FUSE_PRIVATE_KEY3); |     keys->sbk[3] = FUSE(FUSE_PRIVATE_KEY3); | ||||||
|  |  | ||||||
|  |     if (keys->sbk[0] == 0xFFFFFFFF) { | ||||||
|  |         u8 *aes_keys = (u8 *)calloc(0x1000, 1); | ||||||
|  |         se_get_aes_keys(aes_keys + 0x800, aes_keys, AES_128_KEY_SIZE); | ||||||
|  |         memcpy(keys->sbk, aes_keys + 14 * AES_128_KEY_SIZE, AES_128_KEY_SIZE); | ||||||
|  |         free(aes_keys); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     se_aes_key_set(8, keys->tsec_keys, sizeof(keys->tsec_keys) / 2); |     se_aes_key_set(8, keys->tsec_keys, sizeof(keys->tsec_keys) / 2); | ||||||
|     se_aes_key_set(9, keys->sbk, sizeof(keys->sbk)); |     se_aes_key_set(9, keys->sbk, sizeof(keys->sbk)); | ||||||
|  |  | ||||||
| @@ -315,11 +334,10 @@ static void _derive_bis_keys(key_derivation_ctx_t *keys) { | |||||||
|     if (key_generation) |     if (key_generation) | ||||||
|         key_generation--; |         key_generation--; | ||||||
|  |  | ||||||
|     if (_key_exists(keys->device_key)) { |     if (!(_key_exists(keys->device_key) || (key_generation && _key_exists(keys->master_key[0]) && _key_exists(keys->device_key_4x)))) { | ||||||
|         if (key_generation) { |         return; | ||||||
|             _get_device_key(8, keys->temp_key, key_generation, keys->device_key_4x, keys->master_key[0]); |     } | ||||||
|         } else |     _get_device_key(8, keys->temp_key, key_generation, keys->device_key, keys->device_key_4x, keys->master_key[0]); | ||||||
|             memcpy(keys->temp_key, keys->device_key, AES_128_KEY_SIZE); |  | ||||||
|     se_aes_key_set(8, keys->temp_key, AES_128_KEY_SIZE); |     se_aes_key_set(8, keys->temp_key, AES_128_KEY_SIZE); | ||||||
|     se_aes_unwrap_key(8, 8, retail_specific_aes_key_source); // kek = unwrap(rsaks, devkey) |     se_aes_unwrap_key(8, 8, retail_specific_aes_key_source); // kek = unwrap(rsaks, devkey) | ||||||
|     se_aes_crypt_block_ecb(8, 0, keys->bis_key[0] + 0x00, bis_key_source[0] + 0x00); // bkey = unwrap(bkeys, kek) |     se_aes_crypt_block_ecb(8, 0, keys->bis_key[0] + 0x00, bis_key_source[0] + 0x00); // bkey = unwrap(bkeys, kek) | ||||||
| @@ -332,7 +350,6 @@ static void _derive_bis_keys(key_derivation_ctx_t *keys) { | |||||||
|     se_aes_crypt_block_ecb(8, 0, keys->bis_key[2] + 0x10, bis_key_source[2] + 0x10); |     se_aes_crypt_block_ecb(8, 0, keys->bis_key[2] + 0x10, bis_key_source[2] + 0x10); | ||||||
|     memcpy(keys->bis_key[3], keys->bis_key[2], 0x20); |     memcpy(keys->bis_key[3], keys->bis_key[2], 0x20); | ||||||
| } | } | ||||||
| } |  | ||||||
|  |  | ||||||
| static void _derive_misc_keys(key_derivation_ctx_t *keys, u32 *derivable_key_count) { | static void _derive_misc_keys(key_derivation_ctx_t *keys, u32 *derivable_key_count) { | ||||||
|     if (_key_exists(keys->master_key[0])) { |     if (_key_exists(keys->master_key[0])) { | ||||||
| @@ -365,13 +382,13 @@ static void _derive_misc_keys(key_derivation_ctx_t *keys, u32 *derivable_key_cou | |||||||
|     if (_key_exists(keys->master_key[0])) { |     if (_key_exists(keys->master_key[0])) { | ||||||
|         for (u32 i = 0; i < AES_128_KEY_SIZE; i++) |         for (u32 i = 0; i < AES_128_KEY_SIZE; i++) | ||||||
|             keys->temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_03[i]; |             keys->temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_03[i]; | ||||||
|         _generate_kek(7, eticket_rsa_kekek_source, keys->master_key[0], keys->temp_key, NULL); |         _generate_kek(8, eticket_rsa_kekek_source, keys->master_key[0], keys->temp_key, NULL); | ||||||
|         se_aes_crypt_block_ecb(7, 0, keys->eticket_rsa_kek, eticket_rsa_kek_source); |         se_aes_crypt_block_ecb(8, 0, keys->eticket_rsa_kek, eticket_rsa_kek_source); | ||||||
|  |  | ||||||
|         for (u32 i = 0; i < AES_128_KEY_SIZE; i++) |         for (u32 i = 0; i < AES_128_KEY_SIZE; i++) | ||||||
|             keys->temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_01[i]; |             keys->temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_01[i]; | ||||||
|         _generate_kek(7, ssl_rsa_kek_source_x, keys->master_key[0], keys->temp_key, NULL); |         _generate_kek(8, ssl_rsa_kek_source_x, keys->master_key[0], keys->temp_key, NULL); | ||||||
|         se_aes_crypt_block_ecb(7, 0, keys->ssl_rsa_kek, ssl_rsa_kek_source_y); |         se_aes_crypt_block_ecb(8, 0, keys->ssl_rsa_kek, ssl_rsa_kek_source_y); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -411,8 +428,8 @@ static bool _get_titlekeys_from_save(u32 buf_size, const u8 *save_mac_key, title | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     char ticket_bin_path[0x40] = "/ticket.bin"; |     char ticket_bin_path[32] = "/ticket.bin"; | ||||||
|     char ticket_list_bin_path[0x40] = "/ticket_list.bin"; |     char ticket_list_bin_path[32] = "/ticket_list.bin"; | ||||||
|     save_data_file_ctx_t ticket_file; |     save_data_file_ctx_t ticket_file; | ||||||
|  |  | ||||||
|     if (!save_open_file(save_ctx, &ticket_file, ticket_list_bin_path, OPEN_MODE_READ)) { |     if (!save_open_file(save_ctx, &ticket_file, ticket_list_bin_path, OPEN_MODE_READ)) { | ||||||
| @@ -503,7 +520,7 @@ static bool _get_titlekeys_from_save(u32 buf_size, const u8 *save_mac_key, title | |||||||
| } | } | ||||||
|  |  | ||||||
| void dump_keys() { | void dump_keys() { | ||||||
|     key_derivation_ctx_t keys; |     key_derivation_ctx_t __attribute__((aligned(4))) keys = {0}; | ||||||
|  |  | ||||||
|     sd_mount(); |     sd_mount(); | ||||||
|  |  | ||||||
| @@ -544,9 +561,10 @@ void dump_keys() { | |||||||
|  |  | ||||||
|     // Master key derivation |     // Master key derivation | ||||||
|     if (h_cfg.t210b01) { |     if (h_cfg.t210b01) { | ||||||
|         // todo: derive mariko master keys |         _derive_master_key_mariko(pkg1_id->kb, &keys); | ||||||
|  |         _derive_master_keys_post_620(pkg1_id->kb, &keys); | ||||||
|     } else { |     } else { | ||||||
|         _derive_master_keys_post_620_erista(pkg1_id->kb, &keys); |         _derive_master_keys_post_620(pkg1_id->kb, &keys); | ||||||
|         _derive_master_keys_from_keyblobs(&keys); |         _derive_master_keys_from_keyblobs(&keys); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -625,7 +643,7 @@ void dump_keys() { | |||||||
|         goto get_titlekeys; |         goto get_titlekeys; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     u8 read_buf[0x20] = {0}; |     u8 read_buf[0x20] __attribute__((aligned(4))) = {0}; | ||||||
|     for (u32 i = 0x8000; i < f_size(&fp); i += 0x4000) { |     for (u32 i = 0x8000; i < f_size(&fp); i += 0x4000) { | ||||||
|         if (f_lseek(&fp, i) || f_read(&fp, read_buf, 0x20, &read_bytes) || read_bytes != 0x20) |         if (f_lseek(&fp, i) || f_read(&fp, read_buf, 0x20, &read_bytes) || read_bytes != 0x20) | ||||||
|             break; |             break; | ||||||
| @@ -669,8 +687,8 @@ get_titlekeys: | |||||||
|         keypair_generation--; |         keypair_generation--; | ||||||
|         for (u32 i = 0; i < AES_128_KEY_SIZE; i++) |         for (u32 i = 0; i < AES_128_KEY_SIZE; i++) | ||||||
|             keys.temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_03[i]; |             keys.temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_03[i]; | ||||||
|         u8 temp_device_key[AES_128_KEY_SIZE] = {0}; |         u32 temp_device_key[AES_128_KEY_SIZE / 4] = {0}; | ||||||
|         _get_device_key(7, temp_device_key, keypair_generation, keys.device_key_4x, keys.master_key[0]); |         _get_device_key(7, temp_device_key, keypair_generation, keys.device_key, keys.device_key_4x, keys.master_key[0]); | ||||||
|         _generate_kek(7, eticket_rsa_kekek_source, temp_device_key, keys.temp_key, NULL); |         _generate_kek(7, eticket_rsa_kekek_source, temp_device_key, keys.temp_key, NULL); | ||||||
|         se_aes_crypt_block_ecb(7, 0, keys.eticket_rsa_kek_personalized, eticket_rsa_kek_source); |         se_aes_crypt_block_ecb(7, 0, keys.eticket_rsa_kek_personalized, eticket_rsa_kek_source); | ||||||
|         memcpy(keys.temp_key, keys.eticket_rsa_kek_personalized, sizeof(keys.temp_key)); |         memcpy(keys.temp_key, keys.eticket_rsa_kek_personalized, sizeof(keys.temp_key)); | ||||||
| @@ -724,16 +742,16 @@ key_output: ; | |||||||
|     SAVE_KEY(aes_kek_generation_source); |     SAVE_KEY(aes_kek_generation_source); | ||||||
|     SAVE_KEY(aes_key_generation_source); |     SAVE_KEY(aes_key_generation_source); | ||||||
|     SAVE_KEY(bis_kek_source); |     SAVE_KEY(bis_kek_source); | ||||||
|     SAVE_KEY_FAMILY(keys.bis_key, 0); |     SAVE_KEY_FAMILY_VAR(bis_key, keys.bis_key, 0); | ||||||
|     SAVE_KEY_FAMILY(bis_key_source, 0); |     SAVE_KEY_FAMILY(bis_key_source, 0); | ||||||
|     SAVE_KEY(keys.device_key); |     SAVE_KEY_VAR(device_key, keys.device_key); | ||||||
|     SAVE_KEY(keys.device_key_4x); |     SAVE_KEY_VAR(device_key_4x, keys.device_key_4x); | ||||||
|     SAVE_KEY(keys.eticket_rsa_kek); |     SAVE_KEY_VAR(eticket_rsa_kek, keys.eticket_rsa_kek); | ||||||
|     SAVE_KEY(keys.eticket_rsa_kek_personalized); |     SAVE_KEY_VAR(eticket_rsa_kek_personalized, keys.eticket_rsa_kek_personalized); | ||||||
|     SAVE_KEY(eticket_rsa_kek_source); |     SAVE_KEY(eticket_rsa_kek_source); | ||||||
|     SAVE_KEY(eticket_rsa_kekek_source); |     SAVE_KEY(eticket_rsa_kekek_source); | ||||||
|     SAVE_KEY(header_kek_source); |     SAVE_KEY(header_kek_source); | ||||||
|     SAVE_KEY(keys.header_key); |     SAVE_KEY_VAR(header_key, keys.header_key); | ||||||
|     SAVE_KEY(header_key_source); |     SAVE_KEY(header_key_source); | ||||||
|     SAVE_KEY_FAMILY_VAR(key_area_key_application, keys.key_area_key[0], 0); |     SAVE_KEY_FAMILY_VAR(key_area_key_application, keys.key_area_key[0], 0); | ||||||
|     SAVE_KEY_VAR(key_area_key_application_source, key_area_key_sources[0]); |     SAVE_KEY_VAR(key_area_key_application_source, key_area_key_sources[0]); | ||||||
| @@ -741,17 +759,17 @@ key_output: ; | |||||||
|     SAVE_KEY_VAR(key_area_key_ocean_source, key_area_key_sources[1]); |     SAVE_KEY_VAR(key_area_key_ocean_source, key_area_key_sources[1]); | ||||||
|     SAVE_KEY_FAMILY_VAR(key_area_key_system, keys.key_area_key[2], 0); |     SAVE_KEY_FAMILY_VAR(key_area_key_system, keys.key_area_key[2], 0); | ||||||
|     SAVE_KEY_VAR(key_area_key_system_source, key_area_key_sources[2]); |     SAVE_KEY_VAR(key_area_key_system_source, key_area_key_sources[2]); | ||||||
|     SAVE_KEY_FAMILY(keys.keyblob, 0); |     SAVE_KEY_FAMILY_VAR(keyblob, keys.keyblob, 0); | ||||||
|     SAVE_KEY_FAMILY(keys.keyblob_key, 0); |     SAVE_KEY_FAMILY_VAR(keyblob_key, keys.keyblob_key, 0); | ||||||
|     SAVE_KEY_FAMILY(keyblob_key_source, 0); |     SAVE_KEY_FAMILY(keyblob_key_source, 0); | ||||||
|     SAVE_KEY_FAMILY(keys.keyblob_mac_key, 0); |     SAVE_KEY_FAMILY_VAR(keyblob_mac_key, keys.keyblob_mac_key, 0); | ||||||
|     SAVE_KEY(keyblob_mac_key_source); |     SAVE_KEY(keyblob_mac_key_source); | ||||||
|     SAVE_KEY_FAMILY(keys.master_kek, 0); |     SAVE_KEY_FAMILY_VAR(master_kek, keys.master_kek, 0); | ||||||
|     SAVE_KEY_FAMILY_VAR(master_kek_source, master_kek_sources, KB_FIRMWARE_VERSION_620); |     SAVE_KEY_FAMILY_VAR(master_kek_source, master_kek_sources, KB_FIRMWARE_VERSION_620); | ||||||
|     SAVE_KEY_FAMILY(keys.master_key, 0); |     SAVE_KEY_FAMILY_VAR(master_key, keys.master_key, 0); | ||||||
|     SAVE_KEY(master_key_source); |     SAVE_KEY(master_key_source); | ||||||
|     SAVE_KEY_FAMILY(keys.package1_key, 0); |     SAVE_KEY_FAMILY_VAR(package1_key, keys.package1_key, 0); | ||||||
|     SAVE_KEY_FAMILY(keys.package2_key, 0); |     SAVE_KEY_FAMILY_VAR(package2_key, keys.package2_key, 0); | ||||||
|     SAVE_KEY(package2_key_source); |     SAVE_KEY(package2_key_source); | ||||||
|     SAVE_KEY(per_console_key_source); |     SAVE_KEY(per_console_key_source); | ||||||
|     SAVE_KEY(retail_specific_aes_key_source); |     SAVE_KEY(retail_specific_aes_key_source); | ||||||
| @@ -762,7 +780,7 @@ key_output: ; | |||||||
|         keys.temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_01[i]; |         keys.temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_01[i]; | ||||||
|     SAVE_KEY_VAR(rsa_private_kek_generation_source, keys.temp_key); |     SAVE_KEY_VAR(rsa_private_kek_generation_source, keys.temp_key); | ||||||
|     SAVE_KEY(save_mac_kek_source); |     SAVE_KEY(save_mac_kek_source); | ||||||
|     SAVE_KEY(keys.save_mac_key); |     SAVE_KEY_VAR(save_mac_key, keys.save_mac_key); | ||||||
|     SAVE_KEY(save_mac_key_source); |     SAVE_KEY(save_mac_key_source); | ||||||
|     SAVE_KEY(save_mac_sd_card_kek_source); |     SAVE_KEY(save_mac_sd_card_kek_source); | ||||||
|     SAVE_KEY(save_mac_sd_card_key_source); |     SAVE_KEY(save_mac_sd_card_key_source); | ||||||
| @@ -770,12 +788,12 @@ key_output: ; | |||||||
|     SAVE_KEY(sd_card_kek_source); |     SAVE_KEY(sd_card_kek_source); | ||||||
|     SAVE_KEY(sd_card_nca_key_source); |     SAVE_KEY(sd_card_nca_key_source); | ||||||
|     SAVE_KEY(sd_card_save_key_source); |     SAVE_KEY(sd_card_save_key_source); | ||||||
|     SAVE_KEY(keys.sd_seed); |     SAVE_KEY_VAR(sd_seed, keys.sd_seed); | ||||||
|     SAVE_KEY_VAR(secure_boot_key, keys.sbk); |     SAVE_KEY_VAR(secure_boot_key, keys.sbk); | ||||||
|     SAVE_KEY(keys.ssl_rsa_kek); |     SAVE_KEY_VAR(ssl_rsa_kek, keys.ssl_rsa_kek); | ||||||
|     SAVE_KEY(ssl_rsa_kek_source_x); |     SAVE_KEY(ssl_rsa_kek_source_x); | ||||||
|     SAVE_KEY(ssl_rsa_kek_source_y); |     SAVE_KEY(ssl_rsa_kek_source_y); | ||||||
|     SAVE_KEY_FAMILY(keys.titlekek, 0); |     SAVE_KEY_FAMILY_VAR(titlekek, keys.titlekek, 0); | ||||||
|     SAVE_KEY(titlekek_source); |     SAVE_KEY(titlekek_source); | ||||||
|     _save_key("tsec_key", keys.tsec_keys, AES_128_KEY_SIZE, text_buffer); |     _save_key("tsec_key", keys.tsec_keys, AES_128_KEY_SIZE, text_buffer); | ||||||
|     if (pkg1_id->kb == KB_FIRMWARE_VERSION_620) |     if (pkg1_id->kb == KB_FIRMWARE_VERSION_620) | ||||||
| @@ -861,13 +879,15 @@ static void _generate_kek(u32 ks, const void *key_source, void *master_key, cons | |||||||
|         se_aes_unwrap_key(ks, ks, key_seed); |         se_aes_unwrap_key(ks, ks, key_seed); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void _get_device_key(u32 ks, void *out_device_key, u32 revision, const void *device_key, const void *master_key) { | static void _get_device_key(u32 ks, void *out_device_key, u32 revision, const void *device_key, const void *new_device_key, const void *master_key) { | ||||||
|     if (revision < KB_FIRMWARE_VERSION_400) |     if (revision < KB_FIRMWARE_VERSION_400) { | ||||||
|         memcpy(out_device_key, device_key, AES_128_KEY_SIZE); |         memcpy(out_device_key, device_key, AES_128_KEY_SIZE); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     revision -= KB_FIRMWARE_VERSION_400; |     revision -= KB_FIRMWARE_VERSION_400; | ||||||
|     u8 temp_key[AES_128_KEY_SIZE] = {0}; |     u32 temp_key[AES_128_KEY_SIZE / 4] = {0}; | ||||||
|     se_aes_key_set(ks, device_key, AES_128_KEY_SIZE); |     se_aes_key_set(ks, new_device_key, AES_128_KEY_SIZE); | ||||||
|     se_aes_crypt_ecb(ks, 0, temp_key, AES_128_KEY_SIZE, device_master_key_source_sources[revision], AES_128_KEY_SIZE); |     se_aes_crypt_ecb(ks, 0, temp_key, AES_128_KEY_SIZE, device_master_key_source_sources[revision], AES_128_KEY_SIZE); | ||||||
|     se_aes_key_set(ks, master_key, AES_128_KEY_SIZE); |     se_aes_key_set(ks, master_key, AES_128_KEY_SIZE); | ||||||
|     se_aes_unwrap_key(ks, ks, device_master_kek_sources[revision]); |     se_aes_unwrap_key(ks, ks, device_master_kek_sources[revision]); | ||||||
| @@ -875,7 +895,9 @@ static void _get_device_key(u32 ks, void *out_device_key, u32 revision, const vo | |||||||
| } | } | ||||||
|  |  | ||||||
| static bool _test_key_pair(const void *public_exponent, const void *private_exponent, const void *modulus) { | static bool _test_key_pair(const void *public_exponent, const void *private_exponent, const void *modulus) { | ||||||
|     u8 plaintext[RSA_2048_KEY_SIZE] = {0}, ciphertext[RSA_2048_KEY_SIZE] = {0}, work[RSA_2048_KEY_SIZE] = {0}; |     u8  plaintext[RSA_2048_KEY_SIZE] __attribute__((aligned(4))) = {0}, | ||||||
|  |         ciphertext[RSA_2048_KEY_SIZE] __attribute__((aligned(4))) = {0}, | ||||||
|  |         work[RSA_2048_KEY_SIZE] __attribute__((aligned(4))) = {0}; | ||||||
|  |  | ||||||
|     // 0xCAFEBABE |     // 0xCAFEBABE | ||||||
|     plaintext[0xfc] = 0xca; plaintext[0xfd] = 0xfe; plaintext[0xfe] = 0xba; plaintext[0xff] = 0xbe; |     plaintext[0xfc] = 0xca; plaintext[0xfd] = 0xfe; plaintext[0xfe] = 0xba; plaintext[0xff] = 0xbe; | ||||||
|   | |||||||
| @@ -297,27 +297,30 @@ void _get_key_generations(char *sysnand_label, char *emunand_label) | |||||||
| 	sdmmc_t sdmmc; | 	sdmmc_t sdmmc; | ||||||
| 	sdmmc_storage_t storage; | 	sdmmc_storage_t storage; | ||||||
| 	sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400); | 	sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400); | ||||||
| 	u8 *bct = (u8 *)malloc(NX_EMMC_BLOCKSIZE); | 	u8 *pkg1 = (u8 *)malloc(PKG1_MAX_SIZE); | ||||||
| 	sdmmc_storage_set_mmc_partition(&storage, EMMC_BOOT0); | 	sdmmc_storage_set_mmc_partition(&storage, EMMC_BOOT0); | ||||||
| 	sdmmc_storage_read(&storage, 0x2200 / NX_EMMC_BLOCKSIZE, 1, bct); | 	sdmmc_storage_read(&storage, PKG1_OFFSET / NX_EMMC_BLOCKSIZE, PKG1_MAX_SIZE / NX_EMMC_BLOCKSIZE, pkg1); | ||||||
| 	sdmmc_storage_end(&storage); | 	sdmmc_storage_end(&storage); | ||||||
|  |  | ||||||
| 	sprintf(sysnand_label + 36, "% 3d", bct[0x130] - 1); | 	u32 pk1_offset = h_cfg.t210b01 ? sizeof(bl_hdr_t210b01_t) : 0; // Skip T210B01 OEM header. | ||||||
|  |     const pkg1_id_t *pkg1_id = pkg1_identify(pkg1 + pk1_offset); | ||||||
|  | 	sprintf(sysnand_label + 36, "% 3d", pkg1_id->kb); | ||||||
| 	ment_top[0].caption = sysnand_label; | 	ment_top[0].caption = sysnand_label; | ||||||
| 	if (h_cfg.emummc_force_disable) | 	if (h_cfg.emummc_force_disable) | ||||||
| 	{ | 	{ | ||||||
| 		free(bct); | 		free(pkg1); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	emummc_storage_init_mmc(&storage, &sdmmc); | 	emummc_storage_init_mmc(&storage, &sdmmc); | ||||||
| 	memset(bct, 0, NX_EMMC_BLOCKSIZE); | 	memset(pkg1, 0, PKG1_MAX_SIZE); | ||||||
| 	emummc_storage_set_mmc_partition(&storage, EMMC_BOOT0); | 	emummc_storage_set_mmc_partition(&storage, EMMC_BOOT0); | ||||||
| 	emummc_storage_read(&storage, 0x2200 / NX_EMMC_BLOCKSIZE, 1, bct); | 	emummc_storage_read(&storage, PKG1_OFFSET / NX_EMMC_BLOCKSIZE, PKG1_MAX_SIZE / NX_EMMC_BLOCKSIZE, pkg1); | ||||||
| 	emummc_storage_end(&storage); | 	emummc_storage_end(&storage); | ||||||
|  |  | ||||||
| 	sprintf(emunand_label + 36, "% 3d", bct[0x130] - 1); | 	pkg1_id = pkg1_identify(pkg1 + pk1_offset); | ||||||
| 	free(bct); | 	sprintf(emunand_label + 36, "% 3d", pkg1_id->kb); | ||||||
|  | 	free(pkg1); | ||||||
| 	ment_top[1].caption = emunand_label; | 	ment_top[1].caption = emunand_label; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -393,6 +396,19 @@ void ipl_main() | |||||||
| 		ment_top[1].handler = NULL; | 		ment_top[1].handler = NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// Grey out reboot to RCM option if on Mariko or patched console. | ||||||
|  | 	if (h_cfg.t210b01 || h_cfg.rcm_patched) | ||||||
|  | 	{ | ||||||
|  | 		ment_top[6].type = MENT_CAPTION; | ||||||
|  | 		ment_top[6].color = 0xFF555555; | ||||||
|  | 		ment_top[6].handler = NULL; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (h_cfg.rcm_patched) | ||||||
|  | 	{ | ||||||
|  | 		ment_top[5].handler = reboot_full; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Update key generations listed in menu. | 	// Update key generations listed in menu. | ||||||
| 	_get_key_generations((char *)ment_top[0].caption, (char *)ment_top[1].caption); | 	_get_key_generations((char *)ment_top[0].caption, (char *)ment_top[1].caption); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user