Closed uzlonewolf closed 1 year ago
Brilliant work @uzlonewolf ! I hope we can eventually find v3.5 devices for testing.
It currently only works with PyCryptodome.
Right now, PyCryptodome is the only library that works/installs cleanly on all platforms (esp. Windows) so I don't think that is terrible. I do think we should update the README to reflect the limitation (pyaes support deprecated).
I do think this gives enough reason to minor-rev the release of TinyTuya to 1.10.0 (which is what we did for 3.4 support).
TuyaMessage was also extended to add .prefix (which is required no matter which way we go) and .iv (not required but I thought it might be useful).
That makes perfect sense. I do think I will add a comment to describe these (keep me honest, iv is the initialization vector, correct?)
The new 6699 format has an additional 16-bit field that I'm not currently packing into TuyaMessage as I have no idea what to call it.
Were you able to tell what it does or why they would include it?
@uzlonewolf - using latest, the scanner is having some problem with broadcast from my old 3.1 devices:
* Unexpected payload from '10.0.1.31' to port 6666: b'\x00\x00U\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x00\x00\x00\x00{"ip":"10.0.1.31","gwId":"03200160ecfabc8d9700","active":2,"ability":0,"mode":0,"encrypt":true,"productKey":"iXfg9AQVUPhlfyGw","version":"3.1"}m|\x1f>\x00\x00\xaaU'
However, force scan works...
Christmas Tree Stand Light Product ID = ? [Force-Scanned]:
Address = 10.0.1.31 Device ID = 03200160ecfabc8d9700 (len:20) Local Key = 78c2e271b3dcfae4 Version = 3.1 Type = default, MAC = ec:fa:bc:8d:97:00
Status: {'1': True, '2': 0, '4': 79, '5': 84, '6': 1194}
scanner is having some problem with broadcast from my old 3.1 devices
Ugh, I forgot to strip the heater/footer for unencrypted packets. I never liked that try/except block anyway, so I rewrote it based on which port the broadcast was received on. https://github.com/uzlonewolf/tinytuya/commit/5e066415e6513239c2ddaa9e6697bd5145af700e I'll make a new PR once I have a few other updates ready.
Awesome! Found fix for other errors. I have an edge case where new devices are added (no key yet) and getting exceptions in scanner. I suspect we can catch this edge case in constructor and use a b'0'*16
key - This seems to fix it. Any obvious side effects or should we treat this edge case upstream?
# Cryptography Helpers
class AESCipher(object):
def __init__(self, key):
self.bs = 16
self.key = key
if self.key == b'': # Missing key use zero
self.key = b'0'*16
I'd rather not deprecate pyaes just because I was too lazy to read the api docs lol. I'll look into it once I'm done with what I'm currently working on.
iv is the initialization vector, correct?
Yep, initialization vector slash nonce (number used once) depending on who you're talking to. It gets regenerated for every message.
Were you able to tell what it does or why they would include it?
No, it's been set to 0 for every packet I've seen. I would have named and included it if I knew what it did :lol:. I was debating tackling it onto the front of the seqnum or something but decided that could be a disaster later.
Any obvious side effects or should we treat this edge case upstream?
Using all 0's will cause the decryption to throw an exception (unless nopad+nodecode is set) so I don't really see a point. Figuring out how it got there in the first place sounds to me like the better option.
Regarding pyaes, I finally looked into it. Unfortunately pyaes does not support GCM mode. I can work around encrypting/decrypting by using CTR mode with the IV set correctly, however there is no way to do the GMAC hashing with it. So it's going to have to remain PyCryptodome only.
No worries... we can add the note about deprecation. To be clear, with users of pyaes still be able to use tinytuya for other non-3.5 devices, or will they get an error (or do we know)?
Yep, pyaes still works fine for <=3.4, it's only 3.5 it won't work for (it will throw a NotImplementedError if someone tries). The message in the thrown error should probably be updated... Perhaps "pyaes does not support GCM, please install PyCryptodome"
I like that. How about this for the README?
Tuya devices use AES encryption which is not available in the Python standard library. PyCryptodome is recommended and installed by default. Other options include PyCrypto and pyaes.
Looks good to me :)
It currently only works with PyCryptodome. We can probably make it work with pyaes as well, I just haven't had time to research it yet.
Due to it encrypting the retcode I ended up moving the encryption/decryption into pack_message()/unpack_message() so it can populate TuyaMessage.retcode. TuyaMessage was also extended to add .prefix (which is required no matter which way we go) and .iv (not required but I thought it might be useful). The new 6699 format has an additional 16-bit field that I'm not currently packing into TuyaMessage as I have no idea what to call it.