mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
exo: implement remaining SE changes for mariko support
This commit is contained in:
parent
5cb9fa510e
commit
bf92daf055
9 changed files with 167 additions and 67 deletions
|
@ -68,12 +68,56 @@ namespace ams::secmon::boot {
|
||||||
/* to the warmboot key? To be decided during the process of implementing ams-on-mariko support. */
|
/* to the warmboot key? To be decided during the process of implementing ams-on-mariko support. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constinit const u8 DeviceMasterKeySourceKekSource[se::AesBlockSize] = {
|
||||||
|
0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28
|
||||||
|
};
|
||||||
|
|
||||||
/* This function derives the master kek and device keys using the tsec root key. */
|
/* This function derives the master kek and device keys using the tsec root key. */
|
||||||
|
void DeriveMasterKekAndDeviceKeyErista(bool is_prod) {
|
||||||
/* NOTE: Exosphere does not use this in practice, and expects the bootloader to set up keys already. */
|
/* NOTE: Exosphere does not use this in practice, and expects the bootloader to set up keys already. */
|
||||||
/* NOTE: This function is currently not implemented. If implemented, it will only be a reference implementation. */
|
/* NOTE: This function is currently not implemented. If implemented, it will only be a reference implementation. */
|
||||||
[[maybe_unused]]
|
if constexpr (false) {
|
||||||
void DeriveMasterKekAndDeviceKey() {
|
/* TODO: Consider implementing this as a reference. */
|
||||||
/* TODO: Decide whether to implement this. */
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constinit const u8 MarikoMasterKekSourceProd[se::AesBlockSize] = {
|
||||||
|
0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82
|
||||||
|
};
|
||||||
|
|
||||||
|
constinit const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = {
|
||||||
|
0xF9, 0x37, 0xCF, 0x9A, 0xBD, 0x86, 0xBB, 0xA9, 0x9C, 0x9E, 0x03, 0xC4, 0xFC, 0xBC, 0x3B, 0xCE
|
||||||
|
};
|
||||||
|
|
||||||
|
void DeriveMasterKekAndDeviceKeyMariko(bool is_prod) {
|
||||||
|
/* Clear all keyslots other than KEK and SBK in SE1. */
|
||||||
|
for (int i = 0; i < pkg1::AesKeySlot_Count; ++i) {
|
||||||
|
if (i != pkg1::AesKeySlot_MarikoKek && i != pkg1::AesKeySlot_SecureBoot) {
|
||||||
|
se::ClearAesKeySlot(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear all keyslots in SE2. */
|
||||||
|
for (int i = 0; i < pkg1::AesKeySlot_Count; ++i) {
|
||||||
|
se::ClearAesKeySlot2(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Derive the master kek. */
|
||||||
|
se::SetEncryptedAesKey128(pkg1::AesKeySlot_MasterKek, pkg1::AesKeySlot_MarikoKek, is_prod ? MarikoMasterKekSourceProd : MarikoMasterKekSourceDev, se::AesBlockSize);
|
||||||
|
|
||||||
|
/* Derive the device master key source kek. */
|
||||||
|
se::SetEncryptedAesKey128(pkg1::AesKeySlot_DeviceMasterKeySourceKekMariko, pkg1::AesKeySlot_SecureBoot, DeviceMasterKeySourceKekSource, se::AesBlockSize);
|
||||||
|
|
||||||
|
/* Clear the KEK, now that we're done using it. */
|
||||||
|
se::ClearAesKeySlot(pkg1::AesKeySlot_MarikoKek);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeriveMasterKekAndDeviceKey(bool is_prod) {
|
||||||
|
if (GetSocType() == fuse::SocType_Mariko) {
|
||||||
|
DeriveMasterKekAndDeviceKeyMariko(is_prod);
|
||||||
|
} else /* if (GetSocType() == fuse::SocType_Erista) */ {
|
||||||
|
DeriveMasterKekAndDeviceKeyErista(is_prod);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupRandomKey(int slot, se::KeySlotLockFlags flags) {
|
void SetupRandomKey(int slot, se::KeySlotLockFlags flags) {
|
||||||
|
@ -219,7 +263,7 @@ namespace ams::secmon::boot {
|
||||||
const int current_generation = secmon::GetKeyGeneration();
|
const int current_generation = secmon::GetKeyGeneration();
|
||||||
|
|
||||||
/* Get the kek slot. */
|
/* Get the kek slot. */
|
||||||
const int kek_slot = fuse::GetSocType() == fuse::SocType_Mariko ? pkg1::AesKeySlot_DeviceMasterKeySourceKekMariko : pkg1::AesKeySlot_DeviceMasterKeySourceKekErista;
|
const int kek_slot = GetSocType() == fuse::SocType_Mariko ? pkg1::AesKeySlot_DeviceMasterKeySourceKekMariko : pkg1::AesKeySlot_DeviceMasterKeySourceKekErista;
|
||||||
|
|
||||||
/* Iterate for all generations. */
|
/* Iterate for all generations. */
|
||||||
for (int i = 0; i < pkg1::OldDeviceMasterKeyCount; ++i) {
|
for (int i = 0; i < pkg1::OldDeviceMasterKeyCount; ++i) {
|
||||||
|
@ -251,10 +295,7 @@ namespace ams::secmon::boot {
|
||||||
se::LockAesKeySlot(pkg1::AesKeySlot_DeviceMasterKeySourceKekMariko, se::KeySlotLockFlags_AllLockKek);
|
se::LockAesKeySlot(pkg1::AesKeySlot_DeviceMasterKeySourceKekMariko, se::KeySlotLockFlags_AllLockKek);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeriveAllKeys() {
|
void DeriveAllKeys(bool is_prod) {
|
||||||
/* Determine whether we're prod. */
|
|
||||||
const bool is_prod = IsProduction();
|
|
||||||
|
|
||||||
/* Get the ephemeral work block. */
|
/* Get the ephemeral work block. */
|
||||||
u8 * const work_block = se::GetEphemeralWorkBlock();
|
u8 * const work_block = se::GetEphemeralWorkBlock();
|
||||||
ON_SCOPE_EXIT { util::ClearMemory(work_block, se::AesBlockSize); };
|
ON_SCOPE_EXIT { util::ClearMemory(work_block, se::AesBlockSize); };
|
||||||
|
@ -303,16 +344,18 @@ namespace ams::secmon::boot {
|
||||||
/* Initialize the rng. */
|
/* Initialize the rng. */
|
||||||
se::InitializeRandom();
|
se::InitializeRandom();
|
||||||
|
|
||||||
|
/* Determine whether we're production. */
|
||||||
|
const bool is_prod = IsProduction();
|
||||||
|
|
||||||
/* Derive the master kek and device key. */
|
/* Derive the master kek and device key. */
|
||||||
if constexpr (false) {
|
/* NOTE: This is a no-op on erista, because fusee will have set up keys. */
|
||||||
DeriveMasterKekAndDeviceKey();
|
DeriveMasterKekAndDeviceKey(is_prod);
|
||||||
}
|
|
||||||
|
|
||||||
/* Lock the device key as only usable as a kek. */
|
/* Lock the device key as only usable as a kek. */
|
||||||
se::LockAesKeySlot(pkg1::AesKeySlot_Device, se::KeySlotLockFlags_AllLockKek);
|
se::LockAesKeySlot(pkg1::AesKeySlot_Device, se::KeySlotLockFlags_AllLockKek);
|
||||||
|
|
||||||
/* Derive all keys. */
|
/* Derive all keys. */
|
||||||
DeriveAllKeys();
|
DeriveAllKeys(is_prod);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -351,6 +394,9 @@ namespace ams::secmon::boot {
|
||||||
/* Set the security engine to Per Key Secure. */
|
/* Set the security engine to Per Key Secure. */
|
||||||
se::SetPerKeySecure();
|
se::SetPerKeySecure();
|
||||||
|
|
||||||
|
/* Set the security engine to Context Save Secure. */
|
||||||
|
se::SetContextSaveSecure();
|
||||||
|
|
||||||
/* Setup the PMC registers. */
|
/* Setup the PMC registers. */
|
||||||
SetupPmcRegisters();
|
SetupPmcRegisters();
|
||||||
|
|
||||||
|
|
|
@ -257,7 +257,7 @@ namespace ams::secmon::smc {
|
||||||
}
|
}
|
||||||
|
|
||||||
int PrepareDeviceMasterKey(int generation) {
|
int PrepareDeviceMasterKey(int generation) {
|
||||||
if (generation == pkg1::KeyGeneration_1_0_0) {
|
if (generation == pkg1::KeyGeneration_1_0_0 && GetSocType() == fuse::SocType_Erista) {
|
||||||
return pkg1::AesKeySlot_Device;
|
return pkg1::AesKeySlot_Device;
|
||||||
}
|
}
|
||||||
if (generation == GetKeyGeneration()) {
|
if (generation == GetKeyGeneration()) {
|
||||||
|
|
|
@ -37,7 +37,8 @@ namespace ams::pkg1 {
|
||||||
AesKeySlot_Master = 13,
|
AesKeySlot_Master = 13,
|
||||||
AesKeySlot_Device = 15,
|
AesKeySlot_Device = 15,
|
||||||
|
|
||||||
AesKeySlot_SecmonEnd = 16,
|
AesKeySlot_Count = 16,
|
||||||
|
AesKeySlot_SecmonEnd = AesKeySlot_Count,
|
||||||
|
|
||||||
/* Used only during boot. */
|
/* Used only during boot. */
|
||||||
AesKeySlot_Tsec = 12,
|
AesKeySlot_Tsec = 12,
|
||||||
|
@ -48,6 +49,10 @@ namespace ams::pkg1 {
|
||||||
AesKeySlot_DeviceMasterKeySourceKekErista = 10,
|
AesKeySlot_DeviceMasterKeySourceKekErista = 10,
|
||||||
AesKeySlot_MasterKek = 13,
|
AesKeySlot_MasterKek = 13,
|
||||||
AesKeySlot_DeviceMasterKeySourceKekMariko = 14,
|
AesKeySlot_DeviceMasterKeySourceKekMariko = 14,
|
||||||
|
|
||||||
|
/* Mariko only keyslots, used during boot. */
|
||||||
|
AesKeySlot_MarikoKek = 12,
|
||||||
|
AesKeySlot_MarikoBek = 13,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RsaKeySlot {
|
enum RsaKeySlot {
|
||||||
|
|
|
@ -26,6 +26,9 @@ namespace ams::se {
|
||||||
void ClearAesKeyIv(int slot);
|
void ClearAesKeyIv(int slot);
|
||||||
void LockAesKeySlot(int slot, u32 flags);
|
void LockAesKeySlot(int slot, u32 flags);
|
||||||
|
|
||||||
|
/* NOTE: This is Nintendo's API, but if we actually want to use SE2 we should use a different one. */
|
||||||
|
void ClearAesKeySlot2(int slot);
|
||||||
|
|
||||||
void SetAesKey(int slot, const void *key, size_t key_size);
|
void SetAesKey(int slot, const void *key, size_t key_size);
|
||||||
|
|
||||||
void SetEncryptedAesKey128(int dst_slot, int kek_slot, const void *key, size_t key_size);
|
void SetEncryptedAesKey128(int dst_slot, int kek_slot, const void *key, size_t key_size);
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace ams::se {
|
||||||
void SetSecure(bool secure);
|
void SetSecure(bool secure);
|
||||||
void SetTzramSecure();
|
void SetTzramSecure();
|
||||||
void SetPerKeySecure();
|
void SetPerKeySecure();
|
||||||
|
void SetContextSaveSecure();
|
||||||
|
|
||||||
void Lockout();
|
void Lockout();
|
||||||
|
|
||||||
|
|
|
@ -362,15 +362,10 @@ namespace ams::se {
|
||||||
StartOperationRaw(SE, SE_OPERATION_OP_START, out_ll_address, in_ll_address);
|
StartOperationRaw(SE, SE_OPERATION_OP_START, out_ll_address, in_ll_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
void ClearAesKeySlot(volatile SecurityEngineRegisters *SE, int slot) {
|
||||||
|
|
||||||
void ClearAesKeySlot(int slot) {
|
|
||||||
/* Validate the key slot. */
|
/* Validate the key slot. */
|
||||||
AMS_ABORT_UNLESS(0 <= slot && slot < AesKeySlotCount);
|
AMS_ABORT_UNLESS(0 <= slot && slot < AesKeySlotCount);
|
||||||
|
|
||||||
/* Get the engine. */
|
|
||||||
auto *SE = GetRegisters();
|
|
||||||
|
|
||||||
for (int i = 0; i < 16; ++i) {
|
for (int i = 0; i < 16; ++i) {
|
||||||
/* Select the keyslot. */
|
/* Select the keyslot. */
|
||||||
reg::Write(SE->SE_CRYPTO_KEYTABLE_ADDR, SE_REG_BITS_VALUE(CRYPTO_KEYTABLE_ADDR_KEYIV_KEY_SLOT, slot), SE_REG_BITS_VALUE(CRYPTO_KEYTABLE_ADDR_KEYIV_WORD, i));
|
reg::Write(SE->SE_CRYPTO_KEYTABLE_ADDR, SE_REG_BITS_VALUE(CRYPTO_KEYTABLE_ADDR_KEYIV_KEY_SLOT, slot), SE_REG_BITS_VALUE(CRYPTO_KEYTABLE_ADDR_KEYIV_WORD, i));
|
||||||
|
@ -380,6 +375,18 @@ namespace ams::se {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearAesKeySlot(int slot) {
|
||||||
|
/* Clear the slot in SE1. */
|
||||||
|
ClearAesKeySlot(GetRegisters(), slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearAesKeySlot2(int slot) {
|
||||||
|
/* Clear the slot in SE2. */
|
||||||
|
ClearAesKeySlot(GetRegisters2(), slot);
|
||||||
|
}
|
||||||
|
|
||||||
void ClearAesKeyIv(int slot) {
|
void ClearAesKeyIv(int slot) {
|
||||||
/* Validate the key slot. */
|
/* Validate the key slot. */
|
||||||
AMS_ABORT_UNLESS(0 <= slot && slot < AesKeySlotCount);
|
AMS_ABORT_UNLESS(0 <= slot && slot < AesKeySlotCount);
|
||||||
|
|
|
@ -24,6 +24,18 @@ namespace ams::se {
|
||||||
constinit uintptr_t g_register2_address = secmon::MemoryRegionPhysicalDeviceSecurityEngine2.GetAddress();
|
constinit uintptr_t g_register2_address = secmon::MemoryRegionPhysicalDeviceSecurityEngine2.GetAddress();
|
||||||
constinit DoneHandler g_done_handler = nullptr;
|
constinit DoneHandler g_done_handler = nullptr;
|
||||||
|
|
||||||
|
void SetSecure(volatile SecurityEngineRegisters *SE, bool secure) {
|
||||||
|
/* Set the security software setting. */
|
||||||
|
if (secure) {
|
||||||
|
reg::ReadWrite(SE->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_SOFT_SETTING, SECURE));
|
||||||
|
} else {
|
||||||
|
reg::ReadWrite(SE->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_SOFT_SETTING, NONSECURE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the status register to force an update. */
|
||||||
|
reg::Read(SE->SE_SE_SECURITY);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile SecurityEngineRegisters *GetRegisters() {
|
volatile SecurityEngineRegisters *GetRegisters() {
|
||||||
|
@ -45,17 +57,13 @@ namespace ams::se {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSecure(bool secure) {
|
void SetSecure(bool secure) {
|
||||||
auto *SE = GetRegisters();
|
/* Set security for SE1. */
|
||||||
|
SetSecure(GetRegisters(), secure);
|
||||||
|
|
||||||
/* Set the security software setting. */
|
/* If SE2 is present, set security for SE2. */
|
||||||
if (secure) {
|
if (fuse::GetSocType() == fuse::SocType_Mariko) {
|
||||||
reg::ReadWrite(SE->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_SOFT_SETTING, SECURE));
|
SetSecure(GetRegisters2(), secure);
|
||||||
} else {
|
|
||||||
reg::ReadWrite(SE->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_SOFT_SETTING, NONSECURE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the status register to force an update. */
|
|
||||||
reg::Read(SE->SE_SE_SECURITY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetTzramSecure() {
|
void SetTzramSecure() {
|
||||||
|
@ -72,6 +80,18 @@ namespace ams::se {
|
||||||
reg::ReadWrite(SE->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_PERKEY_SETTING, SECURE));
|
reg::ReadWrite(SE->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_PERKEY_SETTING, SECURE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetContextSaveSecure() {
|
||||||
|
/* Context save lock to trustzone secure is only available on mariko. */
|
||||||
|
if (fuse::GetSocType() == fuse::SocType_Mariko) {
|
||||||
|
auto *SE = GetRegisters();
|
||||||
|
auto *SE2 = GetRegisters2();
|
||||||
|
|
||||||
|
reg::ReadWrite(SE->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_CTX_SAVE_TZ_LOCK, SECURE));
|
||||||
|
reg::ReadWrite(SE2->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_CTX_SAVE_TZ_LOCK, SECURE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Lockout() {
|
void Lockout() {
|
||||||
auto *SE = GetRegisters();
|
auto *SE = GetRegisters();
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,8 @@ namespace ams::se {
|
||||||
DEFINE_SE_REG_BIT_ENUM(SECURITY_HARD_SETTING, 0, SECURE, NONSECURE);
|
DEFINE_SE_REG_BIT_ENUM(SECURITY_HARD_SETTING, 0, SECURE, NONSECURE);
|
||||||
DEFINE_SE_REG_BIT_ENUM(SECURITY_ENG_DIS, 1, DISABLE, ENABLE);
|
DEFINE_SE_REG_BIT_ENUM(SECURITY_ENG_DIS, 1, DISABLE, ENABLE);
|
||||||
DEFINE_SE_REG_BIT_ENUM(SECURITY_PERKEY_SETTING, 2, SECURE, NONSECURE);
|
DEFINE_SE_REG_BIT_ENUM(SECURITY_PERKEY_SETTING, 2, SECURE, NONSECURE);
|
||||||
|
DEFINE_SE_REG_BIT_ENUM(SECURITY_CTX_SAVE_TZ_LOCK, 4, SECURE, NONSECURE);
|
||||||
|
DEFINE_SE_REG_BIT_ENUM(SECURITY_CTX_TZ_LOCK_SOFT, 5, SECURE, NONSECURE);
|
||||||
DEFINE_SE_REG_BIT_ENUM(SECURITY_SOFT_SETTING, 16, SECURE, NONSECURE);
|
DEFINE_SE_REG_BIT_ENUM(SECURITY_SOFT_SETTING, 16, SECURE, NONSECURE);
|
||||||
|
|
||||||
/* SE_TZRAM_SECURITY */
|
/* SE_TZRAM_SECURITY */
|
||||||
|
|
|
@ -44,12 +44,7 @@ namespace ams::se {
|
||||||
reg::Write(SE->SE_RNG_CONFIG, SE_REG_BITS_ENUM(RNG_CONFIG_SRC, ENTROPY), SE_REG_BITS_VALUE(RNG_CONFIG_MODE, mode));
|
reg::Write(SE->SE_RNG_CONFIG, SE_REG_BITS_ENUM(RNG_CONFIG_SRC, ENTROPY), SE_REG_BITS_VALUE(RNG_CONFIG_MODE, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
void InitializeRandom(volatile SecurityEngineRegisters *SE) {
|
||||||
|
|
||||||
void InitializeRandom() {
|
|
||||||
/* Get the engine. */
|
|
||||||
auto *SE = GetRegisters();
|
|
||||||
|
|
||||||
/* Lock the entropy source. */
|
/* Lock the entropy source. */
|
||||||
reg::Write(SE->SE_RNG_SRC_CONFIG, SE_REG_BITS_ENUM(RNG_SRC_CONFIG_RO_ENTROPY_SOURCE, ENABLE),
|
reg::Write(SE->SE_RNG_SRC_CONFIG, SE_REG_BITS_ENUM(RNG_SRC_CONFIG_RO_ENTROPY_SOURCE, ENABLE),
|
||||||
SE_REG_BITS_ENUM(RNG_SRC_CONFIG_RO_ENTROPY_SOURCE_LOCK, ENABLE));
|
SE_REG_BITS_ENUM(RNG_SRC_CONFIG_RO_ENTROPY_SOURCE_LOCK, ENABLE));
|
||||||
|
@ -72,6 +67,30 @@ namespace ams::se {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GenerateSrk(volatile SecurityEngineRegisters *SE) {
|
||||||
|
/* Configure the RNG to output to SRK and force a reseed. */
|
||||||
|
ConfigRng(SE, SE_CONFIG_DST_SRK, SE_RNG_CONFIG_MODE_FORCE_RESEED);
|
||||||
|
|
||||||
|
/* Configure a single block operation. */
|
||||||
|
SE->SE_CRYPTO_LAST_BLOCK = 0;
|
||||||
|
|
||||||
|
/* Execute the operation. */
|
||||||
|
ExecuteOperation(SE, SE_OPERATION_OP_START, nullptr, 0, nullptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeRandom() {
|
||||||
|
/* Initialize random for SE1. */
|
||||||
|
InitializeRandom(GetRegisters());
|
||||||
|
|
||||||
|
/* If we have SE2, initialize random for SE2. */
|
||||||
|
/* NOTE: Nintendo's implementation of this is incorrect. */
|
||||||
|
if (fuse::GetSocType() == fuse::SocType_Mariko) {
|
||||||
|
InitializeRandom(GetRegisters2());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GenerateRandomBytes(void *dst, size_t size) {
|
void GenerateRandomBytes(void *dst, size_t size) {
|
||||||
/* If we're not generating any bytes, there's nothing to do. */
|
/* If we're not generating any bytes, there's nothing to do. */
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
|
@ -130,17 +149,14 @@ namespace ams::se {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateSrk() {
|
void GenerateSrk() {
|
||||||
/* Get the engine. */
|
/* Generate SRK for SE1. */
|
||||||
auto *SE = GetRegisters();
|
GenerateSrk(GetRegisters());
|
||||||
|
|
||||||
/* Configure the RNG to output to SRK and force a reseed. */
|
/* If we have SE2, generate SRK for SE2. */
|
||||||
ConfigRng(SE, SE_CONFIG_DST_SRK, SE_RNG_CONFIG_MODE_FORCE_RESEED);
|
/* NOTE: Nintendo's implementation of this is incorrect. */
|
||||||
|
if (fuse::GetSocType() == fuse::SocType_Mariko) {
|
||||||
/* Configure a single block operation. */
|
GenerateSrk(GetRegisters2());
|
||||||
SE->SE_CRYPTO_LAST_BLOCK = 0;
|
}
|
||||||
|
|
||||||
/* Execute the operation. */
|
|
||||||
ExecuteOperation(SE, SE_OPERATION_OP_START, nullptr, 0, nullptr, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue