From fba3fe7d058af601288b1ce9d1afd92461de039d Mon Sep 17 00:00:00 2001 From: Maksim Totmin Date: Sun, 31 May 2026 19:10:44 +0700 Subject: [PATCH] Add HASHAB signing to iTunesCDB header + fix sync_itunescdb - Set hashing_scheme=3 at offset 0x30 (iPod Nano 7G requirement) - Compute and write HASHAB signature at offset 0xAB - Import compute_hashab from hashab module - iTunesCDB.ext creation restored (was removed accidentally) - 0-byte iTunesDB placeholder (firmware expects this file) --- src/ipod_nano7_db.py | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/ipod_nano7_db.py b/src/ipod_nano7_db.py index 8df3ebb..c5d060a 100644 --- a/src/ipod_nano7_db.py +++ b/src/ipod_nano7_db.py @@ -1200,30 +1200,59 @@ class Nano7Database: """ import zlib import re + from hashab import compute_hashab # Read current Library.itdb with open(self.sqlite_path, "rb") as f: lib_data = f.read() - # Compute new SHA1 hash + # Compute new SHA1 hash of Library.itdb for iTunesCDB.ext new_hash = hashlib.sha1(lib_data).hexdigest() compressed = zlib.compress(lib_data) total_size = 244 + len(compressed) - # Build proper mhfd header + # Build mhfd header header = bytearray(244) header[0:4] = b"mhfd" struct.pack_into("= 8: + try: + signature = compute_hashab(hashlib.sha1(itdb_data).digest(), self.firewire_id) + header[0xAB:0xAB + 57] = signature + itdb_data = bytes(header) + compressed + logger.info("HASHAB signature written to iTunesCDB header") + except Exception as e: + logger.warning("HASHAB signing failed for iTunesCDB: %s", e) + # Write new iTunesCDB with open(self.cdb_path, "wb") as f: - f.write(bytes(header) + compressed) + f.write(itdb_data) logger.info(f"Synced iTunesCDB: hash={new_hash}, compressed={len(compressed)} bytes") + # Update hash in iTunesCDB.ext + if not os.path.exists(self.cdb_ext_path): + ext_content = f"[iTunesCDB]\nitunesdb_hash={new_hash}\n" + else: + with open(self.cdb_ext_path, "r") as f: + ext_content = f.read() + new_ext_content = re.sub(r"itunesdb_hash=\w+", f"itunesdb_hash={new_hash}", ext_content) + with open(self.cdb_ext_path, "w") as f: + f.write(new_ext_content) + + logger.info(f"Updated iTunesCDB.ext: hash={new_hash}") + def sync_locations_cbk(self): """Regenerate Locations.itdb.cbk with HASHAB-signed block checksums.