Make is_dev for get_common_key() non-optional

This commit is contained in:
Campbell 2025-04-03 13:41:44 -04:00
parent 405df67e49
commit 0bda6dabf3
Signed by: NinjaCheetah
GPG Key ID: 39C2500E1778B156
6 changed files with 36 additions and 14 deletions

21
Cargo.lock generated
View File

@ -517,6 +517,7 @@ dependencies = [
"regex",
"rsa",
"sha1",
"thiserror",
]
[[package]]
@ -596,6 +597,26 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "typenum"
version = "1.18.0"

View File

@ -34,3 +34,4 @@ glob = "0"
regex = "1"
clap = { version = "4", features = ["derive"] }
anyhow = "1"
thiserror = "2"

View File

@ -117,21 +117,21 @@ pub fn convert_wad(input: &str, target: &ConvertTargets, output: &Option<String>
Target::Dev => {
title.tmd.set_signature_issuer(String::from("Root-CA00000002-CP00000007"))?;
title.ticket.set_signature_issuer(String::from("Root-CA00000002-XS00000006"))?;
title_key_new = crypto::encrypt_title_key(title_key, 0, title.ticket.title_id, Some(true));
title_key_new = crypto::encrypt_title_key(title_key, 0, title.ticket.title_id, true);
title.ticket.common_key_index = 0;
title.tmd.is_vwii = 0;
},
Target::Retail => {
title.tmd.set_signature_issuer(String::from("Root-CA00000001-CP00000004"))?;
title.ticket.set_signature_issuer(String::from("Root-CA00000001-XS00000003"))?;
title_key_new = crypto::encrypt_title_key(title_key, 0, title.ticket.title_id, Some(false));
title_key_new = crypto::encrypt_title_key(title_key, 0, title.ticket.title_id, false);
title.ticket.common_key_index = 0;
title.tmd.is_vwii = 0;
},
Target::Vwii => {
title.tmd.set_signature_issuer(String::from("Root-CA00000001-CP00000004"))?;
title.ticket.set_signature_issuer(String::from("Root-CA00000001-XS00000003"))?;
title_key_new = crypto::encrypt_title_key(title_key, 2, title.ticket.title_id, Some(false));
title_key_new = crypto::encrypt_title_key(title_key, 2, title.ticket.title_id, false);
title.ticket.common_key_index = 2;
title.tmd.is_vwii = 1;
}

View File

@ -8,7 +8,7 @@ const DEV_COMMON_KEY: &str = "a1604a6a7123b529ae8bec32c816fcaa";
/// Returns the common key for the specified index. Providing Some(true) for the optional argument
/// is_dev will make index 0 return the development common key instead of the retail common key.
pub fn get_common_key(index: u8, is_dev: Option<bool>) -> [u8; 16] {
pub fn get_common_key(index: u8, is_dev: bool) -> [u8; 16] {
// Match the Korean and vWii keys, and if they don't match then fall back on the common key.
// The is_dev argument is an option, and if it's set to false or None, then the regular
// common key will be used.
@ -18,8 +18,8 @@ pub fn get_common_key(index: u8, is_dev: Option<bool>) -> [u8; 16] {
2 => selected_key = VWII_KEY,
_ => {
match is_dev {
Some(true) => selected_key = DEV_COMMON_KEY,
_ => selected_key = COMMON_KEY,
true => selected_key = DEV_COMMON_KEY,
false => selected_key = COMMON_KEY,
}
}
}
@ -32,22 +32,22 @@ mod tests {
#[test]
fn test_get_common_key() {
assert_eq!(get_common_key(0, None), [0xeb, 0xe4, 0x2a, 0x22, 0x5e, 0x85, 0x93, 0xe4, 0x48, 0xd9, 0xc5, 0x45, 0x73, 0x81, 0xaa, 0xf7]);
assert_eq!(get_common_key(0, false), [0xeb, 0xe4, 0x2a, 0x22, 0x5e, 0x85, 0x93, 0xe4, 0x48, 0xd9, 0xc5, 0x45, 0x73, 0x81, 0xaa, 0xf7]);
}
#[test]
fn test_get_invalid_index() {
assert_eq!(get_common_key(57, None), [0xeb, 0xe4, 0x2a, 0x22, 0x5e, 0x85, 0x93, 0xe4, 0x48, 0xd9, 0xc5, 0x45, 0x73, 0x81, 0xaa, 0xf7]);
assert_eq!(get_common_key(57, false), [0xeb, 0xe4, 0x2a, 0x22, 0x5e, 0x85, 0x93, 0xe4, 0x48, 0xd9, 0xc5, 0x45, 0x73, 0x81, 0xaa, 0xf7]);
}
#[test]
fn test_get_korean_key() {
assert_eq!(get_common_key(1, None), [0x63, 0xb8, 0x2b, 0xb4, 0xf4, 0x61, 0x4e, 0x2e, 0x13, 0xf2, 0xfe, 0xfb, 0xba, 0x4c, 0x9b, 0x7e]);
assert_eq!(get_common_key(1, false), [0x63, 0xb8, 0x2b, 0xb4, 0xf4, 0x61, 0x4e, 0x2e, 0x13, 0xf2, 0xfe, 0xfb, 0xba, 0x4c, 0x9b, 0x7e]);
}
#[test]
fn test_get_vwii_key() {
assert_eq!(get_common_key(2, None), [0x30, 0xbf, 0xc7, 0x6e, 0x7c, 0x19, 0xaf, 0xbb, 0x23, 0x16, 0x33, 0x30, 0xce, 0xd7, 0xc2, 0x8d]);
assert_eq!(get_common_key(2, false), [0x30, 0xbf, 0xc7, 0x6e, 0x7c, 0x19, 0xaf, 0xbb, 0x23, 0x16, 0x33, 0x30, 0xce, 0xd7, 0xc2, 0x8d]);
}
#[test]
fn test_get_dev_key() {
assert_eq!(get_common_key(0, Some(true)), [0xa1, 0x60, 0x4a, 0x6a, 0x71, 0x23, 0xb5, 0x29, 0xae, 0x8b, 0xec, 0x32, 0xc8, 0x16, 0xfc, 0xaa]);
assert_eq!(get_common_key(0, true), [0xa1, 0x60, 0x4a, 0x6a, 0x71, 0x23, 0xb5, 0x29, 0xae, 0x8b, 0xec, 0x32, 0xc8, 0x16, 0xfc, 0xaa]);
}
}

View File

@ -15,7 +15,7 @@ fn title_id_to_iv(title_id: [u8; 8]) -> [u8; 16] {
}
/// Decrypts a Title Key using the specified common key and the corresponding Title ID.
pub fn decrypt_title_key(title_key_enc: [u8; 16], common_key_index: u8, title_id: [u8; 8], is_dev: Option<bool>) -> [u8; 16] {
pub fn decrypt_title_key(title_key_enc: [u8; 16], common_key_index: u8, title_id: [u8; 8], is_dev: bool) -> [u8; 16] {
let iv = title_id_to_iv(title_id);
type Aes128CbcDec = cbc::Decryptor<aes::Aes128>;
let decryptor = Aes128CbcDec::new(&get_common_key(common_key_index, is_dev).into(), &iv.into());
@ -25,7 +25,7 @@ pub fn decrypt_title_key(title_key_enc: [u8; 16], common_key_index: u8, title_id
}
/// Encrypts a Title Key using the specified common key and the corresponding Title ID.
pub fn encrypt_title_key(title_key_dec: [u8; 16], common_key_index: u8, title_id: [u8; 8], is_dev: Option<bool>) -> [u8; 16] {
pub fn encrypt_title_key(title_key_dec: [u8; 16], common_key_index: u8, title_id: [u8; 8], is_dev: bool) -> [u8; 16] {
let iv = title_id_to_iv(title_id);
type Aes128CbcEnc = cbc::Encryptor<aes::Aes128>;
let encryptor = Aes128CbcEnc::new(&get_common_key(common_key_index, is_dev).into(), &iv.into());

View File

@ -185,7 +185,7 @@ impl Ticket {
pub fn dec_title_key(&self) -> [u8; 16] {
// Get the dev status of this Ticket so decrypt_title_key knows the right common key.
let is_dev = self.is_dev();
decrypt_title_key(self.title_key, self.common_key_index, self.title_id, Some(is_dev))
decrypt_title_key(self.title_key, self.common_key_index, self.title_id, is_dev)
}
/// Gets whether a Ticket was signed for development (true) or retail (false).