diff --git a/src/libWiiPy/__init__.py b/src/libWiiPy/__init__.py index c8b475a..2df7705 100644 --- a/src/libWiiPy/__init__.py +++ b/src/libWiiPy/__init__.py @@ -6,6 +6,7 @@ from .commonkeys import * from .content import * from .ticket import * +from .crypto import * from .title import * from .tmd import * from .wad import * diff --git a/src/libWiiPy/crypto.py b/src/libWiiPy/crypto.py index 7e2c8b1..907a766 100644 --- a/src/libWiiPy/crypto.py +++ b/src/libWiiPy/crypto.py @@ -1,8 +1,10 @@ # "crypto.py" from libWiiPy by NinjaCheetah & Contributors # https://github.com/NinjaCheetah/libWiiPy +import binascii import struct from .commonkeys import get_common_key + from Crypto.Cipher import AES @@ -17,7 +19,7 @@ def decrypt_title_key(title_key_enc, common_key_index, title_id) -> bytes: title_key_enc : bytes The encrypted Title Key. common_key_index : int - The index of the common key to be returned. + The index of the common key used to encrypt the Title Key. title_id : bytes The title ID of the title that the key is for. @@ -29,7 +31,8 @@ def decrypt_title_key(title_key_enc, common_key_index, title_id) -> bytes: # Load the correct common key for the title. common_key = get_common_key(common_key_index) # Calculate the IV by adding 8 bytes to the end of the Title ID. - title_key_iv = title_id + (b'\x00' * 8) + title_key_iv = binascii.unhexlify(title_id) + title_key_iv = title_key_iv + (b'\x00' * 8) # Create a new AES object with the values provided. aes = AES.new(common_key, AES.MODE_CBC, title_key_iv) # Decrypt the Title Key using the AES object. @@ -37,6 +40,38 @@ def decrypt_title_key(title_key_enc, common_key_index, title_id) -> bytes: return title_key +def encrypt_title_key(title_key_dec, common_key_index, title_id) -> bytes: + """ + Encrypts the provided Title Key with the selected common key. + + Requires the index of the common key to use, and the Title ID of the title that the Title Key is for. + + Parameters + ---------- + title_key_dec : bytes + The decrypted Title Key. + common_key_index : int + The index of the common key used to encrypt the Title Key. + title_id : bytes + The title ID of the title that the key is for. + + Returns + ------- + bytes + An encrypted Title Key. + """ + # Load the correct common key for the title. + common_key = get_common_key(common_key_index) + # Calculate the IV by adding 8 bytes to the end of the Title ID. + title_key_iv = binascii.unhexlify(title_id) + title_key_iv = title_key_iv + (b'\x00' * 8) + # Create a new AES object with the values provided. + aes = AES.new(common_key, AES.MODE_CBC, title_key_iv) + # Encrypt Title Key using the AES object. + title_key = aes.encrypt(title_key_dec) + return title_key + + def decrypt_content(content_enc, title_key, content_index, content_length) -> bytes: """ Gets the decrypted version of the encrypted content. diff --git a/src/libWiiPy/ticket.py b/src/libWiiPy/ticket.py index 2cefbdc..45c8136 100644 --- a/src/libWiiPy/ticket.py +++ b/src/libWiiPy/ticket.py @@ -99,10 +99,9 @@ class Ticket: self.console_id = int.from_bytes(ticket_data.read(4)) # Title ID. ticket_data.seek(0x1DC) - self.title_id = ticket_data.read(8) + self.title_id = binascii.hexlify(ticket_data.read(8)) # Title ID (as a string). - title_id_hex = binascii.hexlify(self.title_id) - self.title_id_str = str(title_id_hex.decode()) + self.title_id_str = str(self.title_id.decode()) # Unknown data 1. ticket_data.seek(0x1E4) self.unknown1 = ticket_data.read(2) @@ -172,7 +171,7 @@ class Ticket: # Console ID. ticket_data.write(int.to_bytes(self.console_id, 4)) # Title ID. - ticket_data.write(self.title_id) + ticket_data.write(binascii.unhexlify(self.title_id)) # Unknown data 1. ticket_data.write(self.unknown1) # Title version.