mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
exo2: implement rest of main other than SetupSocProtections
This commit is contained in:
parent
f391354415
commit
87bdc46beb
18 changed files with 408 additions and 78 deletions
|
@ -20,6 +20,7 @@ namespace ams::secmon::boot {
|
|||
|
||||
void MakePageTable();
|
||||
void UnmapPhysicalIdentityMapping();
|
||||
void UnmapDram();
|
||||
|
||||
void InitializeColdBoot();
|
||||
|
||||
|
@ -29,7 +30,13 @@ namespace ams::secmon::boot {
|
|||
bool VerifyBootConfigSignature(pkg1::BootConfig &bc, const void *mod, size_t mod_size);
|
||||
bool VerifyBootConfigEcid(const pkg1::BootConfig &bc);
|
||||
|
||||
void CalculatePackage2Hash(se::Sha256Hash *dst, const pkg2::Package2Meta &meta, uintptr_t package2_start);
|
||||
|
||||
bool VerifyPackage2Signature(pkg2::Package2Header &header, const void *mod, size_t mod_size);
|
||||
void DecryptPackage2(void *dst, size_t dst_size, const void *src, size_t src_size, const void *key, size_t key_size, const void *iv, size_t iv_size, u8 key_generation);
|
||||
|
||||
bool VerifyPackage2Meta(const pkg2::Package2Meta &meta);
|
||||
bool VerifyPackage2Version(const pkg2::Package2Meta &meta);
|
||||
bool VerifyPackage2Payloads(const pkg2::Package2Meta &meta, uintptr_t payload_address);
|
||||
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
#include "secmon_boot.hpp"
|
||||
#include "secmon_boot_cache.hpp"
|
||||
#include "secmon_boot_functions.hpp"
|
||||
#include "secmon_boot_key_data.hpp"
|
||||
|
||||
namespace ams::secmon::boot {
|
||||
|
||||
|
@ -25,66 +26,9 @@ namespace ams::secmon::boot {
|
|||
|
||||
constexpr inline uintptr_t SYSCTR0 = MemoryRegionVirtualDeviceSysCtr0.GetAddress();
|
||||
|
||||
constinit const u8 BootConfigRsaPublicModulus[se::RsaSize] = {
|
||||
0xB5, 0x96, 0x87, 0x31, 0x39, 0xAA, 0xBB, 0x3C, 0x28, 0xF3, 0xF0, 0x65, 0xF1, 0x50, 0x70, 0x64,
|
||||
0xE6, 0x6C, 0x97, 0x50, 0xCD, 0xA6, 0xEE, 0xEA, 0xC3, 0x8F, 0xE6, 0xB5, 0x81, 0x54, 0x65, 0x33,
|
||||
0x1B, 0x88, 0x4B, 0xCE, 0x9F, 0x53, 0xDF, 0xE4, 0xF6, 0xAD, 0xC3, 0x78, 0xD7, 0x3C, 0xD1, 0xDB,
|
||||
0x27, 0x21, 0xA0, 0x24, 0x30, 0x2D, 0x98, 0x41, 0xA8, 0xDF, 0x50, 0x7D, 0xAB, 0xCE, 0x00, 0xD9,
|
||||
0xCB, 0xAC, 0x8F, 0x37, 0xF5, 0x53, 0xE4, 0x97, 0x1F, 0x13, 0x3C, 0x19, 0xFF, 0x05, 0xA7, 0x3B,
|
||||
0xF6, 0xF4, 0x01, 0xDE, 0xF0, 0xC3, 0x77, 0x7B, 0x83, 0xBA, 0xAF, 0x99, 0x30, 0x94, 0x87, 0x25,
|
||||
0x4E, 0x54, 0x42, 0x3F, 0xAC, 0x27, 0xF9, 0xCC, 0x87, 0xDD, 0xAE, 0xF2, 0x54, 0xF3, 0x97, 0x49,
|
||||
0xF4, 0xB0, 0xF8, 0x6D, 0xDA, 0x60, 0xE0, 0xFD, 0x57, 0xAE, 0x55, 0xA9, 0x76, 0xEA, 0x80, 0x24,
|
||||
0xA0, 0x04, 0x7D, 0xBE, 0xD1, 0x81, 0xD3, 0x0C, 0x95, 0xCF, 0xB7, 0xE0, 0x2D, 0x21, 0x21, 0xFF,
|
||||
0x97, 0x1E, 0xB3, 0xD7, 0x9F, 0xBB, 0x33, 0x0C, 0x23, 0xC5, 0x88, 0x4A, 0x33, 0xB9, 0xC9, 0x4E,
|
||||
0x1E, 0x65, 0x51, 0x45, 0xDE, 0xF9, 0x64, 0x7C, 0xF0, 0xBF, 0x11, 0xB4, 0x93, 0x8D, 0x5D, 0xC6,
|
||||
0xAB, 0x37, 0x9E, 0xE9, 0x39, 0xC1, 0xC8, 0xDB, 0xB9, 0xFE, 0x45, 0xCE, 0x7B, 0xDD, 0x72, 0xD9,
|
||||
0x6F, 0x68, 0x13, 0xC0, 0x4B, 0xBA, 0x00, 0xF4, 0x1E, 0x89, 0x71, 0x91, 0x26, 0xA6, 0x46, 0x12,
|
||||
0xDF, 0x29, 0x6B, 0xC2, 0x5A, 0x53, 0xAF, 0xB9, 0x5B, 0xFD, 0x13, 0x9F, 0xD1, 0x8A, 0x7C, 0xB5,
|
||||
0x04, 0xFD, 0x69, 0xEA, 0x23, 0xB4, 0x6D, 0x16, 0x21, 0x98, 0x54, 0xB4, 0xDF, 0xE6, 0xAB, 0x93,
|
||||
0x36, 0xB6, 0xD2, 0x43, 0xCF, 0x2B, 0x98, 0x1D, 0x45, 0xC9, 0xBB, 0x20, 0x42, 0xB1, 0x9D, 0x1D
|
||||
};
|
||||
|
||||
constinit const u8 Package2RsaPublicModulusProduction[se::RsaSize] = {
|
||||
0x8D, 0x13, 0xA7, 0x77, 0x6A, 0xE5, 0xDC, 0xC0, 0x3B, 0x25, 0xD0, 0x58, 0xE4, 0x20, 0x69, 0x59,
|
||||
0x55, 0x4B, 0xAB, 0x70, 0x40, 0x08, 0x28, 0x07, 0xA8, 0xA7, 0xFD, 0x0F, 0x31, 0x2E, 0x11, 0xFE,
|
||||
0x47, 0xA0, 0xF9, 0x9D, 0xDF, 0x80, 0xDB, 0x86, 0x5A, 0x27, 0x89, 0xCD, 0x97, 0x6C, 0x85, 0xC5,
|
||||
0x6C, 0x39, 0x7F, 0x41, 0xF2, 0xFF, 0x24, 0x20, 0xC3, 0x95, 0xA6, 0xF7, 0x9D, 0x4A, 0x45, 0x74,
|
||||
0x8B, 0x5D, 0x28, 0x8A, 0xC6, 0x99, 0x35, 0x68, 0x85, 0xA5, 0x64, 0x32, 0x80, 0x9F, 0xD3, 0x48,
|
||||
0x39, 0xA2, 0x1D, 0x24, 0x67, 0x69, 0xDF, 0x75, 0xAC, 0x12, 0xB5, 0xBD, 0xC3, 0x29, 0x90, 0xBE,
|
||||
0x37, 0xE4, 0xA0, 0x80, 0x9A, 0xBE, 0x36, 0xBF, 0x1F, 0x2C, 0xAB, 0x2B, 0xAD, 0xF5, 0x97, 0x32,
|
||||
0x9A, 0x42, 0x9D, 0x09, 0x8B, 0x08, 0xF0, 0x63, 0x47, 0xA3, 0xE9, 0x1B, 0x36, 0xD8, 0x2D, 0x8A,
|
||||
0xD7, 0xE1, 0x54, 0x11, 0x95, 0xE4, 0x45, 0x88, 0x69, 0x8A, 0x2B, 0x35, 0xCE, 0xD0, 0xA5, 0x0B,
|
||||
0xD5, 0x5D, 0xAC, 0xDB, 0xAF, 0x11, 0x4D, 0xCA, 0xB8, 0x1E, 0xE7, 0x01, 0x9E, 0xF4, 0x46, 0xA3,
|
||||
0x8A, 0x94, 0x6D, 0x76, 0xBD, 0x8A, 0xC8, 0x3B, 0xD2, 0x31, 0x58, 0x0C, 0x79, 0xA8, 0x26, 0xE9,
|
||||
0xD1, 0x79, 0x9C, 0xCB, 0xD4, 0x2B, 0x6A, 0x4F, 0xC6, 0xCC, 0xCF, 0x90, 0xA7, 0xB9, 0x98, 0x47,
|
||||
0xFD, 0xFA, 0x4C, 0x6C, 0x6F, 0x81, 0x87, 0x3B, 0xCA, 0xB8, 0x50, 0xF6, 0x3E, 0x39, 0x5D, 0x4D,
|
||||
0x97, 0x3F, 0x0F, 0x35, 0x39, 0x53, 0xFB, 0xFA, 0xCD, 0xAB, 0xA8, 0x7A, 0x62, 0x9A, 0x3F, 0xF2,
|
||||
0x09, 0x27, 0x96, 0x3F, 0x07, 0x9A, 0x91, 0xF7, 0x16, 0xBF, 0xC6, 0x3A, 0x82, 0x5A, 0x4B, 0xCF,
|
||||
0x49, 0x50, 0x95, 0x8C, 0x55, 0x80, 0x7E, 0x39, 0xB1, 0x48, 0x05, 0x1E, 0x21, 0xC7, 0x24, 0x4F
|
||||
};
|
||||
|
||||
constinit const u8 Package2RsaPublicModulusDevelopment[se::RsaSize] = {
|
||||
0xB3, 0x65, 0x54, 0xFB, 0x0A, 0xB0, 0x1E, 0x85, 0xA7, 0xF6, 0xCF, 0x91, 0x8E, 0xBA, 0x96, 0x99,
|
||||
0x0D, 0x8B, 0x91, 0x69, 0x2A, 0xEE, 0x01, 0x20, 0x4F, 0x34, 0x5C, 0x2C, 0x4F, 0x4E, 0x37, 0xC7,
|
||||
0xF1, 0x0B, 0xD4, 0xCD, 0xA1, 0x7F, 0x93, 0xF1, 0x33, 0x59, 0xCE, 0xB1, 0xE9, 0xDD, 0x26, 0xE6,
|
||||
0xF3, 0xBB, 0x77, 0x87, 0x46, 0x7A, 0xD6, 0x4E, 0x47, 0x4A, 0xD1, 0x41, 0xB7, 0x79, 0x4A, 0x38,
|
||||
0x06, 0x6E, 0xCF, 0x61, 0x8F, 0xCD, 0xC1, 0x40, 0x0B, 0xFA, 0x26, 0xDC, 0xC0, 0x34, 0x51, 0x83,
|
||||
0xD9, 0x3B, 0x11, 0x54, 0x3B, 0x96, 0x27, 0x32, 0x9A, 0x95, 0xBE, 0x1E, 0x68, 0x11, 0x50, 0xA0,
|
||||
0x6B, 0x10, 0xA8, 0x83, 0x8B, 0xF5, 0xFC, 0xBC, 0x90, 0x84, 0x7A, 0x5A, 0x5C, 0x43, 0x52, 0xE6,
|
||||
0xC8, 0x26, 0xE9, 0xFE, 0x06, 0xA0, 0x8B, 0x53, 0x0F, 0xAF, 0x1E, 0xC4, 0x1C, 0x0B, 0xCF, 0x50,
|
||||
0x1A, 0xA4, 0xF3, 0x5C, 0xFB, 0xF0, 0x97, 0xE4, 0xDE, 0x32, 0x0A, 0x9F, 0xE3, 0x5A, 0xAA, 0xB7,
|
||||
0x44, 0x7F, 0x5C, 0x33, 0x60, 0xB9, 0x0F, 0x22, 0x2D, 0x33, 0x2A, 0xE9, 0x69, 0x79, 0x31, 0x42,
|
||||
0x8F, 0xE4, 0x3A, 0x13, 0x8B, 0xE7, 0x26, 0xBD, 0x08, 0x87, 0x6C, 0xA6, 0xF2, 0x73, 0xF6, 0x8E,
|
||||
0xA7, 0xF2, 0xFE, 0xFB, 0x6C, 0x28, 0x66, 0x0D, 0xBD, 0xD7, 0xEB, 0x42, 0xA8, 0x78, 0xE6, 0xB8,
|
||||
0x6B, 0xAE, 0xC7, 0xA9, 0xE2, 0x40, 0x6E, 0x89, 0x20, 0x82, 0x25, 0x8E, 0x3C, 0x6A, 0x60, 0xD7,
|
||||
0xF3, 0x56, 0x8E, 0xEC, 0x8D, 0x51, 0x8A, 0x63, 0x3C, 0x04, 0x78, 0x23, 0x0E, 0x90, 0x0C, 0xB4,
|
||||
0xE7, 0x86, 0x3B, 0x4F, 0x8E, 0x13, 0x09, 0x47, 0x32, 0x0E, 0x04, 0xB8, 0x4D, 0x5B, 0xB0, 0x46,
|
||||
0x71, 0xB0, 0x5C, 0xF4, 0xAD, 0x63, 0x4F, 0xC5, 0xE2, 0xAC, 0x1E, 0xC4, 0x33, 0x96, 0x09, 0x7B
|
||||
};
|
||||
|
||||
constinit const u8 Package2AesKey[] {
|
||||
0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7
|
||||
};
|
||||
NOINLINE void DecryptPayload(uintptr_t dst, uintptr_t src, size_t size, const void *iv, size_t iv_size, u8 key_generation) {
|
||||
secmon::boot::DecryptPackage2(reinterpret_cast<void *>(dst), size, reinterpret_cast<void *>(src), size, Package2AesKey, util::size(Package2AesKey), iv, iv_size, key_generation);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -215,4 +159,27 @@ namespace ams::secmon::boot {
|
|||
}
|
||||
}
|
||||
|
||||
void VerifyPackage2Header(const pkg2::Package2Meta &meta) {
|
||||
/* Validate the metadata. */
|
||||
CheckVerifyResult(VerifyPackage2Meta(meta), pkg1::ErrorInfo_InvalidPackage2Meta, "package2 meta verification failed");
|
||||
|
||||
/* Validate the version. */
|
||||
CheckVerifyResult(VerifyPackage2Version(meta), pkg1::ErrorInfo_InvalidPackage2Version, "package2 version verification failed");
|
||||
}
|
||||
|
||||
void DecryptAndLoadPackage2Payloads(uintptr_t dst, const pkg2::Package2Meta &meta, uintptr_t src, bool encrypted) {
|
||||
/* Get the key generation for crypto. */
|
||||
const u8 key_generation = meta.GetKeyGeneration();
|
||||
/* Decrypt or load each payload in order. */
|
||||
for (int i = 0; i < pkg2::PayloadCount; ++i) {
|
||||
if (encrypted) {
|
||||
DecryptPayload(dst + meta.payload_offsets[i], src, meta.payload_sizes[i], meta.payload_ivs[i], sizeof(meta.payload_ivs[i]), key_generation);
|
||||
} else {
|
||||
std::memcpy(reinterpret_cast<void *>(dst + meta.payload_offsets[i]), reinterpret_cast<void *>(src), meta.payload_sizes[i]);
|
||||
}
|
||||
|
||||
src += meta.payload_sizes[i];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,10 @@ namespace ams::secmon::boot {
|
|||
void VerifyPackage2HeaderSignature(pkg2::Package2Header &header, bool verify);
|
||||
void DecryptPackage2Header(pkg2::Package2Meta *dst, const pkg2::Package2Meta &src, bool encrypted);
|
||||
|
||||
void VerifyPackage2Header(const pkg2::Package2Meta &meta);
|
||||
|
||||
void DecryptAndLoadPackage2Payloads(uintptr_t dst, const pkg2::Package2Meta &meta, uintptr_t src, bool encrypted);
|
||||
|
||||
void CheckVerifyResult(bool verify_result, pkg1::ErrorInfo error_info, const char *message);
|
||||
|
||||
}
|
||||
|
|
82
exosphere2/program/source/boot/secmon_boot_key_data.cpp
Normal file
82
exosphere2/program/source/boot/secmon_boot_key_data.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "secmon_boot_key_data.hpp"
|
||||
|
||||
namespace ams::secmon::boot {
|
||||
|
||||
constinit const u8 BootConfigRsaPublicModulus[se::RsaSize] = {
|
||||
0xB5, 0x96, 0x87, 0x31, 0x39, 0xAA, 0xBB, 0x3C, 0x28, 0xF3, 0xF0, 0x65, 0xF1, 0x50, 0x70, 0x64,
|
||||
0xE6, 0x6C, 0x97, 0x50, 0xCD, 0xA6, 0xEE, 0xEA, 0xC3, 0x8F, 0xE6, 0xB5, 0x81, 0x54, 0x65, 0x33,
|
||||
0x1B, 0x88, 0x4B, 0xCE, 0x9F, 0x53, 0xDF, 0xE4, 0xF6, 0xAD, 0xC3, 0x78, 0xD7, 0x3C, 0xD1, 0xDB,
|
||||
0x27, 0x21, 0xA0, 0x24, 0x30, 0x2D, 0x98, 0x41, 0xA8, 0xDF, 0x50, 0x7D, 0xAB, 0xCE, 0x00, 0xD9,
|
||||
0xCB, 0xAC, 0x8F, 0x37, 0xF5, 0x53, 0xE4, 0x97, 0x1F, 0x13, 0x3C, 0x19, 0xFF, 0x05, 0xA7, 0x3B,
|
||||
0xF6, 0xF4, 0x01, 0xDE, 0xF0, 0xC3, 0x77, 0x7B, 0x83, 0xBA, 0xAF, 0x99, 0x30, 0x94, 0x87, 0x25,
|
||||
0x4E, 0x54, 0x42, 0x3F, 0xAC, 0x27, 0xF9, 0xCC, 0x87, 0xDD, 0xAE, 0xF2, 0x54, 0xF3, 0x97, 0x49,
|
||||
0xF4, 0xB0, 0xF8, 0x6D, 0xDA, 0x60, 0xE0, 0xFD, 0x57, 0xAE, 0x55, 0xA9, 0x76, 0xEA, 0x80, 0x24,
|
||||
0xA0, 0x04, 0x7D, 0xBE, 0xD1, 0x81, 0xD3, 0x0C, 0x95, 0xCF, 0xB7, 0xE0, 0x2D, 0x21, 0x21, 0xFF,
|
||||
0x97, 0x1E, 0xB3, 0xD7, 0x9F, 0xBB, 0x33, 0x0C, 0x23, 0xC5, 0x88, 0x4A, 0x33, 0xB9, 0xC9, 0x4E,
|
||||
0x1E, 0x65, 0x51, 0x45, 0xDE, 0xF9, 0x64, 0x7C, 0xF0, 0xBF, 0x11, 0xB4, 0x93, 0x8D, 0x5D, 0xC6,
|
||||
0xAB, 0x37, 0x9E, 0xE9, 0x39, 0xC1, 0xC8, 0xDB, 0xB9, 0xFE, 0x45, 0xCE, 0x7B, 0xDD, 0x72, 0xD9,
|
||||
0x6F, 0x68, 0x13, 0xC0, 0x4B, 0xBA, 0x00, 0xF4, 0x1E, 0x89, 0x71, 0x91, 0x26, 0xA6, 0x46, 0x12,
|
||||
0xDF, 0x29, 0x6B, 0xC2, 0x5A, 0x53, 0xAF, 0xB9, 0x5B, 0xFD, 0x13, 0x9F, 0xD1, 0x8A, 0x7C, 0xB5,
|
||||
0x04, 0xFD, 0x69, 0xEA, 0x23, 0xB4, 0x6D, 0x16, 0x21, 0x98, 0x54, 0xB4, 0xDF, 0xE6, 0xAB, 0x93,
|
||||
0x36, 0xB6, 0xD2, 0x43, 0xCF, 0x2B, 0x98, 0x1D, 0x45, 0xC9, 0xBB, 0x20, 0x42, 0xB1, 0x9D, 0x1D
|
||||
};
|
||||
|
||||
constinit const u8 Package2RsaPublicModulusProduction[se::RsaSize] = {
|
||||
0x8D, 0x13, 0xA7, 0x77, 0x6A, 0xE5, 0xDC, 0xC0, 0x3B, 0x25, 0xD0, 0x58, 0xE4, 0x20, 0x69, 0x59,
|
||||
0x55, 0x4B, 0xAB, 0x70, 0x40, 0x08, 0x28, 0x07, 0xA8, 0xA7, 0xFD, 0x0F, 0x31, 0x2E, 0x11, 0xFE,
|
||||
0x47, 0xA0, 0xF9, 0x9D, 0xDF, 0x80, 0xDB, 0x86, 0x5A, 0x27, 0x89, 0xCD, 0x97, 0x6C, 0x85, 0xC5,
|
||||
0x6C, 0x39, 0x7F, 0x41, 0xF2, 0xFF, 0x24, 0x20, 0xC3, 0x95, 0xA6, 0xF7, 0x9D, 0x4A, 0x45, 0x74,
|
||||
0x8B, 0x5D, 0x28, 0x8A, 0xC6, 0x99, 0x35, 0x68, 0x85, 0xA5, 0x64, 0x32, 0x80, 0x9F, 0xD3, 0x48,
|
||||
0x39, 0xA2, 0x1D, 0x24, 0x67, 0x69, 0xDF, 0x75, 0xAC, 0x12, 0xB5, 0xBD, 0xC3, 0x29, 0x90, 0xBE,
|
||||
0x37, 0xE4, 0xA0, 0x80, 0x9A, 0xBE, 0x36, 0xBF, 0x1F, 0x2C, 0xAB, 0x2B, 0xAD, 0xF5, 0x97, 0x32,
|
||||
0x9A, 0x42, 0x9D, 0x09, 0x8B, 0x08, 0xF0, 0x63, 0x47, 0xA3, 0xE9, 0x1B, 0x36, 0xD8, 0x2D, 0x8A,
|
||||
0xD7, 0xE1, 0x54, 0x11, 0x95, 0xE4, 0x45, 0x88, 0x69, 0x8A, 0x2B, 0x35, 0xCE, 0xD0, 0xA5, 0x0B,
|
||||
0xD5, 0x5D, 0xAC, 0xDB, 0xAF, 0x11, 0x4D, 0xCA, 0xB8, 0x1E, 0xE7, 0x01, 0x9E, 0xF4, 0x46, 0xA3,
|
||||
0x8A, 0x94, 0x6D, 0x76, 0xBD, 0x8A, 0xC8, 0x3B, 0xD2, 0x31, 0x58, 0x0C, 0x79, 0xA8, 0x26, 0xE9,
|
||||
0xD1, 0x79, 0x9C, 0xCB, 0xD4, 0x2B, 0x6A, 0x4F, 0xC6, 0xCC, 0xCF, 0x90, 0xA7, 0xB9, 0x98, 0x47,
|
||||
0xFD, 0xFA, 0x4C, 0x6C, 0x6F, 0x81, 0x87, 0x3B, 0xCA, 0xB8, 0x50, 0xF6, 0x3E, 0x39, 0x5D, 0x4D,
|
||||
0x97, 0x3F, 0x0F, 0x35, 0x39, 0x53, 0xFB, 0xFA, 0xCD, 0xAB, 0xA8, 0x7A, 0x62, 0x9A, 0x3F, 0xF2,
|
||||
0x09, 0x27, 0x96, 0x3F, 0x07, 0x9A, 0x91, 0xF7, 0x16, 0xBF, 0xC6, 0x3A, 0x82, 0x5A, 0x4B, 0xCF,
|
||||
0x49, 0x50, 0x95, 0x8C, 0x55, 0x80, 0x7E, 0x39, 0xB1, 0x48, 0x05, 0x1E, 0x21, 0xC7, 0x24, 0x4F
|
||||
};
|
||||
|
||||
constinit const u8 Package2RsaPublicModulusDevelopment[se::RsaSize] = {
|
||||
0xB3, 0x65, 0x54, 0xFB, 0x0A, 0xB0, 0x1E, 0x85, 0xA7, 0xF6, 0xCF, 0x91, 0x8E, 0xBA, 0x96, 0x99,
|
||||
0x0D, 0x8B, 0x91, 0x69, 0x2A, 0xEE, 0x01, 0x20, 0x4F, 0x34, 0x5C, 0x2C, 0x4F, 0x4E, 0x37, 0xC7,
|
||||
0xF1, 0x0B, 0xD4, 0xCD, 0xA1, 0x7F, 0x93, 0xF1, 0x33, 0x59, 0xCE, 0xB1, 0xE9, 0xDD, 0x26, 0xE6,
|
||||
0xF3, 0xBB, 0x77, 0x87, 0x46, 0x7A, 0xD6, 0x4E, 0x47, 0x4A, 0xD1, 0x41, 0xB7, 0x79, 0x4A, 0x38,
|
||||
0x06, 0x6E, 0xCF, 0x61, 0x8F, 0xCD, 0xC1, 0x40, 0x0B, 0xFA, 0x26, 0xDC, 0xC0, 0x34, 0x51, 0x83,
|
||||
0xD9, 0x3B, 0x11, 0x54, 0x3B, 0x96, 0x27, 0x32, 0x9A, 0x95, 0xBE, 0x1E, 0x68, 0x11, 0x50, 0xA0,
|
||||
0x6B, 0x10, 0xA8, 0x83, 0x8B, 0xF5, 0xFC, 0xBC, 0x90, 0x84, 0x7A, 0x5A, 0x5C, 0x43, 0x52, 0xE6,
|
||||
0xC8, 0x26, 0xE9, 0xFE, 0x06, 0xA0, 0x8B, 0x53, 0x0F, 0xAF, 0x1E, 0xC4, 0x1C, 0x0B, 0xCF, 0x50,
|
||||
0x1A, 0xA4, 0xF3, 0x5C, 0xFB, 0xF0, 0x97, 0xE4, 0xDE, 0x32, 0x0A, 0x9F, 0xE3, 0x5A, 0xAA, 0xB7,
|
||||
0x44, 0x7F, 0x5C, 0x33, 0x60, 0xB9, 0x0F, 0x22, 0x2D, 0x33, 0x2A, 0xE9, 0x69, 0x79, 0x31, 0x42,
|
||||
0x8F, 0xE4, 0x3A, 0x13, 0x8B, 0xE7, 0x26, 0xBD, 0x08, 0x87, 0x6C, 0xA6, 0xF2, 0x73, 0xF6, 0x8E,
|
||||
0xA7, 0xF2, 0xFE, 0xFB, 0x6C, 0x28, 0x66, 0x0D, 0xBD, 0xD7, 0xEB, 0x42, 0xA8, 0x78, 0xE6, 0xB8,
|
||||
0x6B, 0xAE, 0xC7, 0xA9, 0xE2, 0x40, 0x6E, 0x89, 0x20, 0x82, 0x25, 0x8E, 0x3C, 0x6A, 0x60, 0xD7,
|
||||
0xF3, 0x56, 0x8E, 0xEC, 0x8D, 0x51, 0x8A, 0x63, 0x3C, 0x04, 0x78, 0x23, 0x0E, 0x90, 0x0C, 0xB4,
|
||||
0xE7, 0x86, 0x3B, 0x4F, 0x8E, 0x13, 0x09, 0x47, 0x32, 0x0E, 0x04, 0xB8, 0x4D, 0x5B, 0xB0, 0x46,
|
||||
0x71, 0xB0, 0x5C, 0xF4, 0xAD, 0x63, 0x4F, 0xC5, 0xE2, 0xAC, 0x1E, 0xC4, 0x33, 0x96, 0x09, 0x7B
|
||||
};
|
||||
|
||||
constinit const u8 Package2AesKey[] {
|
||||
0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7
|
||||
};
|
||||
|
||||
}
|
26
exosphere2/program/source/boot/secmon_boot_key_data.hpp
Normal file
26
exosphere2/program/source/boot/secmon_boot_key_data.hpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <exosphere.hpp>
|
||||
|
||||
namespace ams::secmon::boot {
|
||||
|
||||
extern const u8 BootConfigRsaPublicModulus[se::RsaSize];
|
||||
extern const u8 Package2RsaPublicModulusDevelopment[se::RsaSize];
|
||||
extern const u8 Package2RsaPublicModulusProduction[se::RsaSize];
|
||||
extern const u8 Package2AesKey[se::AesBlockSize];
|
||||
|
||||
}
|
|
@ -326,6 +326,11 @@ namespace ams::secmon::boot {
|
|||
InvalidateL1Entries(l1, MemoryRegionPhysical.GetAddress(), MemoryRegionPhysical.GetSize());
|
||||
}
|
||||
|
||||
constexpr void UnmapDramImpl(u64 *l1, u64 *l2, u64 *l3) {
|
||||
/* Unmap the L1 entry corresponding to to the Dram entries. */
|
||||
InvalidateL1Entries(l1, MemoryRegionDram.GetAddress(), MemoryRegionDram.GetSize());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void InitializeColdBoot() {
|
||||
|
@ -366,4 +371,16 @@ namespace ams::secmon::boot {
|
|||
secmon::boot::EnsureMappingConsistency();
|
||||
}
|
||||
|
||||
void UnmapDram() {
|
||||
/* Get the tables. */
|
||||
u64 * const l1 = MemoryRegionPhysicalTzramL1PageTable.GetPointer<u64>();
|
||||
u64 * const l2_l3 = MemoryRegionPhysicalTzramL2L3PageTable.GetPointer<u64>();
|
||||
|
||||
/* Unmap. */
|
||||
UnmapDramImpl(l1, l2_l3, l2_l3);
|
||||
|
||||
/* Ensure the mappings are consistent. */
|
||||
secmon::boot::EnsureMappingConsistency();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,11 +17,19 @@
|
|||
#include "secmon_boot.hpp"
|
||||
#include "secmon_boot_functions.hpp"
|
||||
#include "../smc/secmon_random_cache.hpp"
|
||||
#include "../secmon_setup.hpp"
|
||||
#include "../secmon_cache.hpp"
|
||||
#include "../secmon_cpu_context.hpp"
|
||||
#include "../secmon_misc.hpp"
|
||||
#include "../secmon_setup.hpp"
|
||||
|
||||
namespace ams::secmon {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline const uintptr_t Package2LoadAddress = MemoryRegionDramPackage2Payloads.GetAddress();
|
||||
|
||||
}
|
||||
|
||||
void Main() {
|
||||
/* Set library register addresses. */
|
||||
/* actmon::SetRegisterAddress(MemoryRegionVirtualDeviceActivityMonitor.GetAddress()); */
|
||||
|
@ -122,7 +130,7 @@ namespace ams::secmon {
|
|||
|
||||
/* Parse and decrypt the package2 header. */
|
||||
pkg2::Package2Meta pkg2_meta;
|
||||
const uintptr_t pkg2_segments_start = MemoryRegionDramPackage2.GetAddress() + sizeof(pkg2::Package2Header);
|
||||
const uintptr_t pkg2_payloads_start = MemoryRegionDramPackage2.GetAddress() + sizeof(pkg2::Package2Header);
|
||||
{
|
||||
/* Read the encrypred header. */
|
||||
pkg2::Package2Header encrypted_header;
|
||||
|
@ -143,8 +151,38 @@ namespace ams::secmon {
|
|||
secmon::boot::DecryptPackage2Header(std::addressof(pkg2_meta), encrypted_header.meta, !bc.signed_data.IsPackage2EncryptionDisabled());
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
AMS_UNUSED(pkg2_segments_start);
|
||||
/* Verify the package2 header. */
|
||||
secmon::boot::VerifyPackage2Header(pkg2_meta);
|
||||
|
||||
/* Save the package2 hash if in recovery boot. */
|
||||
if (secmon::IsRecoveryBoot()) {
|
||||
se::Sha256Hash hash;
|
||||
secmon::boot::CalculatePackage2Hash(std::addressof(hash), pkg2_meta, MemoryRegionDramPackage2.GetAddress());
|
||||
secmon::SetPackage2Hash(hash);
|
||||
}
|
||||
|
||||
/* Verify the package2 payloads. */
|
||||
secmon::boot::CheckVerifyResult(secmon::boot::VerifyPackage2Payloads(pkg2_meta, pkg2_payloads_start), pkg1::ErrorInfo_InvalidPackage2Payload, "package2 payload verification failed");
|
||||
|
||||
/* Decrypt/Move the package2 payloads to the right places. */
|
||||
secmon::boot::DecryptAndLoadPackage2Payloads(Package2LoadAddress, pkg2_meta, pkg2_payloads_start, !bc.signed_data.IsPackage2EncryptionDisabled());
|
||||
|
||||
/* Ensure that the CPU sees correct package2 data. */
|
||||
secmon::FlushEntireDataCache();
|
||||
secmon::EnsureInstructionConsistency();
|
||||
|
||||
/* Set the core's entrypoint and argument. */
|
||||
secmon::SetEntryContext(0, Package2LoadAddress + pkg2_meta.entrypoint, 0);
|
||||
|
||||
/* Unmap DRAM. */
|
||||
secmon::boot::UnmapDram();
|
||||
|
||||
/* Wait for NX bootloader to be done. */
|
||||
secmon::boot::WaitForNxBootloader(secmon_params, pkg1::BootloaderState_Done);
|
||||
|
||||
/* Perform final initialization. */
|
||||
secmon::SetupSocProtections();
|
||||
secmon::SetupCpuSErrorDebug();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,23 @@
|
|||
#include "../secmon_error.hpp"
|
||||
#include "../secmon_key_storage.hpp"
|
||||
#include "secmon_boot.hpp"
|
||||
#include "secmon_boot_key_data.hpp"
|
||||
|
||||
namespace ams::secmon::boot {
|
||||
|
||||
void CalculatePackage2Hash(se::Sha256Hash *dst, const pkg2::Package2Meta &meta, uintptr_t package2_start) {
|
||||
/* Determine the region to hash. */
|
||||
const void *data = reinterpret_cast<const void *>(package2_start);
|
||||
const size_t size = meta.GetSize();
|
||||
|
||||
/* Flush to ensure the SE sees the correct data. */
|
||||
hw::FlushDataCache(data, size);
|
||||
hw::DataSynchronizationBarrierInnerShareable();
|
||||
|
||||
/* Calculate the hash. */
|
||||
se::CalculateSha256(dst, data, size);
|
||||
}
|
||||
|
||||
bool VerifyPackage2Signature(pkg2::Package2Header &header, const void *mod, size_t mod_size) {
|
||||
return VerifySignature(header.signature, sizeof(header.signature), mod, mod_size, std::addressof(header.meta), sizeof(header.meta));
|
||||
}
|
||||
|
@ -49,4 +63,90 @@ namespace ams::secmon::boot {
|
|||
hw::DataSynchronizationBarrierInnerShareable();
|
||||
}
|
||||
|
||||
bool VerifyPackage2Meta(const pkg2::Package2Meta &meta) {
|
||||
/* Get the obfuscated metadata. */
|
||||
const size_t size = meta.GetSize();
|
||||
const u8 key_generation = meta.GetKeyGeneration();
|
||||
|
||||
/* Check that size is big enough for the header. */
|
||||
if (size <= sizeof(pkg2::Package2Header)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check that the size isn't larger than what we allow. */
|
||||
if (size > pkg2::Package2SizeMax) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check that the key generation is one that we can use. */
|
||||
static_assert(pkg1::KeyGeneration_Count == 11);
|
||||
if (key_generation >= pkg1::KeyGeneration_Count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check the magic number. */
|
||||
if (!crypto::IsSameBytes(meta.magic, pkg2::Package2Meta::Magic::String, sizeof(meta.magic))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check the payload alignments. */
|
||||
if ((meta.entrypoint % pkg2::PayloadAlignment) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < pkg2::PayloadCount; ++i) {
|
||||
if ((meta.payload_sizes[i] % pkg2::PayloadAlignment) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that the sizes sum to the total. */
|
||||
if (size != sizeof(pkg2::Package2Header) + meta.payload_sizes[0] + meta.payload_sizes[1] + meta.payload_sizes[2]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check that the payloads do not overflow. */
|
||||
for (int i = 0; i < pkg2::PayloadCount; ++i) {
|
||||
if (meta.payload_offsets[i] > meta.payload_offsets[i] + meta.payload_sizes[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Verify that no payloads overlap. */
|
||||
for (int i = 0; i < pkg2::PayloadCount - 1; ++i) {
|
||||
for (int j = i + 1; j < pkg2::PayloadCount; ++j) {
|
||||
if (util::HasOverlap(meta.payload_offsets[i], meta.payload_sizes[i], meta.payload_offsets[j], meta.payload_sizes[j])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether any payload contains the entrypoint. */
|
||||
for (int i = 0; i < pkg2::PayloadCount; ++i) {
|
||||
if (util::Contains(meta.payload_offsets[i], meta.payload_sizes[i], meta.entrypoint)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* No payload contains the entrypoint, so we're not valid. */
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VerifyPackage2Version(const pkg2::Package2Meta &meta) {
|
||||
return meta.bootloader_version <= pkg2::CurrentBootloaderVersion && meta.package2_version >= pkg2::MinimumValidDataVersion;
|
||||
}
|
||||
|
||||
bool VerifyPackage2Payloads(const pkg2::Package2Meta &meta, uintptr_t payload_address) {
|
||||
/* Verify hashes match for all payloads. */
|
||||
for (int i = 0; i < pkg2::PayloadCount; ++i) {
|
||||
if (!VerifyHash(meta.payload_hashes[i], payload_address, meta.payload_sizes[i])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
payload_address += meta.payload_sizes[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
23
exosphere2/program/source/secmon_cache.cpp
Normal file
23
exosphere2/program/source/secmon_cache.cpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <exosphere.hpp>
|
||||
#include "secmon_cache.hpp"
|
||||
|
||||
namespace ams::secmon {
|
||||
|
||||
#include "secmon_cache_impl.inc"
|
||||
|
||||
}
|
|
@ -13,10 +13,11 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <exosphere.hpp>
|
||||
|
||||
namespace ams::secmon::boot {
|
||||
namespace ams::secmon {
|
||||
|
||||
/* TODO */
|
||||
#include "secmon_cache.inc"
|
||||
|
||||
}
|
|
@ -129,4 +129,4 @@ void EnsureInstructionConsistency() {
|
|||
::ams::hw::DataSynchronizationBarrierInnerShareable();
|
||||
|
||||
::ams::hw::InstructionSynchronizationBarrier();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@ namespace ams::secmon {
|
|||
|
||||
namespace {
|
||||
|
||||
pkg1::BctParameters g_bct_params;
|
||||
constinit pkg1::BctParameters g_bct_params = {};
|
||||
constinit se::Sha256Hash g_package2_hash = {};
|
||||
|
||||
}
|
||||
|
||||
|
@ -43,4 +44,12 @@ namespace ams::secmon {
|
|||
return dbg_auth.Get<hw::DbgAuthStatusEl1::Nsid>() == 3;
|
||||
}
|
||||
|
||||
}
|
||||
void GetPackage2Hash(se::Sha256Hash *out) {
|
||||
*out = g_package2_hash;
|
||||
}
|
||||
|
||||
void SetPackage2Hash(const se::Sha256Hash &hash) {
|
||||
g_package2_hash = hash;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,4 +26,7 @@ namespace ams::secmon {
|
|||
|
||||
bool IsJtagEnabled();
|
||||
|
||||
void GetPackage2Hash(se::Sha256Hash *out);
|
||||
void SetPackage2Hash(const se::Sha256Hash &hash);
|
||||
|
||||
}
|
|
@ -837,7 +837,7 @@ namespace ams::secmon {
|
|||
}
|
||||
|
||||
void SetupSocProtections() {
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void SetupPmcAndMcSecure() {
|
||||
|
@ -877,7 +877,21 @@ namespace ams::secmon {
|
|||
}
|
||||
|
||||
void SetupCpuSErrorDebug() {
|
||||
/* Get whether we should enable SError debug. */
|
||||
const auto &bc_data = secmon::GetBootConfig().data;
|
||||
const bool enabled = bc_data.IsDevelopmentFunctionEnabled() && bc_data.IsSErrorDebugEnabled();
|
||||
|
||||
/* Get and set scr_el3. */
|
||||
{
|
||||
util::BitPack32 scr;
|
||||
HW_CPU_GET_SCR_EL3(scr);
|
||||
|
||||
scr.Set<hw::ScrEl3::Ea>(enabled ? 0 : 1);
|
||||
HW_CPU_SET_SCR_EL3(scr);
|
||||
}
|
||||
|
||||
/* Prevent reordering instructions around this call. */
|
||||
hw::InstructionSynchronizationBarrier();
|
||||
}
|
||||
|
||||
}
|
|
@ -19,9 +19,9 @@
|
|||
namespace ams::pkg2 {
|
||||
|
||||
constexpr inline size_t Package2SizeMax = 8_MB - 16_KB;
|
||||
constexpr inline size_t SegmentAlignment = 4;
|
||||
constexpr inline size_t PayloadAlignment = 4;
|
||||
|
||||
constexpr inline int SegmentCount = 3;
|
||||
constexpr inline int PayloadCount = 3;
|
||||
|
||||
constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x10 in Nintendo's code. */
|
||||
constexpr inline int CurrentBootloaderVersion = 0xD;
|
||||
|
@ -32,7 +32,7 @@ namespace ams::pkg2 {
|
|||
u32 package2_size;
|
||||
u8 key_generation;
|
||||
u8 header_iv_remainder[11];
|
||||
u8 segment_iv[SegmentCount][0x10];
|
||||
u8 payload_ivs[PayloadCount][0x10];
|
||||
u8 padding_40[0x10];
|
||||
u8 magic[4];
|
||||
u32 entrypoint;
|
||||
|
@ -40,11 +40,11 @@ namespace ams::pkg2 {
|
|||
u8 package2_version;
|
||||
u8 bootloader_version;
|
||||
u8 padding_5E[2];
|
||||
u32 segment_sizes[SegmentCount];
|
||||
u32 payload_sizes[PayloadCount];
|
||||
u8 padding_6C[4];
|
||||
u32 segment_offsets[SegmentCount];
|
||||
u32 payload_offsets[PayloadCount];
|
||||
u8 padding_7C[4];
|
||||
u8 segment_hashes[SegmentCount][crypto::Sha256Generator::HashSize];
|
||||
u8 payload_hashes[PayloadCount][crypto::Sha256Generator::HashSize];
|
||||
u8 padding_E0[0x20];
|
||||
|
||||
private:
|
||||
|
@ -53,7 +53,7 @@ namespace ams::pkg2 {
|
|||
}
|
||||
public:
|
||||
ALWAYS_INLINE u8 GetKeyGeneration() const {
|
||||
return std::min<u8>(0, (this->key_generation ^ this->header_iv_remainder[1] ^ this->header_iv_remainder[2]) - 1);
|
||||
return static_cast<u8>(std::max<s32>(0, static_cast<s32>(this->key_generation ^ this->header_iv_remainder[1] ^ this->header_iv_remainder[2]) - 1));
|
||||
}
|
||||
|
||||
ALWAYS_INLINE u32 GetSize() const {
|
||||
|
|
|
@ -80,6 +80,9 @@ namespace ams::secmon {
|
|||
constexpr inline const MemoryRegion MemoryRegionDramDefaultKernelCarveout = MemoryRegion(UINT64_C(0x80060000), UINT64_C(0x1FFE0000));
|
||||
static_assert(MemoryRegionDram.Contains(MemoryRegionDramDefaultKernelCarveout));
|
||||
|
||||
constexpr inline const MemoryRegion MemoryRegionDramPackage2Payloads = MemoryRegion(MemoryRegionDram.GetAddress(), 8_MB);
|
||||
static_assert(MemoryRegionDram.Contains(MemoryRegionDramPackage2Payloads));
|
||||
|
||||
constexpr inline const MemoryRegion MemoryRegionDramPackage2 = MemoryRegion(UINT64_C(0xA9800000), UINT64_C(0x07FC0000));
|
||||
static_assert(MemoryRegionDram.Contains(MemoryRegionDramPackage2));
|
||||
|
||||
|
|
|
@ -36,5 +36,6 @@
|
|||
#include <vapours/util/util_tinymt.hpp>
|
||||
#include <vapours/util/util_uuid.hpp>
|
||||
#include <vapours/util/util_bounded_map.hpp>
|
||||
#include <vapours/util/util_overlap.hpp>
|
||||
#include <vapours/util/util_string_util.hpp>
|
||||
#include <vapours/util/util_variadic.hpp>
|
||||
|
|
35
libraries/libvapours/include/vapours/util/util_overlap.hpp
Normal file
35
libraries/libvapours/include/vapours/util/util_overlap.hpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <vapours/common.hpp>
|
||||
#include <vapours/assert.hpp>
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
constexpr inline bool HasOverlap(uintptr_t addr0, size_t size0, uintptr_t addr1, size_t size1) {
|
||||
if (addr0 <= addr1) {
|
||||
return addr1 < addr0 + size0;
|
||||
} else {
|
||||
return addr0 < addr1 + size1;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr inline bool Contains(uintptr_t addr, size_t size, uintptr_t ptr) {
|
||||
return (addr <= ptr) && (ptr < addr + size);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue