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

Tuya Storage decryption #23

Open
Verequies opened this issue Mar 9, 2024 · 13 comments
Open

Tuya Storage decryption #23

Verequies opened this issue Mar 9, 2024 · 13 comments

Comments

@Verequies
Copy link

Is it possible to decrypt the Tuya Storage partition?
I am certain it contains the device ID and possibly other information as flashing a Tuya storage partition from one device to another changes said device ID.
It would be great to be able to edit and rebuild this partition in order to repair devices.
Attached my flash.bin (added .txt in order to upload)

flash.bin.txt

@Cossid
Copy link

Cossid commented Mar 9, 2024

It is already supported by the UPK2ESPHome plugin for LTChipTool. It is included with the binaries in the release section, or can be installed via pip with pip install upk2esphome

@Verequies
Copy link
Author

Verequies commented Mar 9, 2024

I did try this however it unfortunately did not dump the device ID at all. Device ID looks similar to bf8b7201xxxxxxb69b9ucc.

@Cossid
Copy link

Cossid commented Mar 9, 2024

Look at the source data.

@Cossid
Copy link

Cossid commented Mar 9, 2024

This particular device doesn't have an activated device id in storage (which means it wasn't joined to Smart Life at the time it was dumped).

uuid and authkey are present, which is how it communicated with Tuya's API to generate a device ID.
gw_di.id would have held the device id had it been activated.

@Verequies
Copy link
Author

I see, had no idea that it generated a device ID by talking to the Tuya API. Was not able to find much information on that. Thanks for the information.
Yeah, this was a dump of a downlight before it was setup so it did not contain passwords etc.

Changing the UUID and authkey would therefore generate a different device ID correct?

I will analyse a dump from a configured device.

@Cossid
Copy link

Cossid commented Mar 9, 2024

The UUID and authkey are Tuya secrets per device, they must match, or communication will fail. The schema that is returned with the device id is attached to the uuid and authkey. The device id is generated each activation. The device has no local schema until it has been activated.

@Verequies
Copy link
Author

Okay I do see the ID after analysing a dump from a configured device.

How would one go about generating a matching UUID and authkey then?
I assume there would be a process when initially developing the device.

@Cossid
Copy link

Cossid commented Mar 9, 2024

That is a secret defined by Tuya and attached to their license, it is not something that can just be generated. Every device has a unique UUID/authkey combo. UUID and authkey are only used in communication encryption until a device id is assigned, then it switches to seckey which is attached to the device id.

@Verequies
Copy link
Author

I signed up to the Tuya cloud and generated a couple of free UUID and authkey pairs.
What would be the best way to update the originals with these?

@Cossid
Copy link

Cossid commented Mar 9, 2024

There is no easy existing way to do this. All the tools around just read storage data. You'd need to adapt them for editing, re-encrypted, writing, and crc checks. No 3rd party firmwares use Tuya's native storage for writing.

CloudCutter somewhat does this by exploit and using Tuya's SDK functions to overwrite that data, but it has limitations (cloudcutter is using smaller data fields and is limited in the size of data the exploit can carry as a payload).

@Verequies
Copy link
Author

Verequies commented Mar 11, 2024

I have managed to decrypt and re-encrypt the Tuya storage partition. Doing a byte to byte comparision before and after shows no differences and it works upon flashing.

However upon modification before re-encryption it seems to crash on bootup. Looking through the bootup log shows the following:

[01-01 18:12:18 TUYA Err][lr:0xa803d] kvs_read fails gw_bi -1
[01-01 18:12:18 TUYA Err][lr:0xac82b] base read fail:-6914
[01-01 18:12:18 TUYA Err][lr:0xad16f] ERR_EXIT is Jumped!
[01-01 18:12:18 TUYA Err][lr:0x65ad5] tuya_iot_wf_soc_dev_init err:ffffe4fe
[01-01 18:12:18 TUYA Err][lr:0x65adf] smart fram init error
[01-01 18:12:18 TUYA Err][lr:0x57fb7] ret:-6914

Interestingly kvs_read fails gw_bi -1 shows up several times even when booting a working flash backup.
base read fail:-6914 always shows when modified even if I edit just a single byte before re-encryption. I even recalculate the checksum and update that too.

After a lot of playing around I believe there is something else in that partition that needs updating.
Here's the Tuya partition and decrypted Tuya partition. Read from offset 0x1EE000.
tuya.bin.txt
decrypted_tuya.bin.txt

And heres the Python scripts I've been playing with.
split_tuya_storage.py.txt
update_uuid_authkey.py.txt

Should be able to chuck both in a folder with the above flash.bin and run the split_tuya_storage.py. Then afterwards run update_uuid_authkey.py. That will decrypt, update, encrypt and output several files for comparison.

The update script is largely based on bk7231tools/analysis/storage.py.

@Cossid
Copy link

Cossid commented Mar 11, 2024

In your decrypted_tuya.bin.txt, it appears your gw_bi and user_param_key are colliding.

@Verequies
Copy link
Author

Yeah, I think that's just how it looks when decrypted. Because that is unmodified, and when re-encrypting and flashing it works fine. Its just as soon as you modify it, the firmware spits out that error.

I tried editing another dump and it was the same issue.
Must be some other checksum in the file/partition?

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

2 participants