Added function to crypto.py for encrypting a title key

This commit is contained in:
Campbell 2024-05-03 15:10:17 -04:00
parent c92a8096ea
commit 9890a6dbac
3 changed files with 41 additions and 6 deletions

View File

@ -6,6 +6,7 @@
from .commonkeys import * from .commonkeys import *
from .content import * from .content import *
from .ticket import * from .ticket import *
from .crypto import *
from .title import * from .title import *
from .tmd import * from .tmd import *
from .wad import * from .wad import *

View File

@ -1,8 +1,10 @@
# "crypto.py" from libWiiPy by NinjaCheetah & Contributors # "crypto.py" from libWiiPy by NinjaCheetah & Contributors
# https://github.com/NinjaCheetah/libWiiPy # https://github.com/NinjaCheetah/libWiiPy
import binascii
import struct import struct
from .commonkeys import get_common_key from .commonkeys import get_common_key
from Crypto.Cipher import AES 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 title_key_enc : bytes
The encrypted Title Key. The encrypted Title Key.
common_key_index : int 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 title_id : bytes
The title ID of the title that the key is for. 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. # Load the correct common key for the title.
common_key = get_common_key(common_key_index) common_key = get_common_key(common_key_index)
# Calculate the IV by adding 8 bytes to the end of the Title ID. # 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. # Create a new AES object with the values provided.
aes = AES.new(common_key, AES.MODE_CBC, title_key_iv) aes = AES.new(common_key, AES.MODE_CBC, title_key_iv)
# Decrypt the Title Key using the AES object. # 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 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: def decrypt_content(content_enc, title_key, content_index, content_length) -> bytes:
""" """
Gets the decrypted version of the encrypted content. Gets the decrypted version of the encrypted content.

View File

@ -99,10 +99,9 @@ class Ticket:
self.console_id = int.from_bytes(ticket_data.read(4)) self.console_id = int.from_bytes(ticket_data.read(4))
# Title ID. # Title ID.
ticket_data.seek(0x1DC) 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 (as a string).
title_id_hex = binascii.hexlify(self.title_id) self.title_id_str = str(self.title_id.decode())
self.title_id_str = str(title_id_hex.decode())
# Unknown data 1. # Unknown data 1.
ticket_data.seek(0x1E4) ticket_data.seek(0x1E4)
self.unknown1 = ticket_data.read(2) self.unknown1 = ticket_data.read(2)
@ -172,7 +171,7 @@ class Ticket:
# Console ID. # Console ID.
ticket_data.write(int.to_bytes(self.console_id, 4)) ticket_data.write(int.to_bytes(self.console_id, 4))
# Title ID. # Title ID.
ticket_data.write(self.title_id) ticket_data.write(binascii.unhexlify(self.title_id))
# Unknown data 1. # Unknown data 1.
ticket_data.write(self.unknown1) ticket_data.write(self.unknown1)
# Title version. # Title version.