]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdlfjablotron.c
a2984ac89948f2dad1cdf38b708d71b0a47a4e1b
1 //-----------------------------------------------------------------------------
3 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
4 // at your option, any later version. See the LICENSE.txt file for the text of
6 //-----------------------------------------------------------------------------
7 // Low frequency jablotron tag commands
8 // Differential Biphase, RF/64, 64 bits long (complete)
9 //-----------------------------------------------------------------------------
11 #include "cmdlfjablotron.h"
15 #include "proxmark3.h"
19 #include "cmdparser.h"
23 #include "protocols.h" // for T55xx config register definitions
24 #include "lfdemod.h" // parityTest
26 static int CmdHelp(const char *Cmd
);
28 int usage_lf_jablotron_clone(void) {
29 PrintAndLog("clone a Jablotron tag to a T55x7 tag.");
30 PrintAndLog("Usage: lf jablotron clone [h] <card ID> <Q5>");
31 PrintAndLog("Options:");
32 PrintAndLog(" h : This help");
33 PrintAndLog(" <card ID> : jablotron card ID");
34 PrintAndLog(" <Q5> : specify write to Q5 (t5555 instead of t55x7)");
36 PrintAndLog("Sample: lf jablotron clone 112233");
40 int usage_lf_jablotron_sim(void) {
41 PrintAndLog("Enables simulation of jablotron card with specified card number.");
42 PrintAndLog("Simulation runs until the button is pressed or another USB command is issued.");
44 PrintAndLog("Usage: lf jablotron sim [h] <card ID>");
45 PrintAndLog("Options:");
46 PrintAndLog(" h : This help");
47 PrintAndLog(" <card ID> : jablotron card ID");
49 PrintAndLog("Sample: lf jablotron sim 112233");
53 static uint8_t jablontron_chksum(uint8_t *bits
) {
55 for (int i
=16; i
< 56; i
+= 8) {
56 chksum
+= bytebits_to_byte(bits
+i
,8);
62 int getJablotronBits(uint64_t fullcode
, uint8_t *bits
) {
64 num_to_bytebits(0xFFFF, 16, bits
);
67 num_to_bytebits(fullcode
, 40, bits
+16);
70 uint8_t chksum
= jablontron_chksum(bits
);
71 num_to_bytebits(chksum
, 8, bits
+56);
75 // ASK/Diphase fc/64 (inverted Biphase)
76 // Note: this is not a demod, this is only a detection
77 // the parameter *bits needs to be demoded before call
78 // 0xFFFF preamble, 64bits
79 int JablotronDetect(uint8_t *bits
, size_t *size
) {
80 if (*size
< 64*2) return -1; //make sure buffer has enough data
82 uint8_t preamble
[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0};
83 if (preambleSearch(bits
, preamble
, sizeof(preamble
), size
, &startIdx
) == 0)
84 return -2; //preamble not found
85 if (*size
!= 64) return -3; // wrong demoded size
87 uint8_t checkchksum
= jablontron_chksum(bits
+startIdx
);
88 uint8_t crc
= bytebits_to_byte(bits
+startIdx
+56, 8);
89 if ( checkchksum
!= crc
) return -5;
93 //see ASKDemod for what args are accepted
94 int CmdJablotronDemod(const char *Cmd
) {
96 //Differential Biphase / di-phase (inverted biphase)
97 //get binary from ask wave
98 if (!ASKbiphaseDemod("0 64 1 0", false)) {
99 if (g_debugMode
) PrintAndLog("DEBUG: Error - Jablotron ASKbiphaseDemod failed");
102 size_t size
= DemodBufferLen
;
103 int ans
= JablotronDetect(DemodBuffer
, &size
);
107 PrintAndLog("DEBUG: Error - Jablotron too few bits found");
109 PrintAndLog("DEBUG: Error - Jablotron preamble not found");
111 PrintAndLog("DEBUG: Error - Jablotron size not correct: %d", size
);
113 PrintAndLog("DEBUG: Error - Jablotron checksum failed");
115 PrintAndLog("DEBUG: Error - Jablotron ans: %d", ans
);
120 setDemodBuf(DemodBuffer
+ans
, 64, 0);
124 uint32_t raw1
= bytebits_to_byte(DemodBuffer
, 32);
125 uint32_t raw2
= bytebits_to_byte(DemodBuffer
+32, 32);
127 uint64_t id
= (( (uint64_t)bytebits_to_byte(DemodBuffer
+16, 8) )<< 32) | bytebits_to_byte(DemodBuffer
+24,32);
129 PrintAndLog("Jablotron Tag Found: Card ID: %"PRIx64
" :: Raw: %08X%08X", id
, raw1
, raw2
);
131 uint8_t chksum
= raw2
& 0xFF;
132 PrintAndLog("Checksum: %02X [OK]", chksum
);
134 // Printed format: 1410-nn-nnnn-nnnn
135 PrintAndLog("Printed: 1410-%02X-%04X-%04X",
136 (uint8_t)(id
>> 32) & 0xFF,
137 (uint16_t)(id
>> 16) & 0xFFFF,
138 (uint16_t)id
& 0xFFFF
143 int CmdJablotronRead(const char *Cmd
) {
144 lf_read(true, 10000);
145 return CmdJablotronDemod(Cmd
);
148 int CmdJablotronClone(const char *Cmd
) {
150 uint64_t fullcode
= 0;
151 uint32_t blocks
[3] = {T55x7_MODULATION_DIPHASE
| T55x7_BITRATE_RF_64
| 2 << T55x7_MAXBLOCK_SHIFT
, 0, 0};
155 memset(bs
, 0, sizeof(bits
));
157 char cmdp
= param_getchar(Cmd
, 0);
158 if (strlen(Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H') return usage_lf_jablotron_clone();
160 fullcode
= param_get64ex(Cmd
, 0, 0, 16);
163 if (param_getchar(Cmd
, 1) == 'Q' || param_getchar(Cmd
, 1) == 'q') {
164 //t5555 (Q5) BITRATE = (RF-2)/2 (iceman)
165 blocks
[0] = T5555_MODULATION_BIPHASE
| T5555_INVERT_OUTPUT
| ((64-2)>>1) << T5555_BITRATE_SHIFT
| 2 << T5555_MAXBLOCK_SHIFT
;
168 // clearing the topbit needed for the preambl detection.
169 if ((fullcode
& 0x7FFFFFFFFF) != fullcode
) {
170 fullcode
&= 0x7FFFFFFFFF;
171 PrintAndLog("Card Number Truncated to 39bits: %"PRIx64
, fullcode
);
174 if ( !getJablotronBits(fullcode
, bs
)) {
175 PrintAndLog("Error with tag bitstream generation.");
179 blocks
[1] = bytebits_to_byte(bs
,32);
180 blocks
[2] = bytebits_to_byte(bs
+32,32);
182 PrintAndLog("Preparing to clone Jablotron to T55x7 with FullCode: %"PRIx64
, fullcode
);
183 PrintAndLog("Blk | Data ");
184 PrintAndLog("----+------------");
185 PrintAndLog(" 00 | 0x%08x", blocks
[0]);
186 PrintAndLog(" 01 | 0x%08x", blocks
[1]);
187 PrintAndLog(" 02 | 0x%08x", blocks
[2]);
190 UsbCommand c
= {CMD_T55XX_WRITE_BLOCK
, {0,0,0}};
192 for (int i
= 2; i
>= 0; --i
) {
193 c
.arg
[0] = blocks
[i
];
195 clearCommandBuffer();
197 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, T55XX_WRITE_TIMEOUT
)) {
198 PrintAndLog("Error occurred, device did not respond during write operation.");
205 int CmdJablotronSim(const char *Cmd
) {
206 uint64_t fullcode
= 0;
208 char cmdp
= param_getchar(Cmd
, 0);
209 if (strlen(Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H') return usage_lf_jablotron_sim();
211 fullcode
= param_get64ex(Cmd
, 0, 0, 16);
213 // clearing the topbit needed for the preambl detection.
214 if ((fullcode
& 0x7FFFFFFFFF) != fullcode
) {
215 fullcode
&= 0x7FFFFFFFFF;
216 PrintAndLog("Card Number Truncated to 39bits: %"PRIx64
, fullcode
);
219 uint8_t clk
= 64, encoding
= 2, separator
= 0, invert
= 1;
222 arg1
= clk
<< 8 | encoding
;
223 arg2
= invert
<< 8 | separator
;
225 PrintAndLog("Simulating Jablotron - FullCode: %"PRIx64
, fullcode
);
227 UsbCommand c
= {CMD_ASK_SIM_TAG
, {arg1
, arg2
, size
}};
228 getJablotronBits(fullcode
, c
.d
.asBytes
);
229 clearCommandBuffer();
234 static command_t CommandTable
[] = {
235 {"help", CmdHelp
, 1, "This help"},
236 {"demod", CmdJablotronDemod
, 1, "Attempt to read and extract tag data from the GraphBuffer"},
237 {"read", CmdJablotronRead
, 0, "Attempt to read and extract tag data from the antenna"},
238 {"clone", CmdJablotronClone
, 0, "clone jablotron tag"},
239 {"sim", CmdJablotronSim
, 0, "simulate jablotron tag"},
240 {NULL
, NULL
, 0, NULL
}
243 int CmdLFJablotron(const char *Cmd
) {
244 clearCommandBuffer();
245 CmdsParse(CommandTable
, Cmd
);
249 int CmdHelp(const char *Cmd
) {
250 CmdsHelp(CommandTable
);