From b3923cfe405d78b0262f537525de8ae011eaaf02 Mon Sep 17 00:00:00 2001 From: NinjaCheetah <58050615+NinjaCheetah@users.noreply.github.com> Date: Sun, 3 Mar 2024 22:05:30 -0500 Subject: [PATCH] This makes 00000001.app work --- src/libWiiPy/content.py | 6 +++--- src/libWiiPy/crypto.py | 11 ++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libWiiPy/content.py b/src/libWiiPy/content.py index 2d47b0c..5eebe2b 100644 --- a/src/libWiiPy/content.py +++ b/src/libWiiPy/content.py @@ -35,7 +35,7 @@ class ContentRegion: self.num_contents = len(self.content_records) # Calculate the offsets of each content in the content region. for content in self.content_records[:-1]: - start_offset = int(16 * round(content.content_size / 16)) + self.content_start_offsets[-1] + start_offset = int(64 * round(content.content_size / 64)) + self.content_start_offsets[-1] self.content_start_offsets.append(start_offset) def get_enc_content(self, index: int) -> bytes: @@ -55,7 +55,7 @@ class ContentRegion: # Seek to the start of the requested content based on the list of offsets. content_region_data.seek(self.content_start_offsets[index]) # Calculate the number of bytes we need to read by rounding the size to the nearest 16 bytes. - bytes_to_read = int(16 * round(self.content_records[index].content_size / 16)) + bytes_to_read = int(64 * round(self.content_records[index].content_size / 64)) # Read the file based on the size of the content in the associated record. content_enc = content_region_data.read(bytes_to_read) return content_enc @@ -77,7 +77,7 @@ class ContentRegion: """ # Load the encrypted content at the specified index and then decrypt it with the Title Key. content_enc = self.get_enc_content(index) - content_dec = decrypt_content(content_enc, title_key, self.content_records[index].index) + content_dec = decrypt_content(content_enc, title_key, self.content_records[index].index, self.content_records[index].content_size) # Hash the decrypted content and ensure that the hash matches the one in its Content Record. # If it does not, then something has gone wrong in the decryption, and an error will be thrown. content_dec_hash = hashlib.sha1(content_dec) diff --git a/src/libWiiPy/crypto.py b/src/libWiiPy/crypto.py index 7c4c0ee..4e8abef 100644 --- a/src/libWiiPy/crypto.py +++ b/src/libWiiPy/crypto.py @@ -39,7 +39,7 @@ def decrypt_title_key(title_key_enc, common_key_index, title_id): return title_key -def decrypt_content(content_enc, title_key, content_index): +def decrypt_content(content_enc, title_key, content_index, content_length): """Gets the decrypted version of the encrypted content. Requires the index of the common key to use, and the Title ID of the title that the Title Key is for. @@ -62,15 +62,16 @@ def decrypt_content(content_enc, title_key, content_index): content_index_bin += b'\x00' # In CBC mode, content must be padded out to a 16-byte boundary, so do that here, and then remove bytes added after. padded = False - if (len(content_enc) % 64) != 0: + if (len(content_enc) % 128) != 0: print("needs padding to 16 bytes") - content_enc = pad(content_enc, 64, "pkcs7") + content_enc = pad(content_enc, 128, "pkcs7") padded = True # Create a new AES object with the values provided, with the content's unique ID as the IV. aes = AES.new(title_key, AES.MODE_CBC, content_index_bin) # Decrypt the content using the AES object. content_dec = aes.decrypt(content_enc) # Remove padding bytes, if any were added. - #if padded: - #content_dec = unpad(content_dec, AES.block_size) + if padded: + while len(content_dec) > content_length: + content_dec = content_dec[:-1] return content_dec