mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2025-01-05 11:58:00 +00:00
loader: implement 8.1.0 changes
This commit is contained in:
parent
06e4158b93
commit
6699fda8c9
7 changed files with 75 additions and 43 deletions
|
@ -203,12 +203,37 @@ void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_sr
|
||||||
generic_panic();
|
generic_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write config, validate. */
|
||||||
se->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB);
|
se->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB);
|
||||||
|
if (se->CONFIG_REG != (ALG_AES_DEC | DST_KEYTAB)) {
|
||||||
|
generic_panic();
|
||||||
|
}
|
||||||
se->CRYPTO_REG = keyslot_src << 24;
|
se->CRYPTO_REG = keyslot_src << 24;
|
||||||
|
if (se->CRYPTO_REG != (keyslot_src << 24)) {
|
||||||
|
generic_panic();
|
||||||
|
}
|
||||||
se->BLOCK_COUNT_REG = 0;
|
se->BLOCK_COUNT_REG = 0;
|
||||||
|
if (se->BLOCK_COUNT_REG != 0) {
|
||||||
|
generic_panic();
|
||||||
|
}
|
||||||
se->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8;
|
se->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8;
|
||||||
|
if (se->CRYPTO_KEYTABLE_DST_REG != (keyslot_dst << 8)) {
|
||||||
|
generic_panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear address context. */
|
||||||
|
se->IN_LL_ADDR_REG = 0;
|
||||||
|
se->OUT_LL_ADDR_REG = 0;
|
||||||
|
if (se->IN_LL_ADDR_REG != 0 || se->OUT_LL_ADDR_REG != 0) {
|
||||||
|
generic_panic();
|
||||||
|
}
|
||||||
|
|
||||||
trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size);
|
trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size);
|
||||||
|
|
||||||
|
/* Validate address context. */
|
||||||
|
if (se->IN_LL_ADDR_REG == 0 || se->OUT_LL_ADDR_REG == 0) {
|
||||||
|
generic_panic();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
||||||
|
@ -320,6 +345,11 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v
|
||||||
/* Set registers for operation. */
|
/* Set registers for operation. */
|
||||||
se->ERR_STATUS_REG = se->ERR_STATUS_REG;
|
se->ERR_STATUS_REG = se->ERR_STATUS_REG;
|
||||||
se->INT_STATUS_REG = se->INT_STATUS_REG;
|
se->INT_STATUS_REG = se->INT_STATUS_REG;
|
||||||
|
|
||||||
|
if (se->IN_LL_ADDR_REG != (uint32_t) get_physical_address(&in_ll) || se->OUT_LL_ADDR_REG != (uint32_t) get_physical_address(&out_ll) || (se->INT_STATUS_REG & 0x10)) {
|
||||||
|
generic_panic();
|
||||||
|
}
|
||||||
|
|
||||||
se->OPERATION_REG = op;
|
se->OPERATION_REG = op;
|
||||||
|
|
||||||
while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ }
|
while (!(se->INT_STATUS_REG & 0x10)) { /* Wait a while */ }
|
||||||
|
@ -725,39 +755,3 @@ void se_save_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void
|
||||||
se->CONFIG_REG = 0;
|
se->CONFIG_REG = 0;
|
||||||
se_encrypt_with_srk(work_buf, 0, NULL, 0);
|
se_encrypt_with_srk(work_buf, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_save_partial_context(unsigned int srkgen_keyslot, unsigned int rng_keyslot, void *dst) {
|
|
||||||
volatile tegra_se_t *se = se_get_regs();
|
|
||||||
uint8_t _work_buf[0x80];
|
|
||||||
uint8_t *work_buf = (uint8_t *)(((uintptr_t)_work_buf + 0x7F) & ~0x3F);
|
|
||||||
|
|
||||||
/* Generate the SRK (context save encryption key). */
|
|
||||||
se_generate_random_key(srkgen_keyslot, rng_keyslot);
|
|
||||||
se_generate_srk(srkgen_keyslot);
|
|
||||||
|
|
||||||
se_generate_random(rng_keyslot, work_buf, 0x10);
|
|
||||||
|
|
||||||
/* Save known pattern. */
|
|
||||||
static const uint8_t context_save_known_pattern[0x10] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
|
|
||||||
se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_MEM);
|
|
||||||
se->BLOCK_COUNT_REG = 0;
|
|
||||||
se_encrypt_with_srk(dst + 0x00, 0x10, context_save_known_pattern, 0x10);
|
|
||||||
|
|
||||||
/* Save specific keyslots 0xC, 0xD, 0xE. */
|
|
||||||
se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (0xE << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS);
|
|
||||||
se->BLOCK_COUNT_REG = 0;
|
|
||||||
se_encrypt_with_srk(dst + 0x10, 0x10, NULL, 0);
|
|
||||||
se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (0xC << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS);
|
|
||||||
se->BLOCK_COUNT_REG = 0;
|
|
||||||
se_encrypt_with_srk(dst + 0x20, 0x10, NULL, 0);
|
|
||||||
se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_KEYTABLE_AES) | (0xD << CTX_SAVE_KEY_INDEX_SHIFT) | (CTX_SAVE_KEY_LOW_BITS);
|
|
||||||
se->BLOCK_COUNT_REG = 0;
|
|
||||||
se_encrypt_with_srk(dst + 0x30, 0x10, NULL, 0);
|
|
||||||
|
|
||||||
/* Save SRK into PMC registers. */
|
|
||||||
se->CONTEXT_SAVE_CONFIG_REG = (CTX_SAVE_SRC_SRK);
|
|
||||||
se->BLOCK_COUNT_REG = 0;
|
|
||||||
se_encrypt_with_srk(work_buf, 0, NULL, 0);
|
|
||||||
se->CONFIG_REG = 0;
|
|
||||||
se_encrypt_with_srk(work_buf, 0, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
|
@ -222,6 +222,4 @@ void se_set_in_context_save_mode(bool is_context_save_mode);
|
||||||
void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot);
|
void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot);
|
||||||
void se_save_context(unsigned int srk_keyslot, unsigned int rng_keyslot, void *dst);
|
void se_save_context(unsigned int srk_keyslot, unsigned int rng_keyslot, void *dst);
|
||||||
|
|
||||||
void se_save_partial_context(unsigned int srk_keyslot, unsigned int rng_keyslot, void *dst);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,8 +17,15 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "se.h"
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
__attribute__ ((noreturn)) void generic_panic(void) {
|
__attribute__ ((noreturn)) void generic_panic(void) {
|
||||||
|
/* Clear keyslots. */
|
||||||
|
clear_aes_keyslot(0xD);
|
||||||
|
for (size_t i = 0; i < 0x10; i++) {
|
||||||
|
clear_aes_keyslot(i);
|
||||||
|
}
|
||||||
|
clear_aes_keyslot(0xD);
|
||||||
while(1) { /* ... */ }
|
while(1) { /* ... */ }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 281534d9f805af7dccbdd4e0e8883d4d055581ff
|
Subproject commit 7e0ed3b38f437791fdd398c7058c376c9d2a6853
|
|
@ -37,7 +37,7 @@ class NpdmUtils {
|
||||||
u8 default_cpuid;
|
u8 default_cpuid;
|
||||||
u32 _0x10;
|
u32 _0x10;
|
||||||
u32 system_resource_size;
|
u32 system_resource_size;
|
||||||
u32 process_category;
|
u32 version;
|
||||||
u32 main_stack_size;
|
u32 main_stack_size;
|
||||||
char title_name[0x50];
|
char title_name[0x50];
|
||||||
u32 aci0_offset;
|
u32 aci0_offset;
|
||||||
|
|
|
@ -25,6 +25,35 @@
|
||||||
#include "ldr_npdm.hpp"
|
#include "ldr_npdm.hpp"
|
||||||
#include "ldr_nso.hpp"
|
#include "ldr_nso.hpp"
|
||||||
|
|
||||||
|
static inline bool IsDisallowedVersion810(const u64 title_id, const u32 version) {
|
||||||
|
return version == 0 &&
|
||||||
|
(title_id == TitleId_Settings ||
|
||||||
|
title_id == TitleId_Bus ||
|
||||||
|
title_id == TitleId_Audio ||
|
||||||
|
title_id == TitleId_NvServices ||
|
||||||
|
title_id == TitleId_Ns ||
|
||||||
|
title_id == TitleId_Ssl ||
|
||||||
|
title_id == TitleId_Es ||
|
||||||
|
title_id == TitleId_Creport ||
|
||||||
|
title_id == TitleId_Ro);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ProcessCreation::ValidateProcessVersion(u64 title_id, u32 version) {
|
||||||
|
if (GetRuntimeFirmwareVersion() < FirmwareVersion_810) {
|
||||||
|
return ResultSuccess;
|
||||||
|
} else {
|
||||||
|
#ifdef LDR_VALIDATE_PROCESS_VERSION
|
||||||
|
if (IsDisallowedVersion810(title_id, version)) {
|
||||||
|
return ResultLoaderInvalidVersion;
|
||||||
|
} else {
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return ResultSuccess;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Result ProcessCreation::InitializeProcessInfo(NpdmUtils::NpdmInfo *npdm, Handle reslimit_h, u64 arg_flags, ProcessInfo *out_proc_info) {
|
Result ProcessCreation::InitializeProcessInfo(NpdmUtils::NpdmInfo *npdm, Handle reslimit_h, u64 arg_flags, ProcessInfo *out_proc_info) {
|
||||||
/* Initialize a ProcessInfo using an npdm. */
|
/* Initialize a ProcessInfo using an npdm. */
|
||||||
*out_proc_info = {};
|
*out_proc_info = {};
|
||||||
|
@ -36,8 +65,8 @@ Result ProcessCreation::InitializeProcessInfo(NpdmUtils::NpdmInfo *npdm, Handle
|
||||||
/* Set title id. */
|
/* Set title id. */
|
||||||
out_proc_info->title_id = npdm->aci0->title_id;
|
out_proc_info->title_id = npdm->aci0->title_id;
|
||||||
|
|
||||||
/* Set process category. */
|
/* Set version. */
|
||||||
out_proc_info->process_category = npdm->header->process_category;
|
out_proc_info->version = npdm->header->version;
|
||||||
|
|
||||||
/* Copy reslimit handle raw. */
|
/* Copy reslimit handle raw. */
|
||||||
out_proc_info->reslimit_h = reslimit_h;
|
out_proc_info->reslimit_h = reslimit_h;
|
||||||
|
@ -145,6 +174,9 @@ Result ProcessCreation::CreateProcess(Handle *out_process_h, u64 index, char *nc
|
||||||
/* Load the process's NPDM. */
|
/* Load the process's NPDM. */
|
||||||
R_TRY(NpdmUtils::LoadNpdmFromCache(target_process->tid_sid.title_id, &npdm_info));
|
R_TRY(NpdmUtils::LoadNpdmFromCache(target_process->tid_sid.title_id, &npdm_info));
|
||||||
|
|
||||||
|
/* Validate version. */
|
||||||
|
R_TRY(ValidateProcessVersion(target_process->tid_sid.title_id, npdm_info.header->version));
|
||||||
|
|
||||||
/* Validate the title we're loading is what we expect. */
|
/* Validate the title we're loading is what we expect. */
|
||||||
if (npdm_info.aci0->title_id < npdm_info.acid->title_id_range_min || npdm_info.aci0->title_id > npdm_info.acid->title_id_range_max) {
|
if (npdm_info.aci0->title_id < npdm_info.acid->title_id_range_min || npdm_info.aci0->title_id > npdm_info.acid->title_id_range_max) {
|
||||||
return ResultLoaderInvalidProgramId;
|
return ResultLoaderInvalidProgramId;
|
||||||
|
|
|
@ -27,7 +27,7 @@ class ProcessCreation {
|
||||||
public:
|
public:
|
||||||
struct ProcessInfo {
|
struct ProcessInfo {
|
||||||
u8 name[12];
|
u8 name[12];
|
||||||
u32 process_category;
|
u32 version;
|
||||||
u64 title_id;
|
u64 title_id;
|
||||||
u64 code_addr;
|
u64 code_addr;
|
||||||
u32 code_num_pages;
|
u32 code_num_pages;
|
||||||
|
@ -35,6 +35,7 @@ class ProcessCreation {
|
||||||
Handle reslimit_h;
|
Handle reslimit_h;
|
||||||
u32 system_resource_num_pages;
|
u32 system_resource_num_pages;
|
||||||
};
|
};
|
||||||
|
static Result ValidateProcessVersion(u64 title_id, u32 version);
|
||||||
static Result InitializeProcessInfo(NpdmUtils::NpdmInfo *npdm, Handle reslimit_h, u64 arg_flags, ProcessInfo *out_proc_info);
|
static Result InitializeProcessInfo(NpdmUtils::NpdmInfo *npdm, Handle reslimit_h, u64 arg_flags, ProcessInfo *out_proc_info);
|
||||||
static Result CreateProcess(Handle *out_process_h, u64 index, char *nca_path, LaunchQueue::LaunchItem *launch_item, u64 arg_flags, Handle reslimit_h);
|
static Result CreateProcess(Handle *out_process_h, u64 index, char *nca_path, LaunchQueue::LaunchItem *launch_item, u64 arg_flags, Handle reslimit_h);
|
||||||
};
|
};
|
Loading…
Reference in a new issue