]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdlfjablotron.c
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
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
) {
145 getSamples("10000", true);
146 return CmdJablotronDemod(Cmd
);
149 int CmdJablotronClone(const char *Cmd
) {
151 uint64_t fullcode
= 0;
152 uint32_t blocks
[3] = {T55x7_MODULATION_DIPHASE
| T55x7_BITRATE_RF_64
| 2 << T55x7_MAXBLOCK_SHIFT
, 0, 0};
156 memset(bs
, 0, sizeof(bits
));
158 char cmdp
= param_getchar(Cmd
, 0);
159 if (strlen(Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H') return usage_lf_jablotron_clone();
161 fullcode
= param_get64ex(Cmd
, 0, 0, 16);
164 if (param_getchar(Cmd
, 1) == 'Q' || param_getchar(Cmd
, 1) == 'q') {
165 //t5555 (Q5) BITRATE = (RF-2)/2 (iceman)
166 blocks
[0] = T5555_MODULATION_BIPHASE
| T5555_INVERT_OUTPUT
| ((64-2)>>1) << T5555_BITRATE_SHIFT
| 2 << T5555_MAXBLOCK_SHIFT
;
169 // clearing the topbit needed for the preambl detection.
170 if ((fullcode
& 0x7FFFFFFFFF) != fullcode
) {
171 fullcode
&= 0x7FFFFFFFFF;
172 PrintAndLog("Card Number Truncated to 39bits: %"PRIx64
, fullcode
);
175 if ( !getJablotronBits(fullcode
, bs
)) {
176 PrintAndLog("Error with tag bitstream generation.");
180 blocks
[1] = bytebits_to_byte(bs
,32);
181 blocks
[2] = bytebits_to_byte(bs
+32,32);
183 PrintAndLog("Preparing to clone Jablotron to T55x7 with FullCode: %"PRIx64
, fullcode
);
184 PrintAndLog("Blk | Data ");
185 PrintAndLog("----+------------");
186 PrintAndLog(" 00 | 0x%08x", blocks
[0]);
187 PrintAndLog(" 01 | 0x%08x", blocks
[1]);
188 PrintAndLog(" 02 | 0x%08x", blocks
[2]);
191 UsbCommand c
= {CMD_T55XX_WRITE_BLOCK
, {0,0,0}};
193 for (int i
= 2; i
>= 0; --i
) {
194 c
.arg
[0] = blocks
[i
];
196 clearCommandBuffer();
198 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, T55XX_WRITE_TIMEOUT
)) {
199 PrintAndLog("Error occurred, device did not respond during write operation.");
206 int CmdJablotronSim(const char *Cmd
) {
207 uint64_t fullcode
= 0;
209 char cmdp
= param_getchar(Cmd
, 0);
210 if (strlen(Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H') return usage_lf_jablotron_sim();
212 fullcode
= param_get64ex(Cmd
, 0, 0, 16);
214 // clearing the topbit needed for the preambl detection.
215 if ((fullcode
& 0x7FFFFFFFFF) != fullcode
) {
216 fullcode
&= 0x7FFFFFFFFF;
217 PrintAndLog("Card Number Truncated to 39bits: %"PRIx64
, fullcode
);
220 uint8_t clk
= 64, encoding
= 2, separator
= 0, invert
= 1;
223 arg1
= clk
<< 8 | encoding
;
224 arg2
= invert
<< 8 | separator
;
226 PrintAndLog("Simulating Jablotron - FullCode: %"PRIx64
, fullcode
);
228 UsbCommand c
= {CMD_ASK_SIM_TAG
, {arg1
, arg2
, size
}};
229 getJablotronBits(fullcode
, c
.d
.asBytes
);
230 clearCommandBuffer();
235 static command_t CommandTable
[] = {
236 {"help", CmdHelp
, 1, "This help"},
237 {"demod", CmdJablotronDemod
, 1, "Attempt to read and extract tag data from the GraphBuffer"},
238 {"read", CmdJablotronRead
, 0, "Attempt to read and extract tag data from the antenna"},
239 {"clone", CmdJablotronClone
, 0, "clone jablotron tag"},
240 {"sim", CmdJablotronSim
, 0, "simulate jablotron tag"},
241 {NULL
, NULL
, 0, NULL
}
244 int CmdLFJablotron(const char *Cmd
) {
245 clearCommandBuffer();
246 CmdsParse(CommandTable
, Cmd
);
250 int CmdHelp(const char *Cmd
) {
251 CmdsHelp(CommandTable
);