diff --git a/src/kernel/src/regmgr/mod.rs b/src/kernel/src/regmgr/mod.rs index 41b5c7a80..563b356d4 100644 --- a/src/kernel/src/regmgr/mod.rs +++ b/src/kernel/src/regmgr/mod.rs @@ -7,6 +7,7 @@ use crate::ucred::Ucred; use crate::{info, warn}; use std::fmt::{Display, Formatter}; use std::num::NonZeroI32; +use std::ops::Index; use std::ptr::read; use std::sync::Arc; use thiserror::Error; @@ -111,11 +112,15 @@ impl RegMgr { todo!("regmgr_call with multiplier ^ 0x6b > 12"); } - let x = e ^ SBOX1[i] as i32; + let x = e ^ SBOX1[ReverseIndex(i)] as i32; let sbox = if x == 0x19 { &SBOX2 } else { - todo!("regmgr_call with x != 0x19"); + if x != 0x72 { + todo!("regmgr_call with x != 0x19 && x != 0x72: {:#x}", x) + } else { + &SBOX1 + } }; // Construct the key. @@ -135,8 +140,18 @@ impl RegMgr { }; if v3 == 1 { - todo!("decode regmgr_call request with v3 = 1"); - } else if cred.is_nongame() { + if cred.is_nongame() && entry.unk3 & 0x10 == 0 { + return Err(RegError::V800d0216); + } + if entry.unk3 & 1 == 0 { + return Err(RegError::V800d0214); + } + if (!(entry.unk3 >> 12) & web) != 0 { + return Err(RegError::V800d021f); + } + } + + if cred.is_nongame() { todo!("decode regmgr_call request with non-game cred"); } else if (entry.unk3 & 2) == 0 { Err(RegError::V800d0214) @@ -370,6 +385,7 @@ pub enum RegError { V800d0207, V800d0208, V800d0214, + V800d0216, V800d0219, V800d021f, } @@ -383,6 +399,7 @@ impl RegError { Self::V800d0207 => 0x800d0207u32 as i32, Self::V800d0208 => 0x800d0208u32 as i32, Self::V800d0214 => 0x800d0214u32 as i32, + Self::V800d0216 => 0x800d0216u32 as i32, Self::V800d0219 => 0x800d0219u32 as i32, Self::V800d021f => 0x800d021fu32 as i32, } @@ -409,14 +426,25 @@ struct RegUnk6 { unk4: u32, } -const SBOX1: [u8; 13] = [ - 0x8c, 0x4c, 0xa4, 0xff, 0x7b, 0xf5, 0xee, 0x63, 0x5a, 0x23, 0x70, 0x9a, 0x03, +const SBOX1: [u8; 16] = [ + 0x68, 0xe8, 0x98, 0x03, 0x9a, 0x70, 0x23, 0x5a, 0x63, 0xee, 0xf5, 0x7b, 0xff, 0xa4, 0x4c, 0x8c, ]; const SBOX2: [u8; 16] = [ 0x14, 0xee, 0xde, 0xe1, 0x80, 0xac, 0xf3, 0x78, 0x47, 0x43, 0xdb, 0x40, 0x93, 0xdd, 0xb1, 0x34, ]; +pub struct ReverseIndex(pub usize); + +impl Index for [T] { + type Output = T; + + fn index(&self, idx: ReverseIndex) -> &T { + let len = self.len(); + &self[len - 1 - idx.0] + } +} + const UNK_ENTRIES1: [RegUnk6; 3] = [ RegUnk6 { key: RegKey::NET_WIFI_FREQ_BAND,