Reversing Somfy RTS

somfy smoove origin RTS

Some time ago we got new motorized blinds at my office which are controlled by a small wireless remote control. This made me curious how these remotes actually work, and if I would be able to control the blinds from a PC.

In this post I’ll explain the process of reverse engineering the protocol. For a detailed explanation of the protocol it self see here.

Capturing the communication

The remotes are of the type Somfy Smoove Origin RTS. Some searching revealed that RTS stands for “Radio Technology Somfy” and is a proprietary system. It uses an OOK(/ASK) modulated signal on 433.42 Mhz.

This was very convenient since I already had a microcontroller with an Aurel RX-4M50RR30SF 433.92 Mhz OOK receiver attached laying around from an other project. Although the frequency’s don’t exactly match, the receiver is able to pick up the signal if the remote is within ~10 meters. The microcontroller, a Cypress EZ-USB FX2, was running a very simple program that samples the data output from the RF receiver every 35 us and forward it to my PC through USB.

With this setup I created traces of different button presses; 4 times ‘up’, 4 times ‘down’ and so on.

Analysing traces

The trace files are just a big bunch of 1’s and 0’s, not very readable. So I searched for a way to plot the traces.

I started of using GnuPlot. Although very cumbersome and time consuming, I was able to get some useful images out of it. Later I converted my trace files to VCD files and used GTKWave. GTKWave isn’t very user friendly either, but it works a lot better then GnuPlot, especially with longer traces.

The image below shows 4 traces of pressing the same button. The frames are clearly visible and it is pretty obvious that there is a preamble at the start of the frame.

GTKWave showing 4 traces of Somfy RTS frames

GTKWave showing 4 traces of Somfy RTS frames

The next image is a close up of the data. One thing I noticed when looking at the differences between traces is that there is always one point where all traces change state, followed by a point where only some or none of the traces changes state. I highlighted this in the image below, red always changes, blue sometimes. This suggests that the actual data bits are encoded in the edge at the point where the signal always changes state. One obvious encoding that springs to mind when seeing this is Manchester encoding.

Somfy RTS traces close up - annotated

Close up of Somfy RTS data. On the red markers the signal level always changes, on the blue only sometimes

Payload Data

Now I knew how the data was modulated, framed and encoded I could actually analyse the frame payload data. As always when reverse engineering I started by making a list of data fields I would expect to be in the protocol and then started comparing the frames from the different traces.

This directly showed that pressing the same button multiple times resulted in different data. Suggesting that the protocol is not static, but uses some kind of rolling code/sequence number. Comparing the traces of two different buttons shows that the upper nibble of the second byte is probably the button code.

Looking at the bytes that change with every button press I noticed that some actually behave as counters that constantly increase by 1, but with some bits flipped. So I assumed that there was some sort of XOR based obfuscation going on. Using these counters I started XOR’ing nibbles together, till the counters increased as expected. This finally brought me at a point where I was able to predict the data multiple frames ahead of the current frame. But it wasn’t perfect.

Patents…

With all the information gathered so far I went back to Google and stumbled upon US Patent 8,189,620 B 2. Skimming through it I found an image of the frame structure I already determined. Hmmm… interesting! Reading further I found that this patent almost completely describes the RTS protocol. With this new information I was able to determine the obfuscation algorithm used.

An other interesting patent I found was US 7860481 B2. But that one doesn’t describe the payload data.

Taking over control!

Now I could decode the protocol I went on to write a program to actually send out my own frames. Given a captured address, rolling code and ‘encryption key’ I was indeed able to control the blinds. Victory!

To transmit I use a Aurel TX-SAW-MID 5v transmitter hand soldered on an experiment board. The antenna attached is a home-brew 1/4 lambda antenna with 4 radials. I was told this antenna design should sort of match the output impedance of the transmitter, although I’ve got no tools to test this.

With this setup I was able to control the blinds at about 5 meter distance, with a wall/coated window in between. This isn’t very impressive, although expectable given that I’m transmitting at 0.5 MHz above the centre frequency of the receiver. And all soldering and wiring is suboptimal. The actual range also depends on the blinds. One of them I wasn’t able to control at all, even when standing next to it.

One problem was that if I controlled the blinds with my program, the rolling code would advance. This caused the original remote to become out of sync. Luckily the blinds allow multiple remotes to be bound to it. This way I could create a virtual remote with my program with its own rolling code.

Security

When I started of I didn’t expect this to be secure in any way. The requirements on security probably aren’t very high for these systems, since some attacker controlling my blinds would just be very annoying. But it is actually better then I anticipated(as in just replaying a frame doesn’t work).

Obviously the ‘encryption’ doesn’t offer any protection. Even if the algorithm would have been strong, only 4 bits of the 8-bit ‘key’ actually change(in a predictable manner…). And the ‘key’ is send with the frame in the clear.

So what about the rolling code? Well it is 16-bit, so there is a chance of 1 out of 65535 that you guess the next value of the code. But if the receiver only accepted the next value of the rolling code as valid and the remote is out of range, one button press would mean that receiver and remote will be out of sync. To prevent this the receiver uses a window in which the rolling code must fall. This size of this window is somewhere in the order of ~100. So this would give a chance of 1 in 655 to guess a working rolling code, or not? Somfy actually did something clever here, because the receiver seems to shrink the window every time it receives an incorrect rolling code! So in worst case you still have to try 65535 codes.

An important thing to note is that the rolling code is sequential and starts at 0. So especially for new systems it is relatively easy to predict/calculate an approximation of the rolling code using the usage frequency + age of the system. Also the address isn’t a random number, but seems to be assigned sequentially. So given the age of the system, or the address of an other remote in the system you might be able to greatly reduce the address space to search.