Do hash-based verification of disc images

This commit is contained in:
Irastris
2026-05-06 16:08:48 -04:00
parent 72c20f4dd0
commit 4404fce369
3 changed files with 19 additions and 19 deletions
+9 -8
View File
@@ -1,8 +1,8 @@
#include "iso_validate.hpp"
#include <nod.h>
#include "SDL3/SDL_iostream.h"
#include <SDL3/SDL_iostream.h>
#include <stdexcept>
namespace {
@@ -147,7 +147,7 @@ ValidationError verify_disc(NodHandle* disc, VerificationStatus& status) {
const auto hashState = XXH3_createState();
XXH3_128bits_reset(hashState);
while (!status.shouldCancel) {
while (true) {
size_t bytesAvail;
const auto buf = nod_buf_read(disc, &bytesAvail);
if (!bytesAvail)
@@ -159,13 +159,9 @@ ValidationError verify_disc(NodHandle* disc, VerificationStatus& status) {
nod_buf_consume(disc, bytesAvail);
}
if (status.shouldCancel) {
return ValidationError::Cancelled;
}
const auto hash = XXH3_128bits_digest(hashState);
if (!XXH128_isEqual(hash, status.knownDisc->hash)) {
return ValidationError::DiscHashMismatch;
return ValidationError::HashMismatch;
}
return ValidationError::Success;
@@ -214,6 +210,11 @@ ValidationError validate(const char* path, VerificationStatus& status) {
return verify_disc(disc.handle, status);
}
ValidationError validate(const char* path) {
VerificationStatus status{};
return validate(path, status);
}
bool isPal(const char* path) {
NodHandleWrapper disc;
+4 -4
View File
@@ -7,14 +7,13 @@ namespace dusk::iso {
struct KnownDisc;
enum class ValidationError : u8 {
Success = 0,
Unknown = 0,
IOError,
InvalidImage,
WrongGame,
WrongVersion,
Cancelled,
DiscHashMismatch,
Unknown
HashMismatch,
Success
};
struct VerificationStatus {
@@ -25,6 +24,7 @@ namespace dusk::iso {
};
ValidationError validate(const char* path, VerificationStatus& status);
ValidationError validate(const char* path);
bool isPal(const char* path);
}
+6 -7
View File
@@ -56,6 +56,8 @@ constexpr std::array<SDL_DialogFileFilter, 2> kDiscFileFilters{{
static std::string get_error_msg(iso::ValidationError error) {
switch (error) {
default:
return "The selected disc image could not be validated.";
case iso::ValidationError::IOError:
return "Unable to read the selected file.";
case iso::ValidationError::InvalidImage:
@@ -64,22 +66,19 @@ static std::string get_error_msg(iso::ValidationError error) {
return "The selected game is not supported by Dusk.";
case iso::ValidationError::WrongVersion:
return "Dusk currently supports GameCube USA and PAL disc images only.";
case iso::ValidationError::HashMismatch:
return "The selected disc image did not pass hash verification, it may be corrupt or modified.";
case iso::ValidationError::Success:
return "The selected disc image is valid.";
default:
return "The selected disc image could not be validated.";
}
}
void file_dialog_callback(void*, const char* path, const char* error) {
auto& state = prelaunch_state();
if (error != nullptr) {
return;
}
if (path == nullptr) {
if (path == nullptr || error != nullptr) {
return;
}
auto& state = prelaunch_state();
const auto validation = iso::validate(path);
if (validation != iso::ValidationError::Success) {
state.errorString = escape(get_error_msg(validation));