Skip to content

Commit

Permalink
Merge branch '20240704_xbox360_auth' into xb360_mergin
Browse files Browse the repository at this point in the history
  • Loading branch information
arntsonl authored Sep 23, 2024
2 parents fd18b3c + fdddfc2 commit d7c71b5
Show file tree
Hide file tree
Showing 20 changed files with 836 additions and 144 deletions.
6 changes: 3 additions & 3 deletions headers/drivers/shared/driverhelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

static uint16_t * getStringDescriptor(const char * value, uint8_t index)
{
static uint16_t descriptorStringBuffer[32]; // Max 64 bytes, 31 unicode characters
static uint16_t descriptorStringBuffer[128]; // Max 256 bytes, 127 unicode characters
size_t charCount;
if ( index == 0 ) // language always has a character count of 1
charCount = 1;
else {
charCount = strlen(value);
if (charCount > 31)
charCount = 31;
if (charCount > 127)
charCount = 127;
}
// Fill descriptionStringBuffer[1] .. [32]
for (uint8_t i = 0; i < charCount; i++)
Expand Down
58 changes: 51 additions & 7 deletions headers/drivers/xinput/XInputAuth.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,68 @@
typedef enum {
auth_idle_state = 0,
send_auth_console_to_dongle = 1,
send_auth_dongle_to_console = 2,
wait_auth_console_to_dongle = 3,
wait_auth_dongle_to_console = 4,
send_auth_dongle_to_console = 2
} XInputAuthState;

typedef struct {
XInputAuthState xboneState;
class XInputAuthBuffer {
public:
XInputAuthBuffer() {
data = nullptr;
length = 0;
}
~XInputAuthBuffer(){
if ( data != nullptr ) {
delete [] data;
}
}

void setBuffer(uint8_t * inData, uint16_t inLen) {
data = new uint8_t[inLen];
length = inLen;
memcpy(data, inData, inLen);
}

void reset() {
if ( data != nullptr ) {
delete [] data;
}
data = nullptr;
length = 0;
}

// Console-to-Host e.g. Xbox 360 to MagicBoots
bool authCompleted;
uint8_t * data;
uint16_t length;
};

#define X360_AUTHLEN_CONSOLE_INIT 34
#define X360_AUTHLEN_DONGLE_SERIAL 29
#define X360_AUTHLEN_DONGLE_INIT 46
#define X360_AUTHLEN_CHALLENGE 22

// We need to keep track of:
// Xbox 360 Console Auth Init 34 bytes
// Dongle Serial 29 bytes
// Console-Dongle Back and Forth 46 bytes & 22 bytes
typedef struct {
XInputAuthState xinputState;
uint8_t consoleInitialAuth[X360_AUTHLEN_CONSOLE_INIT]; // Console Init (Keep when Dongle Reboots)
uint8_t dongleSerial[X360_AUTHLEN_DONGLE_SERIAL]; // Dongle Serial
uint8_t passthruBuffer[X360_AUTHLEN_DONGLE_INIT]; // Back-and-Forth Buffer (46 or 22 bytes)
uint8_t passthruBufferLen; // Length of Passthru (do we need this?)
uint8_t passthruBufferID; // ID of vendor request
bool authCompleted = false;
bool hasInitAuth = false;
bool dongle_ready = false;
} XInputAuthData;

class XInputAuth : public GPAuthDriver {
public:
virtual void initialize();
virtual bool available();
void process();
XInputAuthData * getAuthData() { return &xinputAuthData; }
private:
XInputAuthData xinputAuthData;
};

#endif
32 changes: 29 additions & 3 deletions headers/drivers/xinput/XInputAuthUSBListener.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,48 @@
#define _XINPUTAUTHUSBLISTENER_H_

#include "usblistener.h"
#include "XInputAuth.h"
#include "usbhostmanager.h"

#include "drivers/shared/xinput_host.h"
#include "drivers/xinput/XInputDescriptors.h"

typedef enum {
DONGLE_AUTH_IDLE = 0,
DONGLE_AUTH_WAIT_STATE
} DONGLE_AUTH_STATE;

class XInputAuthUSBListener : public USBListener {
public:
virtual void setup();
virtual void mount(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len){}
virtual void xmount(uint8_t dev_addr, uint8_t instance, uint8_t controllerType, uint8_t subtype);
virtual void unmount(uint8_t dev_addr);
virtual void report_received(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len);
virtual void report_sent(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len){}
virtual void report_received(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) {}
virtual void report_sent(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) {}
virtual void set_report_complete(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t report_type, uint16_t len){}
virtual void get_report_complete(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t report_type, uint16_t len){}
void process();
void setAuthData(XInputAuthData *);
private:
bool xinputh_vendor_report(tusb_dir_t dir, uint8_t request, uint16_t value, uint16_t length, uint8_t * recvBuf, uintptr_t user_data);
// Helper functions for Xbox 360 Authentication
bool auth_dongle_get_serial();
bool auth_dongle_init_challenge();
bool auth_dongle_challenge_verify();
bool auth_dongle_data_reply(uint8_t replyLen);
bool auth_dongle_wait_get_state();
bool auth_dongle_keepalive();
void auth_dongle_wait(uint8_t waitID);
uint8_t xinput_dev_addr;
uint8_t xinput_instance;
bool mounted;
bool sending;
XInputAuthData * xinputAuthData;
uint32_t wait_time;
uint8_t wait_count;
uint8_t waitBuffer[64]; // wait buffer
uint8_t waitBufferID;
DONGLE_AUTH_STATE dongleAuthState;
};

#endif // _XINPUTAUTHUSBLISTENER_H_
184 changes: 164 additions & 20 deletions headers/drivers/xinput/XInputDescriptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,22 @@ typedef struct __attribute((packed, aligned(1)))
} XInputReport;

static const uint8_t xinput_string_language[] = { 0x09, 0x04 };
static const uint8_t xinput_string_manfacturer[] = "Microsoft";
static const uint8_t xinput_string_product[] = "XInput STANDARD GAMEPAD";
static const uint8_t xinput_string_version[] = "1.0";
static const uint8_t xinput_string_serial[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
//static const uint8_t xinput_string_manfacturer[] = "Microsoft";
//static const uint8_t xinput_string_product[] = "XInput STANDARD GAMEPAD";
//static const uint8_t xinput_string_version[] = "1.0";
static const uint8_t xinput_string_manfacturer[] = "\xa9Microsoft Corporation";
static const uint8_t xinput_string_product[] = "Controller";
static const uint8_t xinput_string_version[] = "08FEC93"; // serial?
static const uint8_t xinput_string_xsm3[] = "Xbox Security Method 3, Version 1.00, \xa9 2005 Microsoft Corporation. All rights reserved.";

static const uint8_t *xinput_string_descriptors[] __attribute__((unused)) =
{
xinput_string_language,
xinput_string_serial,
xinput_string_manfacturer,
xinput_string_product,
xinput_string_version
xinput_string_version,
xinput_string_xsm3
};

static const uint8_t xinput_device_descriptor[] =
Expand All @@ -77,17 +83,21 @@ static const uint8_t xinput_device_descriptor[] =
0x01, // bNumConfigurations 1
};

// This needs to be:
// 4 interfaces
// remote wakeup enabled
static const uint8_t xinput_configuration_descriptor[] =
{
0x09, // bLength
0x02, // bDescriptorType (Configuration)
0x30, 0x00, // wTotalLength 48
0x01, // bNumInterfaces 1
0x99, 0x00, // wTotalLength 0x99
0x04, // bNumInterfaces 4
0x01, // bConfigurationValue
0x00, // iConfiguration (String Index)
0x80, // bmAttributes
0xA0, // bmAttributes (remote wakeup)
0xFA, // bMaxPower 500mA

// Control Interface (0x5D 0xFF)
0x09, // bLength
0x04, // bDescriptorType (Interface)
0x00, // bInterfaceNumber 0
Expand All @@ -98,30 +108,164 @@ static const uint8_t xinput_configuration_descriptor[] =
0x01, // bInterfaceProtocol
0x00, // iInterface (String Index)

0x10, // bLength
// Gamepad Descriptor
0x11, // bLength
0x21, // bDescriptorType (HID)
0x10, 0x01, // bcdHID 1.10
0x01, // bCountryCode
0x24, // bNumDescriptors
0x81, // bDescriptorType[0] (Unknown 0x81)
0x14, 0x03, // wDescriptorLength[0] 788
0x00, // bDescriptorType[1] (Unknown 0x00)
0x03, 0x13, // wDescriptorLength[1] 4867
0x01, // bDescriptorType[2] (Unknown 0x02)
0x00, 0x03, // wDescriptorLength[2] 768
0x00, // bDescriptorType[3] (Unknown 0x00)
0x00, 0x01, // bcdHID 1.10
0x01, // SUB_TYPE
0x25, // reserved2
0x81, // DEVICE_EPADDR_IN
0x14, // bMaxDataSizeIn
0x00, 0x00, 0x00, 0x00, 0x13, // reserved3
0x02, // DEVICE_EPADDR_OUT is this right?
0x08, // bMaxDataSizeOut
0x00, 0x00, // reserved4

// Report IN Endpoint 1.1
0x07, // bLength
0x05, // bDescriptorType (Endpoint)
0x81, // bEndpointAddress (IN/D2H)
0x03, // bmAttributes (Interrupt)
0x20, 0x00, // wMaxPacketSize 32
0x01, // bInterval 1 (unit depends on device speed)

// Report OUT Endpoint 1.2
0x07, // bLength
0x05, // bDescriptorType (Endpoint)
0x01, // bEndpointAddress (OUT/H2D)
0x02, // bEndpointAddress (OUT/H2D)
0x03, // bmAttributes (Interrupt)
0x20, 0x00, // wMaxPacketSize 32
0x08, // bInterval 8 (unit depends on device speed)

// Interface Audio
0x09, // bLength
0x04, // bDescriptorType (Interface)
0x01, // bInterfaceNumber 1
0x00, // bAlternateSetting
0x04, // bNumEndpoints 4
0xFF, // bInterfaceClass
0x5D, // bInterfaceSubClass
0x03, // bInterfaceProtocol
0x00, // iInterface (String Index)

// Audio Descriptor
0x1B, // bLength
0x21,
0x00,
0x01,
0x01,
0x01,
0x83, // XINPUT_MIC_IN
0x40, // ??
0x01, // ??
0x04, // XINPUT_AUDIO_OUT
0x20, // ??
0x16, // ??
0x85, // XINPUT_UNK_IN
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x16,
0x06, // XINPUT_UNK_OUT
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,

// Report IN Endpoint 2.1
0x07, // bLength
0x05, // bDescriptorType (Endpoint)
0x83, // bEndpointAddress (XINPUT_MIC_IN)
0x03, // bmAttributes (Interrupt)
0x20, 0x00, // wMaxPacketSize 32
0x02, // bInterval 2 (unit depends on device speed)

// Report OUT Endpoint 2.2
0x07, // bLength
0x05, // bDescriptorType (Endpoint)
0x04, // bEndpointAddress (XINPUT_AUDIO_OUT)
0x03, // bmAttributes (Interrupt)
0x20, 0x00, // wMaxPacketSize 32
0x04, // bInterval 4 (unit depends on device speed)

// Report IN Endpoint 2.3
0x07, // bLength
0x05, // bDescriptorType (Endpoint)
0x85, // bEndpointAddress (XINPUT_UNK_IN)
0x03, // bmAttributes (Interrupt)
0x20, 0x00, // wMaxPacketSize 32
0x40, // bInterval 128

// Report OUT Endpoint 2.4
0x07, // bLength
0x05, // bDescriptorType (Endpoint)
0x06, // bEndpointAddress (XINPUT_UNK_OUT)
0x03, // bmAttributes (Interrupt)
0x20, 0x00, // wMaxPacketSize 32
0x10, // bInterval 16

// Interface Plugin Module
0x09, // bLength
0x04, // bDescriptorType (Interface)
0x02, // bInterfaceNumber 2
0x00, // bAlternateSetting
0x01, // bNumEndpoints 1
0xFF, // bInterfaceClass
0x5D, // bInterfaceSubClass
0x02, // bInterfaceProtocol
0x00, // iInterface (String Index)

//PluginModuleDescriptor : {
0x09, // bLength
0x21, // bDescriptorType
0x00, 0x01, // version 1.00
0x01, // ??
0x22, // ??
0x86, // XINPUT_PLUGIN_MODULE_IN,
0x03, // ??
0x00, // ??

// Report IN Endpoint 3.1
0x07, // bLength
0x05, // bDescriptorType (Endpoint)
0x86, // bEndpointAddress (XINPUT_PLUGIN_MODULE_IN)
0x03, // bmAttributes (Interrupt)
0x20, 0x00, // wMaxPacketSize 32
0x10, // bInterval 8 (unit depends on device speed)

// Interface Security
0x09, // bLength
0x04, // bDescriptorType (Interface)
0x03, // bInterfaceNumber 3
0x00, // bAlternateSetting
0x00, // bNumEndpoints 0
0xFF, // bInterfaceClass
0xFD, // bInterfaceSubClass
0x13, // bInterfaceProtocol
0x04, // iInterface (String Index)

// SecurityDescriptor (XSM3)
0x06, // bLength
0x41, // bDescriptType (Xbox 360)
0x00,
0x01,
0x01,
0x03,
};

typedef enum
{
XSM360_AUTH_NONE = 0x00, // None
XSM360_GET_SERIAL = 0x81, // Xbox 360 Get Controller Serial
XSM360_INIT_AUTH = 0x82, // Xbox 360 Initialize Authentication
XSM360_RESPOND_CHALLENGE = 0x83, // Xbox 360 Respond with Challenge
XSM360_AUTH_KEEPALIVE = 0x84, // Xbox 360 Keep Authentication Alive
XSM360_REQUEST_STATE = 0x86, // Xbox 360 Request Authentication State
XSM360_VERIFY_AUTH = 0x87, // Xbox 360 Verify Authentication

} XSM360AuthRequest;
Loading

0 comments on commit d7c71b5

Please sign in to comment.