Introduction️

KeeLoq is a security protocol based on a symmetric key cryptographic algorithm that is mainly used in remote control systems, such as garage door remotes and remote access systems for cars. It was developed by Microchip Technology and is widely used due to its low cost and relatively simple implementation.️

KeeLoq implements a “rolling code” system to prevent replay attacks. This means that every time the remote control button is pressed, a unique code is generated that never repeats. The receiver (such as a garage door opener) recognizes this code and validates it against an expected sequence, ignoring any duplicate codes.️

This key is shared between the sender and receiver, a 64-bit secret key that is used to encrypt and decrypt messages exchanged. The algorithm uses simple operations such as XOR, shifts, and rotations for its operation.️

Initially, the transmitter and receiver are paired sharing the same secret key and an initial counter. When the user presses a button, the transmitter generates an encrypted code based on the manufacturer’s secret key and the counter, and this code is transmitted to the receiver. The receiver decrypts the message using the shared key and compares the received counter with its own record. If the code is valid and the counter is within a permitted range (to tolerate accidental presses outside the reach), the door opens. After a successful operation, both the transmitter and receiver update their counters to avoid reusing codes.️

The case mentioned in which a single manufacturer key is used is known as Simple Learning and will be treated in this article. There is also the Normal Learning method, where the encryption key is generated from the manufacturer’s key and the serial number of the transmitter. Finally, the most secure method is Secure Learn, in which the encryption key is derived from a seed, present in the transmitter that must be registered on the receiver.️

The frequency commonly used by KeeLoq remotes is 433.920 MHz, the ISM band, with AM OOK modulation. We can capture the signal using a software-defined radio like RTL-SDR or the Flipper Zero. After that we will decode the signal using the tool Universal Radio Hacker. Finally, we will decipher the encrypted part of the signal with the manufacturer’s key to get the remote control counter. As a reference, we will use the datasheet of the HCS301 encoder chip.️

Signal capture️

Method 1️: RTL-SDR

With the USB device connected, we will use the tool to capture and analyze the signal. To do this, we will access the menu File > Record Signal.... We select the device RTL-SDR, its identifier, the frequency 433.92M, the bandwidth 250.0K and the corresponding gain and frequency correction. We capture the signal by pressing the Start button.️ We observed several captured signal. We saved the capture file with the Save... button and the plot will be loaded automatically into the program when closing the window.️ Now we must adjust the captured signal as it may contain noise. The value of the noise Noise is usually automatically filled in by the program. In this case, there is no noise so it remains at 0. We expand the image adjusting it to one of the grids and expand the scale using the menu Y-Scale.️ Change the value of the threshold Center to 0.0000. Next, change the view Signal view from Analog to Demodulated and adjust the value Y-Scale again.️ In this view we observe that the signal is considered as a 1 if the signal is in high state (HIGH) and a 0 in low state (LOW). The decoder will show a 0 for all signals below the green section and a 1 in the purple section. We can adjust the value of Noise to be able to distinguish between the two signals. In this case, the value of Noise is adjusted to 0,0000.️ Now we filter one of the plots and crop it using right-click and Crop to Selection.️ Now we need to find the value Te, which is the value of the signal with the shortest duration. We select it and observe its value.️ We see that the signal with the shortest duration contains 100 samples (samples) with a duration of 400 microseconds. We can find the speed at which data is sent by dividing the value of 1 second by the Te, resulting in a value of 2500 bps (baud per second). In table 3.3 of the data sheet, we observe that 400 microseconds is the default transmission rate.️ We can use the value of 100 samples in the Samples/Symbol field of the program. Let’s activate an error tolerance of 5% in the Error tolerance field to 5. We keep the modulation Modulation at ASK and bits per symbol Bits/Symbol at 1.️ We observe the decoded values:️

10101010101010101010101

1001001101001001101001001001101101001001101001001101101101001101101101001001101101001101001101101001101101001101101101101001001101101101101101101101101101101101101101101101101101101101001101101001

Method 2️: Flipper Zero

In the device Flipper Zero we use the application Sub-GHZ in the menu option Read.️ In the application, we access the configuration by clicking on the left button and adjust the frequency values of 433.92 and modulation AM with a bandwidth of 270 KHz AM270.️ We return to the application with the back button and capture the signal from the remote control.️ We obtain the signal from the KeeLoq remote control KL of the manufacturer GarajeA and the demodulated message DB9B119490....️

Signal Format

In the data sheet, in section 4.1 and 4.2 next to figures 4.1 and 4.2 it is detailed the signal format. The KeeLoq code word is composed of several parts. First we observe that two Te in high state and one in low state (110) corresponds with bit 0 at the time of decoding. A Te in high state and two in low state (100) corresponds with bit 1.️ Each code word contains a preamble with a 50% duty cycle, a header, 32 encrypted data bits and 34 fixed data bits followed by a guard period before another code word can start (66 bits in total). The 32 data bits are encrypted from 4 button bits, 12 discriminator bits, which is a value used to check if the decryption was correct and contains the 10 least significant bits of the serial number, and the synchronization value (counter) of 16 bits, which is updated every time a button is pressed.️ The 34 bits of the fixed data are composed of 2 bits of states (whether the sent message is repeated and whether the received voltage is low), 4 bits of button (S0, S1, S0, S3 connected each to an input of the chip) and the serial number of 28 bits. In the case that the transmitter uses Secure Learn by pressing all the buttons on the remote, the seed will be sent, which is not the case. Returning to Universal Radio Hacker we can observe the similarity of the signal.️ The code word shown in the diagram goes from MSb (most significant bit) to LSb (least significant bit), so we will have to invert the demodulated bits, obtaining first the encrypted portion and then the fixed portion.️

Decoding of the signal️

Flipper Zero

Returning to the Flipper Zero, we can observe the decoded values and the encrypted section decrypted already if we have the manufacturer’s key, decryption is done automatically.️ The values obtained are:️

  • Key:DB9B119490C00004: bits in hexadecimal demodulated without decoding
  • Fix:0x20000309: bits of the fixed portion inverted from 0x90C00004
  • Cnt:0401: bits obtained from the encrypted portion corresponding to the counter (synchronization value) with the hexadecimal value 401, or 1025 in decimal️
  • Hop:0x2988D0DB: bits of the encrypted portion inverted from 0xDB9B1194, without decrypting️
  • Btn:2: bits with the button pressed on the remote control (2)️
  • MF:GarajeA: manufacturer with which the encrypted portion of the message has been deciphered, in this case with the manufacturer key of GarajeA

The manufacturer key used is AABBCCDDEEFFAABB, 64 bits. It is stored in the file keeLoq_mfcodes_user in the directory /ext/subghz/assets, with the following format. The keys are stored in the format key:encryption_type:manufacturer_name. Being encryption_type, 1 for Simple Learning, 2 for Normal Learning and 3 for Secure Learn.️

Filetype: Flipper SubGhz Keystore File
Version: 0
Encryption: 0
AABBCCDDEEFFAABB:1:GarajeA

Universal Radio Hacker

Returning to Universal Radio Hacker, with the demodulated signal in bits we can move to the tab Analysis.️ We observe two messages in the rows, the preamble and the message that follows. In Encoding, it is shown that the message is being decoded using the method Non Return To Zero (NRZ) where high state is interpreted as a 1 and low state as a 0. As we saw earlier, we have to transform the portions 110 to 0 and 100 to 1. We will press on the options of Decoding and on the option ....️

With this, a window called Decoding opens. Keeping in the option Non Return To Zero (NRZ) we drag the function Substitution from Base Functions to Your Decoding. We configure 2 columns (Rows) and introduce the options 110->0 and 100->1 into the table. Finally, we save the decoder with the name KeeLoq by pressing the button Save as....️ We closed the window to return to the “Analysis” window and selected the decoder Decoding: KeeLoq in the message of the second row, obtaining a 66-bit message in columns.️ The binary value obtained is 110110111001101100010001100101001001000011000000000000000000010011, in hexadecimal db9b119490c000043, matching the decoded by Flipper Zero. Configuring the lower section we can get the values of the encrypted portion 2988d9db and the fixed portion 320000309. We observe that in the Flipper Zero, the first digit (3) of the fixed code is being ignored, related to low battery bits and repetition. We decoded the encrypted portion with the Python library leekoq.️

$ python -m virtualenv KeeLoq
$ pip install leekoq
$ python
>>> import leekoq
>>> key = 0xaabbccddeeffaabb
>>> uncipher = leekoq.decrypt(0x2988d9db, key)
>>> print(hex(uncipher))
0x23090401

We obtain the value in hexadecimal 23090401 which in binary are the 32 bits 00100011000010010000010000000001. Its decoding is as follows:️

2           3     0   9    0   4   0   1
_  _  _  _  --  --____---- ____----____----
0  0  1  0  00  1100001001 0000010000000001
S2 S1 S0 S3 OVR DISCRIMINA COUNTER

The indicator of S0 is set to 1, indicating the use of button 2. The value in binary of the counter is 0000010000000001, 401 in hexadecimal and 1025 in decimal. The value of the discriminator is 1100001001, which must match the last 10 bits of the serial number.️

Moving to the fixed portion, its value in binary is the 34 bits 1100100000000000000000001100001001. Its decoding is as follows:️

3           2           0   0   0   0   3   0   9
-      -    -  -  -  -  ____----____----____----____
1      1    0  0  1  0  0000000000000000001100001001
Repeat Vlow S2 S1 S0 S3 SERIALNUMBER

The Repeat indicator is set to 1, indicating that it’s a repeated message. The Vlow indicator is set to 1, indicating the device needs battery replacement. The S0 indicator is set to 1, indicating use of button 2. The binary value of the serial number is 0000000000000000001100001001, 309 in hexadecimal and 777 in decimal. We confirm that the previous discriminator value is correct.️

Conclusión

The KeeLoq protocol structure allows for the generation of 2^32 (4 billion) different encrypted portions with a manufacturer key of 64 bits that enables the existence of 2^64 (18 trillion) different keys. The combination of the fixed and variable parts allows for the existence of 2^66 (76 trillion) different codes. This makes it practically impossible to perform a brute force attack without first obtaining the manufacturer key or through chip cryptanalysis. Using Normal Learning or Secure Learn, the encryption process will be more robust.️

There are investigations such as Algebraic and Slide Attacks on KeeLoq that show attacks against the implementation of the KeeLoq encryption system. This makes it advisable to move to other systems based on AES encryption or asymmetric key systems.