Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PS5] Eventual DualSense (DS5) emulation #672

Open
dogtopus opened this issue Nov 1, 2020 · 106 comments
Open

[PS5] Eventual DualSense (DS5) emulation #672

dogtopus opened this issue Nov 1, 2020 · 106 comments

Comments

@dogtopus
Copy link

dogtopus commented Nov 1, 2020

Some quick information about it:

  • It's using USB HighSpeed (RIP serialusb) (though I doubt that third party will strictly follow this nor will it be enforced by $**y)
  • The protocol has a distinctive DS4 feeling to it although different.
  • The authentication seems to use the same magic number as DS4 (0xf0-0xf2 but has added bits, namely SET 0xf4 and GET 0xf5). Not sure how much the protocol changes compare to DS4 but my auth script for DS4 didn't work and the "status code" changes based on how many nonce packets I sent to the controller.
    • After some fuzzing with SET 0xf4, GET 0xf5 response changes from initial 0000 to 0111 (after 1 0xf4) then 0103.

The trace on auth

The HID descriptor and lsusb -vd

Real interactions coming soon after I or someone else got the PS5.

@matlo
Copy link
Owner

matlo commented Nov 1, 2020

Could you please share the device and configuration descriptors?

@dogtopus
Copy link
Author

dogtopus commented Nov 1, 2020

Sure. I updated the "HID descriptor" gist to include the lsusb -vd output.

@matlo
Copy link
Owner

matlo commented Nov 1, 2020

Thanks! It has a device qualifier descriptor, which definitely means it is high speed capable. It is still unsure that high speed will be used and enforced all the time. High speed likely consumes more power, which means charging time would be slower if it is enforced. Full speed is enough to carry the communication of a bluetooth device, which I think is still used here. At the moment I see no reason to go high speed.

@matlo
Copy link
Owner

matlo commented Nov 1, 2020

Did you actually try serialusb between the Dualsense and a Windows PC? As serialusb stalls device qualifier descriptor requests, it is actually able to force the communication to go full speed.

@dogtopus
Copy link
Author

dogtopus commented Nov 1, 2020

Did you actually try serialusb between the Dualsense and a Windows PC? As serialusb stalls device qualifier descriptor requests, it is actually able to force the communication to go full speed.

I didn't. However I did try to connect DS5 to PS4 with an OpenVizsla in between and come up with nothing (as in it decodes the high speed traffic but nothing interesting came out).

If it indeed blocks the device qualifier then it should work like you said.

@dogtopus
Copy link
Author

dogtopus commented Nov 2, 2020

There's a weird 64-bit checksum-y field located at the end of each input report and I can't figure out how it's calculated. It doesn't seem to be one of the crc64 that rahash2 supports. Could be a custom poly or some stronger MAC stuff.

@matlo
Copy link
Owner

matlo commented Nov 2, 2020

Do reports with the same content have the same value for this field?

@dogtopus
Copy link
Author

dogtopus commented Nov 2, 2020

@matlo It's practically impossible to get the same report twice since there are timestamps involved.

@matlo
Copy link
Owner

matlo commented Nov 2, 2020

What's the memory size for these timestamps?

@matlo
Copy link
Owner

matlo commented Nov 2, 2020

Just found the answer in your gist.

@dogtopus
Copy link
Author

dogtopus commented Nov 4, 2020

I changed my fuzzing technique to be more aggressive and automated (i.e. throwing random bits and see what turns what on) and made some progress on the output report format.

@dogtopus
Copy link
Author

dogtopus commented Nov 11, 2020

Some update on the bluetooth side of the checksum (last 4 bytes):

The crc32-esque thing is just standard crc32 with custom initial value 0x23fcc4d3 and without flipping all the bits on output (i.e. xor mask is 0)

reveng output:

width=32  poly=0x04c11db7  init=0x23fcc4d3  refin=true  refout=true  xorout=0x00000000  check=0x1141f36b  residue=0x00000000
$ ./reveng -c -i 23fcc4d3 -p 04c11db7 -w 32 -l "$(xxd -r -p | xxd -p | tr -d '\n')"
31 21 7d 80 81 80 00 00 01 08 00 00 00 15 ec 1f
10 f4 ff fb ff 03 00 ec ff 72 1f 4d 05 b5 05 8c
32 0e 82 3a 93 22 80 00 00 00 a0 09 09 00 00 00
00 00 aa 12 8c 32 09 00 00 9c cc 22 e4 28 05 53
46 00 10 00 00 00 00 00 00 00
18c5040c

More info: Ryochan7/DS4Windows#1545 (comment) and below

EDIT: I think it's just regular CRC32 with the Bluetooth HID header included instead of a custom algorithm. Needs further verification on this.

@matlo
Copy link
Owner

matlo commented Nov 11, 2020

Thanks for the tip!

@matlo matlo closed this as completed Nov 11, 2020
@matlo matlo reopened this Nov 11, 2020
@dogtopus
Copy link
Author

Just saw some real protocol captures from others: the auth sequence seems indeed very different compare to DS4 but looks like it should still be passthrough-able. Might need more confirmations.

Now the biggest thing would be figuring out how those 64-bit trailing data were generated.

@InhexSTER
Copy link

Somewhat good news as PS5 supports DS4 I've tried GIMX DS4 BT mode connecting from PC to console over bluetooth works with PS5
I assume wired connection would work too
That means PS4 titles can still be played with keyboard an mouse on PS5

@dogtopus
Copy link
Author

Somewhat good news as PS5 supports DS4 I've tried GIMX DS4 BT mode connecting from PC to console over bluetooth works with PS5
I assume wired connection would work too
That means PS4 titles can still be played with keyboard an mouse on PS5

That was to be expected since licensed PS4 controllers are supported in PS5 compat mode. Thanks for confirming anyway.

@b-desconocido
Copy link

b-desconocido commented Dec 16, 2020

Not sure someone is interested, but there are some info I found:

  1. DualSense works fine in USB FS mode if no data was tampered
  2. Each input report seems to have CRC or signature.
  3. PS5 accepts few tampered HID reports (about 6-8 frames I think), then it enters "I don't give a sh*t" mode untill re-enumeration
    So, the emulation over USB is not possible?

@dogtopus
Copy link
Author

dogtopus commented Dec 16, 2020

Not sure someone is interested, but there are some info I found:

  1. DualSense works fine in USB FS mode if no data was tampered
  2. Each input report seems to have CRC or signature.
  3. PS5 accepts few tampered HID reports (about 6-8 frames I think), then it enters "I don't give a sh*t" mode untill re-enumeration
    So, the emulation over USB is not possible?

Yeah that's what I would expect. Don't have PS5 so I didn't check it myself but I was pretty sure they would check it if they spent time implementing it.

Also Bluetooth packets have this as well. So the best thing to do now IMO is to wait until some 3rd party controller maker forgot to lock their firmware or wait for PS5 firmware decryption (which all could take ages).

@b-desconocido
Copy link

Yeah that's what I would expect. Don't have PS5 so I didn't check it myself but I was pretty sure they would check it if they spent time implementing it.

Also Bluetooth packets have this as well. So the best thing to do now IMO is to wait until some 3rd party controller maker forgot to lock their firmware or wait for PS5 firmware decryption (which all could take ages).

Isn't Bluetooth report use plain CRC as you mentioned and discovered earlier? I'm curious why they did what they did, like implementing something entirely different for USB reports. 64 bit checksum doesn't make much sense for me, there must be a salt (although, there are counters and timestamp already)/seed/public key/IV or whatever else it might be. If this stuff requires obtaining some private "keys" (also signed by the manufacturer) from a gamepad, that will be a disaster :(

I hope it is something simple, cuz this kind of reversing isn't for an average Joe.

@dogtopus
Copy link
Author

dogtopus commented Dec 17, 2020

Isn't Bluetooth report use plain CRC as you mentioned and discovered earlier?

Before the CRC field there's also the 64-bit MAC/checksum stuff.

64 bit checksum doesn't make much sense for me

It could still be something simple if there is performance concern since cryptographically secure stuff usually takes more resources. However if there's a hardware block dedicated to this it might be less of a concern. Still keep in mind that $**y would likely still allow 3rd party controllers and it would add another constraint to how complex this thing could be (unless they went all out and make the ASIC available for 3rd party controller makers for running some sandboxed applets/etc.)

If this stuff requires obtaining some private "keys" (also signed by the manufacturer) from a gamepad, that will be a disaster :(

I thought this possibility as well but IMO it would be unlikely. The MAC/checksum is included way before the auth key exchange and as you pointed out it only takes couple of frames for PS5 to stop responding to the input report. So it is unlikely that the field is linked to the auth identity key. Also 64-bit isn't a lot to work with so I doubt that there would be anything fancier than A traditional MAC.

@b-desconocido
Copy link

he MAC/checksum is included way before the auth key exchange and as you pointed out it only takes couple of frames for PS5 to stop responding to the input report.

I was wrong, console accepts few modified input reports, not frames. I was jerking around debugging my smelly "code", while all host requests being NAK'ed by hardware - console still accepts several input reports, even several seconds apart from each other.
Wondering, what MCU they are using. I'm sure it is some kind of relabeled mainstream MC, gonna take a deep dive into it.

@dogtopus
Copy link
Author

dogtopus commented Dec 18, 2020

he MAC/checksum is included way before the auth key exchange and as you pointed out it only takes couple of frames for PS5 to stop responding to the input report.

I was wrong, console accepts few modified input reports, not frames. I was jerking around debugging my smelly "code", while all host requests being NAK'ed by hardware - console still accepts several input reports, even several seconds apart from each other.
Wondering, what MCU they are using. I'm sure it is some kind of relabeled mainstream MC, gonna take a deep dive into it.

Still doesn't change much even if it was report instead of frames since iirc auth comes seconds later. Receiving reports after "stalling" sounds normal to me since that's what 8 minute timeout would do on PS4.

As for the micro, hopes are not high. Even later revisions of DS4 start to use obscure Mediatek SoCs that I can't find anything online, not even briefs.

@dogtopus
Copy link
Author

dogtopus commented Jan 5, 2021

https://patchwork.kernel.org/project/linux-input/patch/[email protected]/

That's a very nice reserved you got there. Good job $**y :P

@tpunix
Copy link

tpunix commented Mar 22, 2021

The MCU of dualsense:
IMG_20210322_121647

@tpunix
Copy link

tpunix commented Mar 22, 2021

CXD90064GG == MT3616ECT ??

@dogtopus
Copy link
Author

dogtopus commented Mar 22, 2021

CXD90064GG == MT3616ECT ??

Probably just rebranded chip. The PCB looks exactly the same to me so it's pretty likely.

(Not so) big oopsie for $**y but we still

can't find anything online, not even briefs

However slightly related: I heard that B***k is also Taiwan based so they might use some help from their Taiwanese friend 😝 (half joking half serious).

@smartcharge
Copy link

I have made some progress, but not enough to crack the DS5. So here's where I'm at.

I have a STM32F4 that uses 2 USB full speed ports, one for the DS5 and the other for the PS5. I have set the PS5 to use USB, forget the Bluetooth, for now. I can get the DS5 to send data through the STM32F4 to the PS5 and play games. But I can't inject packets into the USB because of the last 64 bits that are encoded/encrypted. Now we all know that the last 64 bits of the message are the mystery that we have to solve. I don't know if its a CRC or some encryption, but I'm going to assume it's a CRC for now, because encryption seems like it would take too long to encode and decode and a 64 bit CRC is very hard to crack, especially when you consider the initial XOR value, the final XOR value and the polynomial. With all this it might as well be encrypted.

I opened up a DS5 controller and started sniffing the traces, I started with the simple ones that look like they might be I2C. Sure enough they were. I captured the I2C data and then something interesting happened, the DS5 no longer sends the 64 bit CRC. The last 64 bits are filled with zeros for every packet sent from the DS5. The DS5 no longer works with the PS5. The USB works fine, the DS5 sends and receives all USB packets. The DS5 sends the joystick data, the Gyro data but not the 64 bit CRC and so the PS5 ignores all commands from the DS5. Another thing I noticed is that one of the timestamps are also zeroed out, specifically bytes 12 to 15. This leads me to believe that the timestamp is used as a seed, or salt or perhaps the initial/final XOR value.

One problem, I monitored 2 different I2C lines at the same time and I don't know which one caused the problem, so I attached the values I received from both lines. In the attached files, the I2C data only occurs during boot up, after that no data was sent. I've looked through the data and couldn't find any correlation between the I2C data and the security authentication data that is sent over USB between the DS5 and the PS5. Maybe someone else will spot something I've missed. One other thing, I'm not a perfect human being so it is possible that I shorted the I2C lies without knowing it, but the rest of the controller works fine, it even works on my Windows 10. Only the 64 bit CRC is not working. I think there may have been a tamper detection at the hardware level that forced the DS5 to zero out the 64 bit CRC.

Here is the I2C data I sniffed from the DS5:

PS5 I2C.zip

@tpunix
Copy link

tpunix commented Mar 24, 2021

A PS5 pad converter is on the store now:
https://detail.tmall.com/item.htm?id=640910895139&ns=1&abbucket=10

@zecoxao
Copy link

zecoxao commented Jun 2, 2023

adaptive trigger works
controller speaker and haptic feedback don't

@Gunflame13
Copy link

Gunflame13 commented Aug 6, 2023

I just want to say thank you very much for your work to everyone involved in this and if I could support even financially I would do it. Hopefully this will lead to being able to decrypt the Dualsense firmware someday and we can make it compatible with OpenStickCommunity's GP2040-CE.

https://github.com/OpenStickCommunity/GP2040-CE

Also, f//k br//k

@LilJess13
Copy link

Hey all,
This seemed like a great place to request some help.
I'm trying to create a joystick calibration software like ds4 tool but for dualsense. I'm having trouble finding the right location for getting and setting the data. Do you guys have any guidance on this. Thanks in advance!

@dogtopus
Copy link
Author

Hey all, This seemed like a great place to request some help. I'm trying to create a joystick calibration software like ds4 tool but for dualsense. I'm having trouble finding the right location for getting and setting the data. Do you guys have any guidance on this. Thanks in advance!

I mean there's 40 bytes long GET 5 usage 33 that's labeled "Get Sensor Calibration" and there's also a 47 bytes long SET 8 usage 34 so... One can only speculate.

@LilJess13
Copy link

If im understanding correctly, sounds like there is no confirmed information on this. Is that right?

@dogtopus
Copy link
Author

dogtopus commented Sep 1, 2023

No it's not confirmed. There are several unknown SET reports that you might be able to poke but I'm not sure what the outcome will be, especially when it involves calibration.

@fraca7
Copy link

fraca7 commented Sep 1, 2023

What do you mean by "calibration"? IMU? The GET 5 returns that indeed (and switches the Dualsense to "full report" mode). As for how to use that, IIRC the structure is the same as the one for the DualShock (which uses GET 2 instead) so you can look at my dsremap project or directly in the Linux kernel (https://github.com/torvalds/linux/blob/master/drivers/hid/hid-sony.c)

@dogtopus
Copy link
Author

dogtopus commented Sep 1, 2023

@fraca7 what @LilJess13 wants is a way to calibrate the joysticks after they got replaced by 3rd party. So it would be something like a SET report and maybe also a GET report that reports back the raw joystick readings, if those reports even exist.

@bytesizelearning
Copy link

bytesizelearning commented Sep 11, 2023

@dogtopus @LilJess13 @fraca7 I'm also interested in figuring out this calibration for the dualsense. Has anyone made any progress on this?

@vgf89
Copy link

vgf89 commented Sep 21, 2023

In case no one else noticed, there was an handshake auth edit to dev wiki on 01:17, 7 November 2022. Is that related?

@michaelbutler
Copy link

It looks like the Beloader team successfully made a PS5 passthru and are now selling it through their Besavior U5 device as shown in this video: https://youtu.be/Kjkklm2zNj0

so it seems like it is possible, but potentially not legal depending on what they are doing (it's a black box)

@marcokps
Copy link

I can also confirm that the Cronus Zen has a (working) PS5 passthrough update available, allowing for almost any device to act like a DS5 controller. So it seems to be possible indeed...

@marcokps
Copy link

marcokps commented Dec 4, 2023

Has anyone made progress with authentication recently?

I noticed in the latest Cronus Zen update that it can now connect an official DS5 controller via Bluetooth. When I had the Cronus Zen device linked to my PS5 through USB, I could use my DS5 controller without needing an extra authentication controller. It appears that the Bluetooth connection contains enough data to generate valid USB protocol checksums, possibly using similar algorithms. This suggests that the Cronus Zen developers have cracked the checksum calculation.

Not entirely sure how useful this information is practically, but it does show the ability of the checksum calculation.

@Invictaz
Copy link

Invictaz commented Dec 4, 2023

@marcokps Isnt it so that the Zen authenticates as a Dualshock 4 which algorithm is known and the Dualsense is only used as input? Even 8bitdo is working with Dualsense as input.

@marcokps
Copy link

marcokps commented Dec 4, 2023

@Invictaz No I am pretty sure the Zen uses the connected Dualsense 5 controller for authentication. I was able to play all my games (also the DS5 dedicated games) with it

@fraca7
Copy link

fraca7 commented Dec 4, 2023

Not entirely sure how useful this information is practically, but it does show the ability of the checksum calculation.

Yeah I've noticed several "remappers" that now support the Dualsense so it looks like both the authentication and the HID input signature have been reverse-engineered. The wiki has two keys but no explanation on how they work exactly: https://www.psdevwiki.com/ps5/Keys#HID_Auth_Keys_(DualSense_HandShake)

@Invictaz
Copy link

Invictaz commented Dec 4, 2023

I guess if you look at other Playstation developments these keys cannot be used in encrypted form.

@Invictaz
Copy link

Invictaz commented Dec 4, 2023

@Invictaz No I am pretty sure the Zen uses the connected Dualsense 5 controller for authentication. I was able to play all my games (also the DS5 dedicated games) with it

The previous workaround was via Remote Play (aka like the way Besavior did). This was stopped. Besavior now has the U5 which does key passthrough.

@zecoxao
Copy link

zecoxao commented Apr 1, 2024

i've documented a bunch of HID commands here:

https://www.psdevwiki.com/ps5/DualSense_HID_Commands

Enjoy!

@Invictaz
Copy link

Invictaz commented Apr 2, 2024

i've documented a bunch of HID commands here:

https://www.psdevwiki.com/ps5/DualSense_HID_Commands

Enjoy!

Great work. What does the NVS unlock do?

@zecoxao
Copy link

zecoxao commented Apr 2, 2024

@Invictaz it unlocks read and write access to the controller's non volatile storage, which is where all the settings are stored, including callibration settings

@vgf89
Copy link

vgf89 commented Apr 4, 2024

@zecoxao Is all of the non-volatile storage read/write accessible? Curious if it'd be possible to manually calibrate the sticks instead of relying on the built-in cal routine

@zecoxao
Copy link

zecoxao commented Apr 4, 2024

@vgf89 it should be possible yes, however i do not know exactly where those settings are located in the nvs

@Invictaz
Copy link

Invictaz commented Apr 5, 2024

@zecoxao Is all of the non-volatile storage read/write accessible? Curious if it'd be possible to manually calibrate the sticks instead of relying on the built-in cal routine

@vgf89

See an example https://the.al/dualshock/ and the code https://github.com/carpikes/ds4-tools/blob/master/ds5-calibration-tool.py

@vgf89
Copy link

vgf89 commented Apr 5, 2024

@zecoxao Is all of the non-volatile storage read/write accessible? Curious if it'd be possible to manually calibrate the sticks instead of relying on the built-in cal routine

@vgf89

See an example https://the.al/dualshock/ and the code https://github.com/carpikes/ds4-tools/blob/master/ds5-calibration-tool.py

You misunderstand. That triggers the built-in calibration routines. The PC does not poll the controller for inputs itself nor generate the calibration values, it's all done on the controller itself. I want to dump the NVS, change values manually (should be easy to find where to change by running the cal routine a few times and doing multiple dumps), and flash it back to the controller, I just don't know the commands to do that.

@Invictaz
Copy link

Invictaz commented Apr 5, 2024

You didn't use the tool. It can read values from the controller but does not display them yet.

@vgf89
Copy link

vgf89 commented Apr 6, 2024

I did use the tool. I can't tell for certain what that first tool does behind the scenes because the source is obfuscated, but it appears like it does the same thing as ds4-tools and provides the same features. ds4-tools doesn't do any sort of manual calibration or reading calibration values, it just triggers a cal routine with one command and ends the cal routine with another. The only time it reads from the controller is to check status before running the calibration, or get basic controller info like hardware IDs.

Here's what happens right now:

  1. Unlock NVS (so that cal persists after reset): hid_set_report(dev, 0x80, struct.pack('BBBBBB', 3, 2, 101, 50, 64, 12))
  2. Start the min/max calibration by sending: hid_set_report(dev, 0x82, struct.pack('BBB', 1, 1, 2))
  3. The controller itself polls the sticks and tracks min/max deflection. The computer does nothing.
  4. Stop the min/max calibration by sending: hid_set_report(dev, 0x82, struct.pack('BBB', 2, 1, 2))
  5. Lock NVS: hid_set_report(dev, 0x80, struct.pack('BB', 3, 1))

What I want is something a little bit different. I want to be able to read/write arbitrary NVS addresses, or maybe dump/flash the entire NVS to/from a file, but I don't know the commands to read/write to NVS addresses and I'm not seeing any obvious examples of that in the aformentioned tools. If I could read/write, we could start searching for where the calibration values are actually stored, write dummy calibration values that give us raw stick output, and write custom calibration routines and make tweaking calibrations easier.

EDIT: I'm seeing examples of some calibration data reads in another repo for DS4, so that's probably a lead: https://github.com/antroids/ds4-gui/blob/main/src/dual_shock_4.rs

@AbkarinoMHM
Copy link

Added more info and HID commands here also:
https://www.psdevwiki.com/ps5/DualSense_HID_Commands

@Glomby
Copy link

Glomby commented Apr 16, 2024

Is it already possible to have an original DS5 connected, pass all its data through and then alter some data? Or is it still not known how to circumvent the ps5 from detecting that the data has been tempered with?

@Invictaz
Copy link

Invictaz commented Apr 16, 2024

Is it already possible to have an original DS5 connected, pass all its data through and then alter some data? Or is it still not known how to circumvent the ps5 from detecting that the data has been tempered with?

We might as well look into the Besavior U5. It isn't banned from what I know and can passthrough the key.

Another option is this, it already seems to work for PS4 controllers to PS5 but not for PS5 controllers

https://github.com/jfedor2/paaas

On hacked PS5 consoles you have a debug option to enable PS4 controllers in native PS5 games.

There are also commands found to do the calibration:
https://blog.the.al/2024/04/02/calibrating-dualsense.html
https://github.com/dualshock-tools/ds4-tools/blob/master/ds5-calibration-tool.py

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests