-
Notifications
You must be signed in to change notification settings - Fork 205
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
Feature request question: Very energy efficient encrypted custom format? #94
Comments
It's not hard for me to fit any format, but the changed format requires third party application support. Application support for the new format will be very slow. Usually it takes from 3 months if the format is available for several popular sensors. Those. thousands of users are required for popular software to support the new format. |
Thanks for your detailed answer. Wouldn't it be possible just to add a 4th select option beside "Custom", "ATC_1441" and "MiLike" ? I hoped that it is possbile this way. Since new Payloadlength differs from length of previous payloads software should be able to distinguish the new packets and ignore it if they don't have support for that new format. |
From the very beginning, I built a format, different in length, so that third-party programs could be corrected. But this is not happening. Users are encouraged to switch the format to the old one and disable the new one :) Entering an additional format will increase the size of the firmware and will not change anything, except for the questions - why does not it work? :) |
I think most developers just didn't know how to parse it properly. It also makes sends to only activate the format you need because then you have more transmits in the desired format and thus a higher reception chance. And especially when you want to activate the encrypted format, users should explicitly not send also the unencrypted packets ;). But yeah I understand how frustrating this can be when third party software isn't adapted after months. At least the questions "why does ist not work" can be prevented by some kind of checkbox "really enable encrypted format, I know what I am doing" and then "error no encryption password set" if they forget to fill password. Concerning batterysaving I meant using Blowfish to 8 Bytes. I think there is a natively AES support, or at least already built in. One could also use that but then have 16 Bytes Payload instead of small 8 Bytes. |
In the current version of mijia encryption, only 3..4 bytes are encrypted... |
What does that mean exactly? Which reported values are encrypted, which aren't? |
https://github.com/pvvx/ATC_MiThermometer/blob/master/test_adv_key.py
Only "crypt data". Some interfaces do not transmit the MAC address. Therefore, it is inserted into data PDU messages. This makes it impossible to reduce the message length to 8 bytes. |
So Bytes 15 .. 26 are encrypted?
With a new encryption format it should be possible. |
Participation in encryption in this example is taken by: 5 bytes (crypt data) + 4 bytes (mic). |
Payload: Ad len - 1 byte, ad type = 0x16 - 1 byte, UUID16 - 2 bytes, data - 8 bytes: temperature 2, humidity 2, battery level 1, battery voltage 2, counter 1. Total: 1 + 1 + 2 + 8 = 12 bytes Whole package: 16 + 12 = 28 bytes 43/28 = max x 1.53 Advertising interval * 1.5 will come out even less consumption... |
@JsBergbau - Format 11 bytes.
Used by bindkey, AES.MODE_CCM.
Test:
A counter is also needed to track the message. It allows tracking the measurement number and protects against counterfeiting.
AES.MODE_CCM:
|
Hi @pvvx thanks for your work. Is it possible to derive bindkey from a Password via argon2 or pbkdf2? I think this long bind key is very complicated to handle for most users whereas a password like "correct horse battery staple" is much easier to handle. The derivation could be done in the TelinkFlasher HTML page, since there are much more ressources than on the device. The 4 Bytes from 7 to 10 are needed to transmit a kind of initialization vector to have different ciphertext when temperature, humidty and battery stays the same. Did I get this correctly? Regarding counterfeiting messages and counter: So this counter should prevent replaying messages? So when having values 0-255 and value is incremented by one after each measurement interval and the interval is 10 seconds, then after about 40 minutes the same packet could be replayed / injected again as it then seems valid, woulnd't it? In addition this is perhaps even much earlier possible because you should also accept packets with a higher counter because you could have missed some messages. Then this time is even much shorter. Don't think this counter would raise security level a lot or am I getting something wrong? So fake data could be prevented with 3 Bytes IV, leading to more than 5 years until it repeats at 10 seconds measurement interval. To prevent fakes you could use the last 4 bits of temperature and humidity and set a specific pattern. If this pattern is found after decryption packet is original, if not, then data is disregarded as it is forged. Its hard to express in english what I want to say. So if something is unclear, don't hesitate to ask. |
bindkey is any 16 bytes.
No. Nonce - For MODE_CCM, its length must be in the range [7..13]. Bear in mind that with CCM there is a trade-off between nonce length and maximum message size. Recommendation: 11 bytes. |
Argon2 can be configured of how many bytes to return https://en.wikipedia.org/wiki/Argon2 Is in the Telink-Crypto library support for CFB-Mode? Then it would be possible to use 4 Bytes as IV and proceed as described above |
Using other functions will increase the size of the code. If the counter does not change after the calculated time interval, this is the definition of a fake duplicate packet. Xiaomi rolls back the fake after a few hours. The passed counter is 32-bit. Every 512 steps of the counter, the value is stored in Flash. Recovery requires the phone to be connected to the sensor in Mi-Home. When re-registering again (new bindkey), the counter is immediately added to + 512.
cnt, cnt1..3 - 32 bit count I did not include all this in the code so that there was no support for Mi-Home. So far, no one will describe in an open source the entire Xiaomi identification, inserting the full code conflicts with the user agreement in Mi-Home. |
In ver 3.2 new crypto-advertising packages (AES.CCM) are added, according to the previously described format ... Two formats: |
Thanks for implementing. I have some troubles to decrypt: def main():
mac = binascii.unhexlify('bde39238c1a4')
binkey = binascii.unhexlify('4651865E80C7B114CA682FB84F4BB9F0')
print("MAC:", mac.hex(), "Binkey:", binkey.hex())
print()
print("====== Test1 ATC decode ----------------------------------------")
#decrypt_aes_ccm(binkey, mac, adstruct);
received=bytes.fromhex("0e 16 1a 18 7f 26 ec 53 4c 8b 61 8d 05 34 2d")
print("Received:",received)
decrypt_aes_ccm(binkey, mac,received); Error is always
Copied data from Wireshark dump: So whats wrong here? PS: In #94 (comment) Byte 2..3 is stated as "0x181C" but it is advertised and checked in your code sample as "0x181A" |
https://github.com/pvvx/ble_monitor/blob/master/custom_components/ble_monitor/ble_parser/atc.py#L14 |
https://github.com/pvvx/ble_monitor automatically selects the highest data ad option if all ad package options are enabled. |
For now, I decided to leave the old UUID, and use the new one for notification by button and soil moisture. I am experimenting with the option of soldering simple two isolated electrodes in XiaomiLYWSD03MMC connected to the GPIO on which there will be a PWM-> ADC measurement of soil moisture or leakage. I am already rolling back the option with soldering to the reed switch board ... |
Works now, thanks. Is it possible instead of setting a bindkey directly to use a password to derive it via argon2id? This makes it much easier for people to set up encryption. Instead of handling this ugly bind key they can use a Password like "correct horse battery staple". This feature would have to be implemented in the TelinkFlasher Webpage, so there is no additional code or used capacity on the sensor device itself. A live demo is here https://antelle.net/argon2-browser/ I suggest memory size 10240, 64 Iterations, Has length 16 bytes of course and 4 parallelism. With theses settings a Galaxy S10 Lite needs about 3,1 seconds. With this approach even a simple PW is quite secure because only a few passwords can be tested per seconds. |
Perhaps, but it's easier to link to https://antelle.net/argon2-browser/ |
Hi Victor,
thanks for all your work with this sensor.
I know you have enabled to send encrypted packages like the original firmware does. However these packets require 25 Bytes transmitted as advertising data. The format I propose would be 11 Bytes, 1 byte packet length, 2 Bytes service UUID and 8 Bytes payload.
These 8 Byte payloads are 64 Bits which is excactly the blocksize of Blowfish encryption. AES always uses 128 Bit (16 Bytes) blocksize, so the double amount of data needed to be transmitted. You could use AES as a streamcipher, then you also could transmit 8 Bytes, but I don't see any way how to keep track of the nedeeded Inialisation Vector IV without sending more data again. So blowfish would be the ideal encryption alogrithm here. Blocksize of 64 Bits is only a problem because of birthday paradoxon. Since we have here so little data we will never have any trouble with this.
So you can configure a static key, derived by a Password via PBKDF2 (or even argon2 function) to encrypt all your Mi Beacons.
I know this is a heavy feature request and thats why I've called it "feature request question".
I perfectly understand if you say "Sorry thats not worth the effort". I liked that idea very much and so I just wrote this feature request.
When you're interested I have some ideas for the design of the unencrypted dataformat, which I'll write happily down.
The text was updated successfully, but these errors were encountered: