cIOS builder now re-encrypts vWii IOSes with the common key

Also added new wad vwii2wii command that will re-encrypt any input vWii WAD with the common key.
This commit is contained in:
Campbell 2024-10-26 19:14:29 -04:00
parent 55e38caf46
commit bcdb4fed21
Signed by: NinjaCheetah
GPG Key ID: B547958AF96ED344
4 changed files with 41 additions and 1 deletions

View File

@ -123,6 +123,14 @@ def build_cios(args):
except ValueError:
raise ValueError(f"The provided version \"{args.version}\" is not valid!")
# If this is a vWii cIOS, then we need to re-encrypt it with the Wii Common key so that it's installable from
# within Wii mode.
title_key_dec = title.ticket.get_title_key()
title_key_common = libWiiPy.title.encrypt_title_key(title_key_dec, 0, title.tmd.title_id)
title.ticket.title_key_enc = title_key_common
title.ticket.common_key_index = 0
title.tmd.vwii = 0
# Ensure the WAD is fakesigned.
title.fakesign()

View File

@ -95,7 +95,7 @@ def _print_ticket_info(ticket: libWiiPy.title.Ticket):
key = "vWii"
case _:
key = "Unknown (Likely Common)"
print(f" Common Key: {key}")
print(f" Decryption Key: {key}")
print(f" Title Key (Encrypted): {binascii.hexlify(ticket.title_key_enc).decode()}")
print(f" Title Key (Decrypted): {binascii.hexlify(ticket.get_title_key()).decode()}")

View File

@ -349,3 +349,28 @@ def handle_wad_r2d(args):
title.fakesign()
output_path.write_bytes(title.dump_wad())
print(f"Successfully converted retail WAD to development WAD \"{output_path.name}\"!")
def handle_wad_v2w(args):
input_path = pathlib.Path(args.input)
output_path = pathlib.Path(input_path.stem + "_Wii" + input_path.suffix)
if not input_path.exists():
raise FileNotFoundError(input_path)
title = libWiiPy.title.Title()
title.load_wad(input_path.read_bytes())
# First, verify that this IS actually a vWii WAD.
if title.ticket.common_key_index != 2:
raise ValueError("This is not a vWii WAD!")
# Now, extract the Title Key, change the required flags in the TMD/tik, and set the new common key encrypted
# Title Key. The WAD will also be fakesigned, since making this change invalidates the signature, so there's no
# downside.
title_key_dec = title.ticket.get_title_key()
title_key_common = libWiiPy.title.encrypt_title_key(title_key_dec, 0, title.tmd.title_id)
title.ticket.title_key_enc = title_key_common
title.ticket.common_key_index = 0
title.tmd.vwii = 0
title.fakesign()
output_path.write_bytes(title.dump_wad())
print(f"Successfully re-encrypted vWii WAD to regular WAD \"{output_path.name}\"!")

View File

@ -284,6 +284,13 @@ if __name__ == "__main__":
wad_unpack_parser.add_argument("output", metavar="OUT", type=str, help="output directory")
wad_unpack_parser.add_argument("-s", "--skip-hash", help="skips validating the hashes of decrypted "
"content", action="store_true")
# vwii2wii WAD subcommand.
wad_v2w_parser = wad_subparsers.add_parser("vwii2wii", help="re-encrypt a vWii WAD with the common key",
description="re-encrypt a vWii WAD with the common key, allowing it to "
"be installed in Dolphin and from within Wii mode on Wii U; "
"this also fakesigns the WAD")
wad_v2w_parser.set_defaults(func=handle_wad_v2w)
wad_v2w_parser.add_argument("input", metavar="IN", type=str, help="vWii WAD file to re-encrypt")
# Parse all the args, and call the appropriate function with all of those args if a valid subcommand was passed.