forked from baltimorehackerspace/keeloq_shield_library
-
Notifications
You must be signed in to change notification settings - Fork 0
/
keeloq.cpp
155 lines (131 loc) · 4.11 KB
/
keeloq.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* KeeloqShield - KeeLoq */
/* */
#include "keeloq.h"
#ifdef DBG
/** Buffer for sprintf calls. */
char buffer7[22];
#endif
union
{
char c[4];
uint32_t num;
} tmpSN;
/**
* Decrypts and interprets received codes
*/
void Remote(void)
{
// a frame was received and is stored in the receive buffer
// move it to decryption Buffer, and restart receiving again
// Copy the received data to the work buffer
memcpy(Buffer, RX_Buffer, sizeof(RX_Buffer));
#ifdef DBG
int i;
Serial.print("DATA ");
for(i = 0; i<sizeof(RX_Buffer); i++)
{
Serial.print(Buffer[i], HEX);
Serial.print(" ");
}
Serial.println("");
#endif
switch (RFtype)
{
case KEELOQ_PACKET: // Standard Keeloq frame detected
NormalKeyGen(); // Compute the decryption key
Decrypt(); // Decrypt the hopping code portion
// Validate received packet (aka, is it a paired device?)
if (Find(RFtype) == FALSE)
{ // Transmitter is not paired. Are we in learn mode?
if (FLearn)
{ // look for new space to store record
if (!Insert())
{ // fail if no memory available
#ifdef DBG
Serial.println("INSERT CODE FAIL");
#endif
break;
}
else
{
#ifdef DBG
Serial.println("Paired");
#endif
if(keeloq_callback)
{
tmpSN.c[0] = SEED[0];
tmpSN.c[1] = SEED[1];
tmpSN.c[2] = SEED[2];
tmpSN.c[3] = Buffer[3] & 0xF;
keeloq_callback(KMSG_NEWPAIR, tmpSN.num, 0);
}
// ASSERT Ind is pointing to a valid memory location
IDWrite(); // write Serial Number in memory
FHopOK = TRUE; // enable updating Hopping Code
HopUpdate(); // Write Hoping code in memory
CFlash = 10; // request Led flashing to indicate successful learning
CTFlash = TFLASH; // load period timer
// LED1 = TRUE; // start with Led on
FLearn = FALSE; // terminate successfully Learn
CTLearn = 0;
}
}
else // not in learning mode
{
#ifdef DBG
Serial.println("Not learned");
#endif
}
}
else if (DecCHK() == FALSE)
{ //Transmitter is paired, but message is not valid
#ifdef DBG
Serial.println("Not valid KLQ");
#endif
}
else
{ // Transmitter is already paired
// Check Hopping Code integrity; are we within the acceptable window?
if (!HopCHK())
{
#ifdef DBG
Serial.println("Hop check fail");
#endif
break;
}
// Visual status confirmation of success
digitalWrite(PIN_LED_RED, LOW);
COut = TOUT; // Init LED output timer
/// Callback
// hopping code incrementing properly
HopUpdate(); // update memory
if(keeloq_callback)
{
tmpSN.c[0] = SEED[0];
tmpSN.c[1] = SEED[1];
tmpSN.c[2] = SEED[2];
tmpSN.c[3] = Buffer[3] & 0xF;
keeloq_callback(KMSG_BTN, tmpSN.num, Buffer[3] >> 4);
}
#ifdef DBG
if (((Buffer[7] ^ FCode) & 0xf0) == 0) // check against learned function code
{
Serial.println("check against");
}
// tone(38, 3000, 400);
sprintf(buffer7, "KLQ: %01X%02X%02X%02X", SEED[3], SEED[2], SEED[1], SEED[0]);
Serial.println((char*)buffer7);
sprintf(buffer7, "C:%01X%02X%02X%02X F:%1X", Buffer[3] & 0xF, Buffer[2], Buffer[1], Buffer[0], Buffer[3] >> 4);
Serial.println((char*)buffer7);
#endif
}
break;
default:
#ifdef DBG
Serial.println("AES/XTEA not supported");
#endif
break;
}
// Ready to receive a new frame
RFFull = FALSE;
} // remote