Io-homecontrol / velux - something's in the bush

Hello everyone.
Thank you for this very instructive thread.
Like many of you I tried to hack io remotes …
I have noticed that the somfy smoove remotes have an ATmega328p on their pcb. Do you think its possible to unsolder the atmega and dump its content an inject it insise another atmega ?To for instance clone the remote.
It’s beyond my knowledge…

Is the reverse engineering still needed when this local api is available? [somfytahoma] Implement new local API · Issue #13013 · openhab/openhab-addons · GitHub

My main driver to reverse engineer the protocol would be to get rid of the cloud dependency. With the above mentioned local api this is possible.
Does anyone know if this is already implemented in any binding?

Hello!

Just so you know. I finally cracked io-homecontrol authentication mechanisms. You will find details here: iown-homecontrol/LinkLayer.md at main · Aldohrs/iown-homecontrol · GitHub

And here is the key that keeps everything together (the key used to encrypt other keys sent on the air):

34c3466ed88f4e8e16aa473949884373

As this key is hardcoded, I have no doubt they can’t change it just like that.

Enjoy replaying/forge your own io-homecontrol frames. I don’t have much details on how to have a complete specification for all devices but I figured out while intercepting frames of my devices that once authentication is sorted out, frame replay should be easy.

5 Likes

Hi Aldohr.

Maybe I can add some more info to io-homecontrol and I need some help to calculate frequency from CC1021 from a old velux KUX100. I use a logic analyzer to sniffing the SPI infomation between mcu and CC1021.

I think there are 6 channels. 3 Rx and 3 Tx channels and each Rx channel is connected to each Tx channel. mcu/cc1021 scan every Rx channel for 2.7 ms if there is data on an Rx channel the mcu/cc1021 changes to predetermined Tx channel.

Frequency register A is use for RX
Frequency register B is use for TX

AA = Configuration Registers addresse
DD = Data
W/R = Write to CC1021 / Read from CC1021

Init CC1021

AA DD W/R
04 3A W Frequency register 2A
08 3A W Frequency register 2B
01 4F W Interface control register
02 FF W Digital module reset register
03 8F W Automatic power-up sequencing control register
07 27 W Clock generation register A
0B 27 W Clock generation register B
0C 44 W VCO current control register
0D 53 W Modem control register = 5: ADC frequency = XOSC frequency / 12 – Transparent asynchronous UART operation, set DCLK=1
0E 3B W TX frequency deviation register
0F C6 W RX AFC control register
10 22 W Channel filter / RSSI control register
11 65 W VGA control register 1
12 57 W VGA control register 2
13 2E W VGA control register 3
14 2E W VGA control register 4
16 76 W Front end bias current control register
17 87 W Analog modules control register
18 50 W LO buffer and prescaler swing control register
19 25 W LO buffer and prescaler bias current control register
1A AE W PLL loop bandwidth / charge pump current control register
1C 00 W Power amplifier output power register
1D F0 W Match capacitor array control register, for RX and TX impedance matching
1E 00 W Phase error compensation control register for LO I/Q
1F 00 W Gain error compensation control register for mixer I/Q
20 00 W Power-down control register

15 23 W Lock control register
00 11 W Main control register
00 01 W Main control register

05 28 W Frequency register 1A
06 A3 W Frequency register 0A
00 11 W Main control register
1B B4 W LO buffer and prescaler swing control register

40 07 R Status information register (PLL lock, RSSI, calibration ready, and so on)
40 07 R Status information register (PLL lock, RSSI, calibration ready, and so on)
40 27 R Status information register (PLL lock, RSSI, calibration ready, and so on)
40 07 R Status information register (PLL lock, RSSI, calibration ready, and so on)
40 07 R Status information register (PLL lock, RSSI, calibration ready, and so on)

CC1021 up and running.

scan every channel for 2.7 ms


CC1021 RX channel 1
AA DD
04 3A = Frequency register 2A
05 1C = Frequency register 1A
06 7D = Frequency register 0A

wait 2.7 ms before changes to new Rx kanal
if data on Rx channel changes Tx channel in CC1021 to

CC1021 TX channel 1
08 3A = Frequency register 2B
09 21 = Frequency register 1B
0A D1 = Frequency register 0B


CC1021 RX channel 2
04 3A = Frequency register 2A
05 28 = Frequency register 1A
06 A3 = Frequency register 0A

wait 2.7 ms before changes to new Rx kanal
if data on Rx channel changes Tx channel in CC1021 to

CC1021 TX channel 2
08 3A = Frequency register 2B
09 2D = Frequency register 1B
0A F9 = Frequency register 0B


CC1021 RX channel 3

04 3A = Frequency register 2A
05 38 = Frequency register 1A
06 43 = Frequency register 0A

wait 2.7 ms before changes to new Rx kanal
if data on Rx channel changes Tx channel in CC1021 to

CC1021 TX channel 3
08 3A = Frequency register 2B
09 3D = Frequency register 1B
0A 99 = Frequency register 0B


start over

Maybe someone can calculator the Rx/Tx frekvens from the hex code in Frequency register A/B from cc1021 datasheet. CC1021 use 14.7456 MHz Crystal oscillator.

Parring KLR200 with KUX100/Pk03

33 F1 20 00 00 3F 43 8D 43 2E 00 00 00 93 D3 22 92 55 74 E4 B4 - KLR 200 > KUX100/PK03
33 F1 00 00 00 3F 43 8D 43 2E 00 00 00 93 D3 22 92 55 74 26 A5 - KLR 200 > KUX100/PK03
33 F1 00 00 00 3F 43 8D 43 2E 00 00 00 93 D3 22 92 55 74 26 A5 - KLR 200 > KUX100/PK03
33 F1 00 00 00 3F 43 8D 43 2E 00 00 00 93 D3 22 92 55 74 26 A5 - KLR 200 > KUX100/PK03

33 C8 10 00 00 3B 43 8D 43 28 96 94 - KLR 200 > KUX100/PK03
33 D1 08 43 8D 43 38 ED A1 29 02 80 B6 2B BB 01 54 00 A2 04 C7 - KUX100/PK03 > KLR 200

33 48 10 38 ED A1 43 8D 43 2C B2 DB - KLR 200 > KUX100/PK03
33 88 08 43 8D 43 38 ED A1 2D 6E 06 - KUX100/PK03 > KLR 200

33 C8 10 00 00 3B 43 8D 43 28 96 94 - KLR 200 > KUX100/PK03
33 C8 10 00 00 3B 43 8D 43 28 96 94 - KLR 200 > KUX100/PK03
33 C8 10 00 00 3B 43 8D 43 28 96 94 - KLR 200 > KUX100/PK03

33 48 10 38 ED A1 43 8D 43 31 D6 10 - KLR 200 > KUX100/PK03
33 0E 08 43 8D 43 38 ED A1 3C 9C 9C CD E3 20 1C 81 B8 - KUX100/PK03 > KLR 200

33 18 10 38 ED A1 43 8D 43 32 29 E6 1E 00 E2 5C 4D A2 68 E7 0E F3 CC 09 E4 85 14 50 - KLR 200 > KUX100/PK03
33 88 08 43 8D 43 38 ED A1 33 91 FF - KUX100/PK03 > KLR 200

33 D4 30 00 00 3B 43 8D 73 95 9D 1D B3 C2 24 3D ED 0E F8 7C 13 A0 72 DB - KLR 200 > KUX100/PK03
33 D4 30 00 00 3B 43 8D 43 2A 2B E7 9C E3 77 E0 34 90 79 0D F2 8C 08 66 - KLR 200 > KUX100/PK03
33 D4 30 00 00 3B 43 8D 43 2A 4A 15 C2 1F 97 33 2F 2F A5 4F 82 19 C7 AC - KLR 200 > KUX100/PK03 OK
33 48 14 38 ED A1 43 8D 43 36 B7 72 - KLR 200 > KUX100/PK03
33 0B 0C 43 8D 43 38 ED A1 37 B6 2B BB AA B9 - KUX100/PK03 > KLR 200

33 0E 10 38 ED A1 43 8D 43 3C 64 45 E0 81 DC 93 31 26 - KLR 200 > KUX100/PK03
33 8E 08 43 8D 43 38 ED A1 3D 78 75 46 F7 84 32 70 FB - KUX100/PK03 > KLR 200

COMMANDO 2E

KLR200 SEND MASSAGE TO KUX100/PK04 BLIND - PREPARE 1 WAY CONTROL
xx
33 49 10 16 EB 1E 79 BA 7D 2E 00 01 BD KLR200 >> KUX100
33 0E 08 79 BA 7D 16 EB 1E 3C 23 19 A7 B0 51 48 22 8E KUX100 >> KLR200
33 0E 10 16 EB 1E 79 BA 7D 3D 53 AB 19 59 40 E7 59 86 KLR200 >> KUX100
33 89 08 79 BA 7D 16 EB 1E 2F 00 A4 3B KUX100 >> KLR200

Hello everyone!

I’m a last year engineering french student and during this year I have to acheive a project that aim at reverse engineering the IO Home Control protocol and stating if using it in other project is a great idea. The final goal would be creating our own custom box that can use this protocol to talk to Somfy devices or to our custom devices.

First thank you for this discussion, with your help i’ve already been able to gather a lot of informations and I’m starting to understand how it does work. But as it is my first time dealing with reverse engineering, I’m having a hard time to planing what to do and in what order to reach succes. For now my plan would be to sniff pairing communication in order to intercept the key exchange mecanism. Once I’m able to decrypt messages, I want to send frames with an sdr to act like a tahoma switch and talk to a somfy device.

For you, is my plan realistic? Any suggestion on how to proceed would be really appreciated. I will update you if I find something interesting.

No,

En français parceque je répond avec mon téléphone en clavier français… Désolé.

C’est comme pour ssl, ssh etc…
De ce que j’ai compris, la clé est en mémoire dans l’ic qui gère le protocole.
En général cpu, donc mort.
Mais certain sont en spi, donc peut être que tu peux la récupérer sur du matériel qui a un ic de ce genre.

English please, this is an international community !

What’s the point of reverse engineering a proprietary protocol that is not disclosed on purpose? Even if you succeed it may not work for very long.
Apart from that you may get into legal issues.
I don’t like proprietary protocols and Somfy’s stuff is amongst the worst but asking a student to hack a protected protocol is bordering on being unethical.
I would probably out of private interest but I definitely would not tie my engineering degree to a project that is bound to fail.

Thank you for your answer. For now, my goal is only to discuss if yes or no it would be worth to use this protocol in our future projects. I don’t really know if I can get into legal issues but as long as this project was pushed by my tutor, I think I may be alright. For now, I’m trying to sniff the pairing process, as the first key shared is the same and hard coded in all devices (34c3466ed88f4e8e16aa473949884373), I should be able to intercept all the communications. I’ll keep you in touch if I discover something interesting.

Can somebody explain if the protocol has been solved yet? Are there already some examples of cloning remotes with raspi/nodemcu + cc1101/CC1120 available or further progress on layer 3 is needed?

The transfert key isnt hardcoded but created with the harcoded system key in the firmware :

import binascii
def AES_CreateTRANSFERTKEY_With_SYSTEMKEY_08025734(ReturnedEncryptedData, KEY):
    EncryptedData = bytearray(KEY) 

    EncryptedData[0] = ((~EncryptedData[0]) & 0xFF) ^ 0x05
    EncryptedData[1] = ((~EncryptedData[1]) & 0xFF) ^ 0x31
    EncryptedData[2] = EncryptedData[2] ^ 0xD
    EncryptedData[3] = EncryptedData[3] ^ 0x41
    EncryptedData[4] = ((~EncryptedData[4]) & 0xFF) ^ 0x7B
    EncryptedData[5] = ((~EncryptedData[5]) & 0xFF) ^ 0x18
    EncryptedData[6] = EncryptedData[6] ^ 0x6A
    EncryptedData[7] = EncryptedData[7] ^ 0x1D
    EncryptedData[8] = EncryptedData[8] ^ 0x3B
    EncryptedData[9] = EncryptedData[9] ^ 0x55
    EncryptedData[10] = ((~EncryptedData[10]) & 0xFF) ^ 0x55
    EncryptedData[11] = EncryptedData[11] ^ 0x47
    EncryptedData[12] = EncryptedData[12] ^ 0x39
    EncryptedData[13] = ((~EncryptedData[13]) & 0xFF) ^ 0x71
    EncryptedData[14] = ((~EncryptedData[14]) & 0xFF) ^ 0x6F
    EncryptedData[15] = EncryptedData[15] ^ 0x4B

    ReturnedEncryptedData[:] = EncryptedData

AES_KEY = bytes.fromhex("CE0D4B2F5C6824932DFFED7E7006D338") #from firmware

ReturnedEncryptedData = bytearray(16)
AES_EncryptFrameData_With_SYSTEM_KEY(ReturnedEncryptedData, AES_KEY)
print(binascii.hexlify(ReturnedEncryptedData))
1 Like

You can rewrite it like this :
From 16EB1E To 79BA7D Cmd 2E Data 00 CRC 01 BD
From 79BA7D To 16EB1E Challenge Asked 3C 23 19 A7 B0 51 48 CRC 22 8E
From 16EB1E To 79BA7D Challenge Answer 3D 53 AB 19 59 40 E7 CRC 59 86
From 79BA7D To 16EB1E Cmd 2F Data 00 CRC A4 3B

1 Like

Hi Pascal_M,
can we contact you by email?