From edb2af4dd5a53ac4e822217ddcd1894718265db3 Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Thu, 18 Feb 2021 17:16:44 -0600 Subject: [PATCH] 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. --- .../MelonDSCoreSettingsViewController.swift | 18 ++++++++--- Delta/Settings/Cores/SystemBIOS.swift | 31 ++++++++++++++++--- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/Delta/Settings/Cores/MelonDSCoreSettingsViewController.swift b/Delta/Settings/Cores/MelonDSCoreSettingsViewController.swift index 8686fda..9556557 100644 --- a/Delta/Settings/Cores/MelonDSCoreSettingsViewController.swift +++ b/Delta/Settings/Cores/MelonDSCoreSettingsViewController.swift @@ -32,6 +32,7 @@ private extension MelonDSCoreSettingsViewController { case unknownSize(URL) case incorrectHash(URL, hash: String, expectedHash: String) + case unsupportedHash(URL, hash: String) @available(iOS 13, *) case incorrectSize(URL, size: Int, validSizes: Set>>) @@ -50,7 +51,10 @@ private extension MelonDSCoreSettingsViewController return String(format: NSLocalizedString("%@’s size could not be determined.", comment: ""), fileURL.lastPathComponent) 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): let actualSize = BIOSError.byteFormatter.string(fromByteCount: Int64(size)) @@ -435,15 +439,21 @@ extension MelonDSCoreSettingsViewController: UIDocumentPickerDelegate let measurement = Measurement(value: Double(fileSize), unit: .bytes) 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 md5Hash = Insecure.MD5.hash(data: data) 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) } } } diff --git a/Delta/Settings/Cores/SystemBIOS.swift b/Delta/Settings/Cores/SystemBIOS.swift index 5a847cf..19e965b 100644 --- a/Delta/Settings/Cores/SystemBIOS.swift +++ b/Delta/Settings/Cores/SystemBIOS.swift @@ -16,6 +16,7 @@ protocol SystemBIOS var filename: String { get } var expectedMD5Hash: String? { get } + var unsupportedMD5Hashes: Set { get } // RangeSet would be preferable, but it's not in Swift stdlib yet. @available(iOS 13, *) @@ -27,6 +28,14 @@ extension SystemBIOS var filename: String { return self.fileURL.lastPathComponent } + + var expectedMD5Hash: String? { + return nil + } + + var unsupportedMD5Hashes: Set { + return [] + } } enum DSBIOS: SystemBIOS, CaseIterable @@ -88,13 +97,25 @@ enum DSiBIOS: SystemBIOS, CaseIterable } } - var expectedMD5Hash: String? { + var unsupportedMD5Hashes: Set { switch self { - case .bios7: return "559dae4ea78eb9d67702c56c1d791e81" - case .bios9: return "87b665fce118f76251271c3732532777" - case .firmware: return nil - case .nand: return nil + case .bios7: + return [ + "c8b9fe70f1ef5cab8e55540cd1c13dc8", // BIOSDSI7.ROM + "3fbb3f39bd9a96e5d743f138bd4b9907", // BIOSDSI9.ROM + "87b665fce118f76251271c3732532777", // bios9i.bin + ] + + case .bios9: + return [ + "c8b9fe70f1ef5cab8e55540cd1c13dc8", // BIOSDSI7.ROM + "3fbb3f39bd9a96e5d743f138bd4b9907", // BIOSDSI9.ROM + "559dae4ea78eb9d67702c56c1d791e81", // bios7i.bin + ] + + case .firmware: return [] + case .nand: return [] } }