To create a full duplicate, able to generate valid transmission packets you'll need the following information:
- Serial Number
- Button press mapping
- 32 bit of KeeLoq encrypted data
See attached Figure 1-2, from the datasheet, near "Transmitted information" at the bottom right:
Using those three pieces of information you can theoretically create your own device.
The serial number is a unique identifier of the remote control, and is trivially retrievable by capturing a single transmission packet because it is sent as-is. OP already retrieved it.
The serial is later required because it is part of the encrypted data as well, so the ability to retrieve it without first decrypting a transmission might help us down the line when we'll create the encrypted part.
In order to send a specific key, you'll need to create your own mapping of values to key meaning. This is not as easy as getting a single value of any transmitted message but does not prove any difficulty, just hit every key and capture it's Button Press Information field. OP seems to have managed that as well.
32 bit of KeeLoq encrypted data
This is where shit gets serious, we'll need to know what to encrypt in addition to the key:
- Button status.
- DISC bits.
- OVR bits.
- Sync Counter (16 bit word incremented once for every button press in the controller's life span).
- Encryption Key (called "Crypt Key" to sound leet in the datasheet :D )
See attached Figure 4-2, from the datasheet, right part:
Button status bits
These four bits are the same ones sent unencrypted, so we've already discussed their rather easy retrieval.
The discrimination value aids the post-decryption
check on the decoder end. It may be any value, but in
a typical system it will be programmed as the 10 Least
Significant bits of the serial number. Values other than
this must be separately stored by the receiver when a
transmitter is learned. The discrimination bits are part
of the information that form the encrypted portion of the
transmission (Figure 4-2). After the receiver has
decrypted a transmission, the discrimination bits are
checked against the receiver’s stored value to verify
that the decryption process was valid. If the discrimination
value was programmed as the 10 LSb’s of the
serial number then it may merely be compared to the
respective bits of the received serial number; saving
These bits are used to identify the device, and according to the datasheet are usually the Least Significant Bits of the previously discussed Serial Number.
The overflow bits are used to extend the number of
possible synchronization values. The synchronization
counter is 16 bits in length, yielding 65,536 values
before the cycle repeats. Under typical use of
10 operations a day, this will provide nearly 18 years of
use before a repeated value will be used. Should the
system designer conclude that is not adequate, then
the overflow bits can be utilized to extend the number
of unique values. This can be done by programming
OVR0 and OVR1 to 1s at the time of production. The
encoder will automatically clear OVR0 the first time that
the synchronization value wraps from 0xFFFF to
0x0000 and clear OVR1 the second time the counter
wraps. Once cleared, OVR0 and OVR1 cannot be set
again, thereby creating a permanent record of the
counter overflow. This prevents fast cycling of 64K
counter. If the decoder system is programmed to track
the overflow bits, then the effective number of unique
synchronization values can be extended to 196,608.
Under normal circumstances, these bits will be zero. They're used to increase the overall Sync Counter size by two bits but are unused by default, according to the datasheet.
Out of the datasheet:
This is the 16-bit synchronization value that is used to create the hopping code for transmission. This value will increment after every transmission.
This is a value incremented every time a button is pressed, so once we get it we'll be able to roughly know what is the next expected value (which will depend on the number of button presses since).
Figure 7-3 shows a 3-partition, rotating synchronization
window. The size of each window is optional but the
technique is fundamental. Each time a transmission is
authenticated, the intended function is executed and
the transmission’s synchronization counter value is
stored in EEPROM. From the currently stored counter
value there is an initial "Single Operation" forward window
of 16 codes. If the difference between a received
synchronization counter and the last stored counter is
within 16, the intended function will be executed on the
single button press and the new synchronization
counter will be stored. Storing the new synchronization
counter value effectively rotates the entire synchronization
A "Double Operation" (resynchronization) window further
exists from the Single Operation window up to 32K
codes forward of the currently stored counter value. It
is referred to as "Double Operation" because a transmission
with synchronization counter value in this window
will require an additional, sequential counter
transmission prior to executing the intended function.
Upon receiving the sequential transmission the
decoder executes the intended function and stores the
synchronization counter value. This resynchronization
occurs transparently to the user as it is human nature
to press the button a second time if the first was unsuccessful.
Which means we don't have to hit the exact value, and actually can guess a number the the range of up to 32k values further away, nearly half the size of the value-space.
There are three possible ways to figure it out.
Reading the EEPROM
By reading the EEPROM, which stores the Sync Counter. Since it is not possible to read EEPROM using the HCS301 without first writing it, you cannot normally read it without tinkering with the hardware. If you've managed to do that you can easily duplicate a remote. Good for you!
Decrypting a single transmission
By decrypting a single transmission you can get the currently used Sync Counter, and have a rough estimate going forward. Since the counter is incremented relatively rarely (datasheet estimates 10 times a day), you can easily guess enough values to succeed.
Good old bruteforcing
By bruteforcing the entire value, you're also able to get the correct value. Since the key-space is relatively small 64k values, you could go at it. According to this cryptanalysis and related-works review:
Depending on the transponder, it takes 65 or 98 minutes to gather
2^16 plaintext/ciphertext pairs.
Note they quote is taken a bit out of context here. While the original intent was getting samples of known plaintext/ciphertext for the challenge-response part of the chip, they also provide a rough estimate at the protocol's speed.
And that essentially means a receiver can handle these many messages in under two minutes.
Thankfully, using the 16 values window mentioned above, we can shave off four bits if done properly.
The A Practical Attack on KeeLoq article describes different vulnerabilities of the KeeLoq encryption espclifically as used for vehicle remote controls and immobilizers. This is a good read if you're interested retrieving the key using cryptanalysis, and it demonstrates several potentially feasible methods. It also reviews related works for your convenience.
I'll iterate possible approaches:
Reading the EEPROM (again)
if you've done that, you could just as easily get the key itself together with the Sync Counter.
Cryptographically retrieving the key, as described in detail at the above article and it's references.
Using the "Learning" feature
According the datasheet, the chip has a feature called "Learning" to communicate / share the key which might use the SYNC value OP has mentioned.
There are three types of "Learning":
Simple Learning - this basically means all Encoder (remote controls) and Decoders (cars) by the same manufacturer share the same key, and are associated using the Serial Number. This is useful because it makes bruteforcing slightly more beneficial because a successful retrieval will provide keys for all of that manufacturer's cars. It also makes it easy to parallelize using multiple vehicles.
The receiver uses information transmitted
during normal operation to derive the crypt
key and decrypt the received code word’s
The transmitter is activated through a special
button combination to transmit a stored 60-bit
seed value used to generate the transmitter’s
crypt key. The receiver uses this seed value
to derive the same crypt key and decrypt the
received code word’s encrypted portion.
It is possible to use the "Secure Learning" feature, with the manufacturer key to calculate the key. For that, you'll need to reverse engineer the Key generation algorithm (stored in the receiver/car) and fetch the manufacturer key from there.
Normal Learning and Secure Learning are only mentioned, but aren't described in the datasheet in depth which makes it harder to bypass those without manual analysis.
Although the implementation/design details of "Secure Learning" are not described in the datasheet, a patent filing titled "Secure self learning system" (USA Patent US 5686904 A) is mentioned on page 29.
The patent includes the following relevant yet vague paragraph:
The key generation algorithm that is used in key generation unit 42 during the secure learning operation is usually a non-linear algorithm. This algorithm accepts as input the manufacturer’s master key 40 (not known) and key generation information. The key generation information can consist of the encoder serial number 24 or the seed 20 or both.
This information is transferred from the encoder in a learning operation to the decoder.
The decoder 12 uses the key generation algorithm to
generate a key 44 that is used to decode a normal code
hopping transmission. The security of this mechanism pertains to the fact that the relationship between the transmitted
seed and the decoding key is not lmown, rendering any kind
of interception of the transmission useless. The non-linear
key generation function also makes it impossible to establish
any relationship between the key and the key generation
information, making it impossible for a possible imposter to
copy an illegitimate encoder. The key 22, serial number 24
and randomly generated seed 20 of an encoder 10 are loaded
during the manufacturing process. The manufacturer generates the key using the seed, serial number, manufacturers
master key and key generation algorithm. The key genera
tion algorithm is not made known publicly. Because the seed
is a random number, the possibility of manufacturing two
encoders with the same keys are very slim. Considering the
fact that the serial number is also used in this process, it is