Compares DSi BIOS files against unsupported files

DSi BIOS files can have various hashes, so rather than compare them against an expected hash, we now compare them against unsupported hashes and throw an error if it matches one.
This commit is contained in:
Riley Testut 2021-02-18 17:16:44 -06:00
parent 7c3b67fbfb
commit edb2af4dd5
2 changed files with 40 additions and 9 deletions

View File

@ -32,6 +32,7 @@ private extension MelonDSCoreSettingsViewController
{ {
case unknownSize(URL) case unknownSize(URL)
case incorrectHash(URL, hash: String, expectedHash: String) case incorrectHash(URL, hash: String, expectedHash: String)
case unsupportedHash(URL, hash: String)
@available(iOS 13, *) @available(iOS 13, *)
case incorrectSize(URL, size: Int, validSizes: Set<ClosedRange<Measurement<UnitInformationStorage>>>) case incorrectSize(URL, size: Int, validSizes: Set<ClosedRange<Measurement<UnitInformationStorage>>>)
@ -50,7 +51,10 @@ private extension MelonDSCoreSettingsViewController
return String(format: NSLocalizedString("%@s size could not be determined.", comment: ""), fileURL.lastPathComponent) return String(format: NSLocalizedString("%@s size could not be determined.", comment: ""), fileURL.lastPathComponent)
case .incorrectHash(let fileURL, let md5Hash, let expectedHash): case .incorrectHash(let fileURL, let md5Hash, let expectedHash):
return String(format: NSLocalizedString("%@s hash does not match the expected hash.\n\nHash:\n%@\n\nExpected:\n%@.", comment: ""), fileURL.lastPathComponent, md5Hash, expectedHash) return String(format: NSLocalizedString("%@s checksum does not match the expected checksum.\n\nChecksum:\n%@\n\nExpected:\n%@", comment: ""), fileURL.lastPathComponent, md5Hash, expectedHash)
case .unsupportedHash(let fileURL, let md5Hash):
return String(format: NSLocalizedString("%@ is not compatible with this version of Delta.\n\nChecksum:\n%@", comment: ""), fileURL.lastPathComponent, md5Hash)
case .incorrectSize(let fileURL, let size, let validSizes): case .incorrectSize(let fileURL, let size, let validSizes):
let actualSize = BIOSError.byteFormatter.string(fromByteCount: Int64(size)) let actualSize = BIOSError.byteFormatter.string(fromByteCount: Int64(size))
@ -435,15 +439,21 @@ extension MelonDSCoreSettingsViewController: UIDocumentPickerDelegate
let measurement = Measurement<UnitInformationStorage>(value: Double(fileSize), unit: .bytes) let measurement = Measurement<UnitInformationStorage>(value: Double(fileSize), unit: .bytes)
guard bios.validFileSizes.contains(where: { $0.contains(measurement) }) else { throw BIOSError.incorrectSize(fileURL, size: fileSize, validSizes: bios.validFileSizes) } guard bios.validFileSizes.contains(where: { $0.contains(measurement) }) else { throw BIOSError.incorrectSize(fileURL, size: fileSize, validSizes: bios.validFileSizes) }
if let expectedMD5Hash = bios.expectedMD5Hash if bios.expectedMD5Hash != nil || !bios.unsupportedMD5Hashes.isEmpty
{ {
// If there's an expected hash, make sure it matches. // Only calculate hash if we need to.
let data = try Data(contentsOf: fileURL) let data = try Data(contentsOf: fileURL)
let md5Hash = Insecure.MD5.hash(data: data) let md5Hash = Insecure.MD5.hash(data: data)
let hashString = md5Hash.compactMap { String(format: "%02x", $0) }.joined() let hashString = md5Hash.compactMap { String(format: "%02x", $0) }.joined()
guard hashString == expectedMD5Hash else { throw BIOSError.incorrectHash(fileURL, hash: hashString, expectedHash: expectedMD5Hash) }
if let expectedMD5Hash = bios.expectedMD5Hash
{
guard hashString == expectedMD5Hash else { throw BIOSError.incorrectHash(fileURL, hash: hashString, expectedHash: expectedMD5Hash) }
}
guard !bios.unsupportedMD5Hashes.contains(hashString) else { throw BIOSError.unsupportedHash(fileURL, hash: hashString) }
} }
} }

View File

@ -16,6 +16,7 @@ protocol SystemBIOS
var filename: String { get } var filename: String { get }
var expectedMD5Hash: String? { get } var expectedMD5Hash: String? { get }
var unsupportedMD5Hashes: Set<String> { get }
// RangeSet would be preferable, but it's not in Swift stdlib yet. // RangeSet would be preferable, but it's not in Swift stdlib yet.
@available(iOS 13, *) @available(iOS 13, *)
@ -27,6 +28,14 @@ extension SystemBIOS
var filename: String { var filename: String {
return self.fileURL.lastPathComponent return self.fileURL.lastPathComponent
} }
var expectedMD5Hash: String? {
return nil
}
var unsupportedMD5Hashes: Set<String> {
return []
}
} }
enum DSBIOS: SystemBIOS, CaseIterable enum DSBIOS: SystemBIOS, CaseIterable
@ -88,13 +97,25 @@ enum DSiBIOS: SystemBIOS, CaseIterable
} }
} }
var expectedMD5Hash: String? { var unsupportedMD5Hashes: Set<String> {
switch self switch self
{ {
case .bios7: return "559dae4ea78eb9d67702c56c1d791e81" case .bios7:
case .bios9: return "87b665fce118f76251271c3732532777" return [
case .firmware: return nil "c8b9fe70f1ef5cab8e55540cd1c13dc8", // BIOSDSI7.ROM
case .nand: return nil "3fbb3f39bd9a96e5d743f138bd4b9907", // BIOSDSI9.ROM
"87b665fce118f76251271c3732532777", // bios9i.bin
]
case .bios9:
return [
"c8b9fe70f1ef5cab8e55540cd1c13dc8", // BIOSDSI7.ROM
"3fbb3f39bd9a96e5d743f138bd4b9907", // BIOSDSI9.ROM
"559dae4ea78eb9d67702c56c1d791e81", // bios7i.bin
]
case .firmware: return []
case .nand: return []
} }
} }