mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
Validate firmware before installing
This commit is contained in:
parent
925f2ce02f
commit
e9ea226e30
@ -152,6 +152,13 @@ static u8 SCEPKG_ERK[0x20] = {
|
||||
0x4D, 0xBC, 0xB2, 0xCB, 0x52, 0xC5, 0xA2, 0xF8, 0xB0, 0x2B, 0x10, 0x31
|
||||
};
|
||||
|
||||
static u8 PUP_KEY[0x40] = {
|
||||
0xF4, 0x91, 0xAD, 0x94, 0xC6, 0x81, 0x10, 0x96, 0x91, 0x5F, 0xD5, 0xD2, 0x44, 0x81, 0xAE, 0xDC, 0xED, 0xED, 0xBE, 0x6B,
|
||||
0xE5, 0x13, 0x72, 0x4D, 0xD8, 0xF7, 0xB6, 0x91, 0xE8, 0x8A, 0x38, 0xF4, 0xB5, 0x16, 0x2B, 0xFB, 0xEC, 0xBE, 0x3A, 0x62,
|
||||
0x18, 0x5D, 0xD7, 0xC9, 0x4D, 0xA2, 0x22, 0x5A, 0xDA, 0x3F, 0xBF, 0xCE, 0x55, 0x5B, 0x9E, 0xA9, 0x64, 0x98, 0x29, 0xEB,
|
||||
0x30, 0xCE, 0x83, 0x66
|
||||
};
|
||||
|
||||
class KeyVault
|
||||
{
|
||||
std::vector<SELF_KEY> sk_LV0_arr;
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "Crypto/sha1.h"
|
||||
#include "Crypto/key_vault.h"
|
||||
|
||||
#include "PUP.h"
|
||||
|
||||
pup_object::pup_object(const fs::file& file): m_file(file)
|
||||
@ -10,6 +13,7 @@ pup_object::pup_object(const fs::file& file): m_file(file)
|
||||
return;
|
||||
}
|
||||
|
||||
m_file.seek(0);
|
||||
PUPHeader m_header;
|
||||
m_file.read(m_header);
|
||||
if (m_header.magic != "SCEUF\0\0\0"_u64)
|
||||
@ -40,3 +44,24 @@ fs::file pup_object::get_file(u64 entry_id)
|
||||
}
|
||||
return fs::file();
|
||||
}
|
||||
|
||||
bool pup_object::validate_hashes()
|
||||
{
|
||||
for (size_t i = 0; i < m_file_tbl.size(); i++)
|
||||
{
|
||||
u8 *hash = m_hash_tbl[i].hash;
|
||||
PUPFileEntry file = m_file_tbl[i];
|
||||
|
||||
std::vector<u8> buffer(file.data_length);
|
||||
m_file.seek(file.data_offset);
|
||||
m_file.read(buffer.data(), file.data_length);
|
||||
|
||||
u8 output[20] = {};
|
||||
sha1_hmac(PUP_KEY, sizeof(PUP_KEY), buffer.data(), buffer.size(), output);
|
||||
if (memcmp(output, hash, 20) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -44,4 +44,5 @@ public:
|
||||
explicit operator bool() const { return isValid; }
|
||||
|
||||
fs::file get_file(u64 entry_id);
|
||||
bool validate_hashes();
|
||||
};
|
||||
|
@ -506,6 +506,24 @@ void main_window::InstallPup(const QString& dropPath)
|
||||
return;
|
||||
}
|
||||
|
||||
if (pup_f.size() < sizeof(PUPHeader))
|
||||
{
|
||||
LOG_ERROR(GENERAL, "Too small PUP file: %llu", pup_f.size());
|
||||
QMessageBox::critical(this, tr("Failure!"), tr("Error while installing firmware: PUP file size is invalid."));
|
||||
return;
|
||||
}
|
||||
|
||||
struct PUPHeader header = {};
|
||||
pup_f.seek(0);
|
||||
pup_f.read(header);
|
||||
|
||||
if (header.header_length + header.data_length != pup_f.size())
|
||||
{
|
||||
LOG_ERROR(GENERAL, "Firmware size mismatch, expected: %llu, actual: %llu + %llu", pup_f.size(), header.header_length, header.data_length);
|
||||
QMessageBox::critical(this, tr("Failure!"), tr("Error while installing firmware: PUP file is corrupted."));
|
||||
return;
|
||||
}
|
||||
|
||||
pup_object pup(pup_f);
|
||||
if (!pup)
|
||||
{
|
||||
@ -514,6 +532,13 @@ void main_window::InstallPup(const QString& dropPath)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pup.validate_hashes())
|
||||
{
|
||||
LOG_ERROR(GENERAL, "Error while installing firmware: Hash check failed. ");
|
||||
QMessageBox::critical(this, tr("Failure!"), tr("Error while installing firmware: PUP file contents are invalid."));
|
||||
return;
|
||||
}
|
||||
|
||||
fs::file update_files_f = pup.get_file(0x300);
|
||||
tar_object update_files(update_files_f);
|
||||
auto updatefilenames = update_files.get_filenames();
|
||||
|
Loading…
Reference in New Issue
Block a user