mirror of
https://github.com/azahar-emu/azahar.git
synced 2026-06-06 02:33:44 -04:00
core: Add CMAKE option to disable built-in keyblob
This commit is contained in:
parent
b2faa299d5
commit
a6caff24d8
7 changed files with 63 additions and 11 deletions
|
|
@ -137,6 +137,8 @@ option(ENABLE_SSE42 "Enable SSE4.2 optimizations on x86_64" ON)
|
|||
|
||||
option(ENABLE_DEVELOPER_OPTIONS "Enable functionality targeted at emulator developers" OFF)
|
||||
|
||||
option(ENABLE_BUILTIN_KEYBLOB "Enable the inclusion of the default crypto keys blob" ON)
|
||||
|
||||
# Compile options
|
||||
CMAKE_DEPENDENT_OPTION(COMPILE_WITH_DWARF "Add DWARF debugging information" ${IS_DEBUG_BUILD} "MINGW" OFF)
|
||||
option(ENABLE_LTO "Enable link time optimization" ${DEFAULT_ENABLE_LTO})
|
||||
|
|
|
|||
|
|
@ -183,6 +183,9 @@ endif()
|
|||
if(ENABLE_DEVELOPER_OPTIONS)
|
||||
add_compile_definitions(ENABLE_DEVELOPER_OPTIONS)
|
||||
endif()
|
||||
if(ENABLE_BUILTIN_KEYBLOB)
|
||||
add_compile_definitions(ENABLE_BUILTIN_KEYBLOB)
|
||||
endif()
|
||||
|
||||
add_subdirectory(common)
|
||||
add_subdirectory(core)
|
||||
|
|
|
|||
|
|
@ -670,12 +670,16 @@ void ConfigureSystem::RefreshSecureDataStatus() {
|
|||
return tr("Status: Loaded (Invalid Signature)");
|
||||
case HW::UniqueData::SecureDataLoadStatus::RegionChanged:
|
||||
return tr("Status: Loaded (Region Changed)");
|
||||
case HW::UniqueData::SecureDataLoadStatus::CannotValidateSignature:
|
||||
return tr("Status: Loaded (Cannot Validate Signature)");
|
||||
case HW::UniqueData::SecureDataLoadStatus::NotFound:
|
||||
return tr("Status: Not Found");
|
||||
case HW::UniqueData::SecureDataLoadStatus::Invalid:
|
||||
return tr("Status: Invalid");
|
||||
case HW::UniqueData::SecureDataLoadStatus::IOError:
|
||||
return tr("Status: IO Error");
|
||||
case HW::UniqueData::SecureDataLoadStatus::NoCryptoKeys:
|
||||
return tr("Status: Missing Crypto Keys");
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@
|
|||
#include "core/hle/service/fs/archive.h"
|
||||
#include "core/hw/aes/arithmetic128.h"
|
||||
#include "core/hw/aes/key.h"
|
||||
#ifdef ENABLE_BUILTIN_KEYBLOB
|
||||
#include "core/hw/default_keys.h"
|
||||
#endif // ENABLE_BUILTIN_KEYBLOB
|
||||
#include "core/hw/rsa/rsa.h"
|
||||
#include "core/loader/loader.h"
|
||||
|
||||
|
|
@ -130,8 +132,8 @@ std::array<std::optional<AESKey>, NumDlpNfcKeyYs> dlp_nfc_key_y_slots;
|
|||
std::array<NfcSecret, NumNfcSecrets> nfc_secrets;
|
||||
AESIV nfc_iv;
|
||||
|
||||
AESKey otp_key;
|
||||
AESIV otp_iv;
|
||||
AESKey otp_key{};
|
||||
AESIV otp_iv{};
|
||||
|
||||
// gets xor'd with the mac address to produce the final iv
|
||||
AESIV dlp_checksum_mod_iv;
|
||||
|
|
@ -297,6 +299,7 @@ std::istringstream GetKeysStream() {
|
|||
if (file.is_open()) {
|
||||
return std::istringstream(std::string(std::istreambuf_iterator<char>(file), {}));
|
||||
} else {
|
||||
#ifdef ENABLE_BUILTIN_KEYBLOB
|
||||
// The key data is encrypted in the source to prevent easy access to it for unintended
|
||||
// purposes.
|
||||
std::vector<u8> kiv(16);
|
||||
|
|
@ -304,6 +307,9 @@ std::istringstream GetKeysStream() {
|
|||
CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption(kiv.data(), kiv.size(), kiv.data())
|
||||
.ProcessData(reinterpret_cast<u8*>(s.data()), default_keys_enc, s.size());
|
||||
return std::istringstream(s);
|
||||
#else
|
||||
return std::istringstream("");
|
||||
#endif // ENABLE_BUILTIN_KEYBLOB
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020 Citra Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
|
@ -14,7 +14,8 @@ class RsaSlot {
|
|||
public:
|
||||
RsaSlot() = default;
|
||||
RsaSlot(std::vector<u8> exponent, std::vector<u8> modulus)
|
||||
: init(true), exponent(std::move(exponent)), modulus(std::move(modulus)) {}
|
||||
: init_exponent(true), init_modulus(true), exponent(std::move(exponent)),
|
||||
modulus(std::move(modulus)) {}
|
||||
|
||||
std::vector<u8> ModularExponentiation(std::span<const u8> message,
|
||||
int out_size_bytes = -1) const;
|
||||
|
|
@ -25,11 +26,12 @@ public:
|
|||
|
||||
explicit operator bool() const {
|
||||
// TODO(B3N30): Maybe check if exponent and modulus are vailid
|
||||
return init;
|
||||
return init_exponent && init_modulus;
|
||||
}
|
||||
|
||||
void SetExponent(const std::vector<u8>& e) {
|
||||
exponent = e;
|
||||
init_exponent = true;
|
||||
}
|
||||
|
||||
const std::vector<u8>& GetExponent() const {
|
||||
|
|
@ -38,6 +40,7 @@ public:
|
|||
|
||||
void SetModulus(const std::vector<u8>& m) {
|
||||
modulus = m;
|
||||
init_modulus = true;
|
||||
}
|
||||
|
||||
const std::vector<u8>& GetModulus() const {
|
||||
|
|
@ -46,6 +49,7 @@ public:
|
|||
|
||||
void SetPrivateD(const std::vector<u8>& d) {
|
||||
private_d = d;
|
||||
init_private_d = true;
|
||||
}
|
||||
|
||||
const std::vector<u8>& GetPrivateD() const {
|
||||
|
|
@ -53,7 +57,9 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
bool init = false;
|
||||
bool init_exponent = false;
|
||||
bool init_modulus = false;
|
||||
bool init_private_d = false;
|
||||
std::vector<u8> exponent;
|
||||
std::vector<u8> modulus;
|
||||
std::vector<u8> private_d;
|
||||
|
|
|
|||
|
|
@ -27,13 +27,17 @@ static MovableSedFull movable;
|
|||
static bool movable_signature_valid = false;
|
||||
|
||||
bool SecureInfoA::VerifySignature() const {
|
||||
return HW::RSA::GetSecureInfoSlot().Verify(
|
||||
std::span<const u8>(reinterpret_cast<const u8*>(&body), sizeof(body)), signature);
|
||||
auto sec_info_slot = HW::RSA::GetSecureInfoSlot();
|
||||
return sec_info_slot &&
|
||||
sec_info_slot.Verify(
|
||||
std::span<const u8>(reinterpret_cast<const u8*>(&body), sizeof(body)), signature);
|
||||
}
|
||||
|
||||
bool LocalFriendCodeSeedB::VerifySignature() const {
|
||||
return HW::RSA::GetLocalFriendCodeSeedSlot().Verify(
|
||||
std::span<const u8>(reinterpret_cast<const u8*>(&body), sizeof(body)), signature);
|
||||
auto lfcs_slot = HW::RSA::GetLocalFriendCodeSeedSlot();
|
||||
return lfcs_slot &&
|
||||
HW::RSA::GetLocalFriendCodeSeedSlot().Verify(
|
||||
std::span<const u8>(reinterpret_cast<const u8*>(&body), sizeof(body)), signature);
|
||||
}
|
||||
|
||||
bool MovableSed::VerifySignature() const {
|
||||
|
|
@ -42,6 +46,9 @@ bool MovableSed::VerifySignature() const {
|
|||
|
||||
SecureDataLoadStatus LoadSecureInfoA() {
|
||||
if (secure_info_a.IsValid()) {
|
||||
if (!HW::RSA::GetSecureInfoSlot()) {
|
||||
return SecureDataLoadStatus::CannotValidateSignature;
|
||||
}
|
||||
return secure_info_a_signature_valid
|
||||
? SecureDataLoadStatus::Loaded
|
||||
: (secure_info_a_region_changed ? SecureDataLoadStatus::RegionChanged
|
||||
|
|
@ -63,8 +70,11 @@ SecureDataLoadStatus LoadSecureInfoA() {
|
|||
return SecureDataLoadStatus::IOError;
|
||||
}
|
||||
|
||||
HW::AES::InitKeys();
|
||||
secure_info_a_region_changed = false;
|
||||
HW::AES::InitKeys();
|
||||
if (!HW::RSA::GetSecureInfoSlot()) {
|
||||
return SecureDataLoadStatus::CannotValidateSignature;
|
||||
}
|
||||
secure_info_a_signature_valid = secure_info_a.VerifySignature();
|
||||
if (!secure_info_a_signature_valid) {
|
||||
// Check if the file has been region changed
|
||||
|
|
@ -93,6 +103,9 @@ SecureDataLoadStatus LoadSecureInfoA() {
|
|||
|
||||
SecureDataLoadStatus LoadLocalFriendCodeSeedB() {
|
||||
if (local_friend_code_seed_b.IsValid()) {
|
||||
if (!HW::RSA::GetLocalFriendCodeSeedSlot()) {
|
||||
return SecureDataLoadStatus::CannotValidateSignature;
|
||||
}
|
||||
return local_friend_code_seed_b_signature_valid ? SecureDataLoadStatus::Loaded
|
||||
: SecureDataLoadStatus::InvalidSignature;
|
||||
}
|
||||
|
|
@ -114,6 +127,9 @@ SecureDataLoadStatus LoadLocalFriendCodeSeedB() {
|
|||
}
|
||||
|
||||
HW::AES::InitKeys();
|
||||
if (!HW::RSA::GetLocalFriendCodeSeedSlot()) {
|
||||
return SecureDataLoadStatus::CannotValidateSignature;
|
||||
}
|
||||
local_friend_code_seed_b_signature_valid = local_friend_code_seed_b.VerifySignature();
|
||||
if (!local_friend_code_seed_b_signature_valid) {
|
||||
LOG_WARNING(HW, "LocalFriendCodeSeed_B signature check failed");
|
||||
|
|
@ -128,10 +144,17 @@ SecureDataLoadStatus LoadOTP() {
|
|||
return SecureDataLoadStatus::Loaded;
|
||||
}
|
||||
|
||||
auto is_all_zero = [](const auto& arr) {
|
||||
return std::all_of(arr.begin(), arr.end(), [](auto x) { return x == 0; });
|
||||
};
|
||||
|
||||
const std::string filepath = GetOTPPath();
|
||||
|
||||
HW::AES::InitKeys();
|
||||
auto otp_keyiv = HW::AES::GetOTPKeyIV();
|
||||
if (is_all_zero(otp_keyiv.first) || is_all_zero(otp_keyiv.second)) {
|
||||
return SecureDataLoadStatus::NoCryptoKeys;
|
||||
}
|
||||
|
||||
auto loader_status = otp.Load(filepath, otp_keyiv.first, otp_keyiv.second);
|
||||
if (loader_status != Loader::ResultStatus::Success) {
|
||||
|
|
@ -169,6 +192,9 @@ SecureDataLoadStatus LoadOTP() {
|
|||
|
||||
SecureDataLoadStatus LoadMovable() {
|
||||
if (movable.IsValid()) {
|
||||
if (!HW::RSA::GetLocalFriendCodeSeedSlot()) {
|
||||
return SecureDataLoadStatus::CannotValidateSignature;
|
||||
}
|
||||
return movable_signature_valid ? SecureDataLoadStatus::Loaded
|
||||
: SecureDataLoadStatus::InvalidSignature;
|
||||
}
|
||||
|
|
@ -193,6 +219,9 @@ SecureDataLoadStatus LoadMovable() {
|
|||
}
|
||||
|
||||
HW::AES::InitKeys();
|
||||
if (!HW::RSA::GetLocalFriendCodeSeedSlot()) {
|
||||
return SecureDataLoadStatus::CannotValidateSignature;
|
||||
}
|
||||
movable_signature_valid = movable.VerifySignature();
|
||||
if (!movable_signature_valid) {
|
||||
LOG_WARNING(HW, "movable.sed signature check failed");
|
||||
|
|
|
|||
|
|
@ -136,10 +136,12 @@ enum class SecureDataLoadStatus {
|
|||
Loaded = 0,
|
||||
InvalidSignature = 1,
|
||||
RegionChanged = 2,
|
||||
CannotValidateSignature = 3,
|
||||
|
||||
NotFound = -1,
|
||||
Invalid = -2,
|
||||
IOError = -3,
|
||||
NoCryptoKeys = -4,
|
||||
};
|
||||
|
||||
SecureDataLoadStatus LoadSecureInfoA();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue