PabloMK7 dc1ebb63cb Major revamps to match game loading decisions.
- Allow downloading titles from eshop and system settings
- Remove encrypted game support
2025-02-27 14:22:50 +01:00

57 lines
1.8 KiB
C++

// Copyright 2024 Azahar Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <cryptopp/aes.h>
#include <cryptopp/modes.h>
#include <cryptopp/sha.h>
#include "common/file_util.h"
#include "common/logging/log.h"
#include "core/file_sys/otp.h"
#include "core/loader/loader.h"
namespace FileSys {
Loader::ResultStatus OTP::Load(const std::string& file_path, std::span<const u8> key,
std::span<const u8> iv) {
FileUtil::IOFile file(file_path, "rb");
if (!file.IsOpen())
return Loader::ResultStatus::ErrorNotFound;
if (file.GetSize() != sizeof(OTPBin)) {
LOG_ERROR(HW_AES, "Invalid OTP size");
return Loader::ResultStatus::Error;
}
OTPBin temp_otp;
if (file.ReadBytes(&temp_otp, sizeof(OTPBin)) != sizeof(OTPBin)) {
return Loader::ResultStatus::Error;
}
// OTP is probably encrypted, decrypt it.
if (temp_otp.body.magic != otp_magic) {
CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption d;
d.SetKeyWithIV(key.data(), key.size(), iv.data());
d.ProcessData(reinterpret_cast<u8*>(&temp_otp), reinterpret_cast<u8*>(&temp_otp),
sizeof(temp_otp));
if (temp_otp.body.magic != otp_magic) {
LOG_ERROR(HW_AES, "OTP failed to decrypt (or uses dev keys)");
return Loader::ResultStatus::Error;
}
}
// Verify OTP hash
CryptoPP::SHA256 hash;
std::array<u8, CryptoPP::SHA256::DIGESTSIZE> digest;
hash.CalculateDigest(digest.data(), reinterpret_cast<u8*>(&temp_otp.body),
sizeof(temp_otp.body));
if (temp_otp.hash != digest) {
LOG_ERROR(HW_AES, "OTP is corrupted");
return Loader::ResultStatus::Error;
}
otp = temp_otp;
return Loader::ResultStatus::Success;
}
} // namespace FileSys