1 //-----------------------------------------------------------------------------
2 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
3 // at your option, any later version. See the LICENSE.txt file for the text of
5 //-----------------------------------------------------------------------------
6 // HitagS emulation (preliminary test version)
8 // (c) 2016 Oguzhan Cicek, Hendrik Schwartke, Ralf Spenneberg
10 //-----------------------------------------------------------------------------
11 // Some code was copied from Hitag2.c
12 //-----------------------------------------------------------------------------
14 #include "proxmark3.h"
22 #define CRC_PRESET 0xFF
23 #define CRC_POLYNOM 0x1D
28 #define rev8(x) ((((x)>>7)&1)+((((x)>>6)&1)<<1)+((((x)>>5)&1)<<2)+((((x)>>4)&1)<<3)+((((x)>>3)&1)<<4)+((((x)>>2)&1)<<5)+((((x)>>1)&1)<<6)+(((x)&1)<<7))
29 #define rev16(x) (rev8 (x)+(rev8 (x>> 8)<< 8))
30 #define rev32(x) (rev16(x)+(rev16(x>>16)<<16))
31 #define rev64(x) (rev32(x)+(rev32(x>>32)<<32))
32 #define bit(x,n) (((x)>>(n))&1)
33 #define bit32(x,n) ((((x)[(n)>>5])>>((n)))&1)
34 #define inv32(x,i,n) ((x)[(i)>>5]^=((u32)(n))<<((i)&31))
35 #define rotl64(x, n) ((((u64)(x))<<((n)&63))+(((u64)(x))>>((0-(n))&63)))
38 static bool bSuccessful
;
39 static struct hitagS_tag tag
;
40 static byte_t page_to_be_written
= 0;
41 static int block_data_left
= 0;
42 typedef enum modulation
{
48 static MOD m
= AC2K
; //used modulation
49 static uint32_t temp_uid
;
51 static int sof_bits
; //number of start-of-frame bits
52 static byte_t pwdh0
, pwdl0
, pwdl1
; //password bytes
53 static uint32_t rnd
= 0x74124485; //randomnumber
58 // Single bit Hitag2 functions:
59 #define i4(x,a,b,c,d) ((u32)((((x)>>(a))&1)+(((x)>>(b))&1)*2+(((x)>>(c))&1)*4+(((x)>>(d))&1)*8))
60 static const u32 ht2_f4a
= 0x2C79; // 0010 1100 0111 1001
61 static const u32 ht2_f4b
= 0x6671; // 0110 0110 0111 0001
62 static const u32 ht2_f5c
= 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011
63 #define ht2bs_4a(a,b,c,d) (~(((a|b)&c)^(a|d)^b))
64 #define ht2bs_4b(a,b,c,d) (~(((d|c)&(a^b))^(d|a|b)))
65 #define ht2bs_5c(a,b,c,d,e) (~((((((c^e)|d)&a)^b)&(c^b))^(((d^e)|a)&((d^b)|c))))
68 static u32
f20(const u64 x
) {
71 i5
= ((ht2_f4a
>> i4(x
, 1, 2, 4, 5)) & 1) * 1
72 + ((ht2_f4b
>> i4(x
, 7, 11, 13, 14)) & 1) * 2
73 + ((ht2_f4b
>> i4(x
, 16, 20, 22, 25)) & 1) * 4
74 + ((ht2_f4b
>> i4(x
, 27, 28, 30, 32)) & 1) * 8
75 + ((ht2_f4a
>> i4(x
, 33, 42, 43, 45)) & 1) * 16;
77 return (ht2_f5c
>> i5
) & 1;
79 static u64
hitag2_round(u64
*state
) {
83 + ((((x
>> 0) ^ (x
>> 2) ^ (x
>> 3) ^ (x
>> 6) ^ (x
>> 7) ^ (x
>> 8)
84 ^ (x
>> 16) ^ (x
>> 22) ^ (x
>> 23) ^ (x
>> 26) ^ (x
>> 30)
85 ^ (x
>> 41) ^ (x
>> 42) ^ (x
>> 43) ^ (x
>> 46) ^ (x
>> 47))
91 static u64
hitag2_init(const u64 key
, const u32 serial
, const u32 IV
) {
93 u64 x
= ((key
& 0xFFFF) << 32) + serial
;
94 for (i
= 0; i
< 32; i
++) {
96 x
+= (u64
) (f20(x
) ^ (((IV
>> i
) ^ (key
>> (i
+ 16))) & 1)) << 47;
100 static u32
hitag2_byte(u64
*x
) {
103 for (i
= 0, c
= 0; i
< 8; i
++)
104 c
+= (u32
) hitag2_round(x
) << (i
^ 7);
108 // Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK)
109 // TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz
110 // Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
111 // T0 = TIMER_CLOCK1 / 125000 = 192
114 #define SHORT_COIL() LOW(GPIO_SSC_DOUT)
115 #define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
117 #define HITAG_FRAME_LEN 20
118 #define HITAG_T_STOP 36 /* T_EOF should be > 36 */
119 #define HITAG_T_LOW 8 /* T_LOW should be 4..10 */
120 #define HITAG_T_0_MIN 15 /* T[0] should be 18..22 */
121 #define HITAG_T_1_MIN 25 /* T[1] should be 26..30 */
122 //#define HITAG_T_EOF 40 /* T_EOF should be > 36 */
123 #define HITAG_T_EOF 80 /* T_EOF should be > 36 */
124 #define HITAG_T_WAIT_1 200 /* T_wresp should be 199..206 */
125 #define HITAG_T_WAIT_2 90 /* T_wresp should be 199..206 */
126 #define HITAG_T_WAIT_MAX 300 /* bit more than HITAG_T_WAIT_1 + HITAG_T_WAIT_2 */
128 #define HITAG_T_TAG_ONE_HALF_PERIOD 10
129 #define HITAG_T_TAG_TWO_HALF_PERIOD 25
130 #define HITAG_T_TAG_THREE_HALF_PERIOD 41
131 #define HITAG_T_TAG_FOUR_HALF_PERIOD 57
133 #define HITAG_T_TAG_HALF_PERIOD 16
134 #define HITAG_T_TAG_FULL_PERIOD 32
136 #define HITAG_T_TAG_CAPTURE_ONE_HALF 13
137 #define HITAG_T_TAG_CAPTURE_TWO_HALF 25
138 #define HITAG_T_TAG_CAPTURE_THREE_HALF 41
139 #define HITAG_T_TAG_CAPTURE_FOUR_HALF 57
144 * Implementation of the crc8 calculation from Hitag S
145 * from http://www.proxmark.org/files/Documents/125%20kHz%20-%20Hitag/HitagS.V11.pdf
147 void calc_crc(unsigned char * crc
, unsigned char data
, unsigned char Bitcount
) {
148 *crc
^= data
; // crc = crc (exor) data
150 if (*crc
& 0x80) // if (MSB-CRC == 1)
152 *crc
<<= 1; // CRC = CRC Bit-shift left
153 *crc
^= CRC_POLYNOM
; // CRC = CRC (exor) CRC_POLYNOM
155 *crc
<<= 1; // CRC = CRC Bit-shift left
157 } while (--Bitcount
);
160 static void hitag_send_bit(int bit
) {
162 // Reset clock for the next bit
163 AT91C_BASE_TC0
->TC_CCR
= AT91C_TC_SWTRG
;
170 while (AT91C_BASE_TC0
->TC_CV
< T0
* 32)
173 while (AT91C_BASE_TC0
->TC_CV
< T0
* 64)
178 while (AT91C_BASE_TC0
->TC_CV
< T0
* 16)
181 while (AT91C_BASE_TC0
->TC_CV
< T0
* 32)
184 while (AT91C_BASE_TC0
->TC_CV
< T0
* 48)
187 while (AT91C_BASE_TC0
->TC_CV
< T0
* 64)
196 while (AT91C_BASE_TC0
->TC_CV
< T0
* HITAG_T_TAG_HALF_PERIOD
)
199 while (AT91C_BASE_TC0
->TC_CV
< T0
* HITAG_T_TAG_FULL_PERIOD
)
204 while (AT91C_BASE_TC0
->TC_CV
< T0
* 8)
207 while (AT91C_BASE_TC0
->TC_CV
< T0
* 16)
210 while (AT91C_BASE_TC0
->TC_CV
< T0
* 24)
213 while (AT91C_BASE_TC0
->TC_CV
< T0
* 32)
220 // Manchester: Unloaded, then loaded |__--|
222 while (AT91C_BASE_TC0
->TC_CV
< T0
* 16)
225 while (AT91C_BASE_TC0
->TC_CV
< T0
* 32)
228 // Manchester: Loaded, then unloaded |--__|
230 while (AT91C_BASE_TC0
->TC_CV
< T0
* 16)
233 while (AT91C_BASE_TC0
->TC_CV
< T0
* 32)
240 // Manchester: Unloaded, then loaded |__--|
242 while (AT91C_BASE_TC0
->TC_CV
< T0
* 8)
245 while (AT91C_BASE_TC0
->TC_CV
< T0
* 16)
248 // Manchester: Loaded, then unloaded |--__|
250 while (AT91C_BASE_TC0
->TC_CV
< T0
* 8)
253 while (AT91C_BASE_TC0
->TC_CV
< T0
* 16)
263 static void hitag_send_frame(const byte_t
* frame
, size_t frame_len
) {
264 // Send start of frame
266 for (size_t i
= 0; i
< sof_bits
; i
++) {
270 // Send the content of the frame
271 for (size_t i
= 0; i
< frame_len
; i
++) {
272 hitag_send_bit((frame
[i
/ 8] >> (7 - (i
% 8))) & 1);
274 // Drop the modulation
278 static void hitag_reader_send_bit(int bit
) {
279 //Dbprintf("BIT: %d",bit);
281 // Reset clock for the next bit
282 AT91C_BASE_TC0
->TC_CCR
= AT91C_TC_SWTRG
;
284 // Binary puls length modulation (BPLM) is used to encode the data stream
285 // This means that a transmission of a one takes longer than that of a zero
287 // Enable modulation, which means, drop the the field
290 // Wait for 4-10 times the carrier period
291 while (AT91C_BASE_TC0
->TC_CV
< T0
* 6)
295 // Disable modulation, just activates the field again
300 while (AT91C_BASE_TC0
->TC_CV
< T0
* 11)
302 // SpinDelayUs(16*8);
305 while (AT91C_BASE_TC0
->TC_CV
< T0
* 14)
307 // SpinDelayUs(22*8);
310 // Wait for 4-10 times the carrier period
311 while (AT91C_BASE_TC0
->TC_CV
< T0
* 6)
315 // Disable modulation, just activates the field again
320 while (AT91C_BASE_TC0
->TC_CV
< T0
* 22)
322 // SpinDelayUs(16*8);
325 while (AT91C_BASE_TC0
->TC_CV
< T0
* 28)
327 // SpinDelayUs(22*8);
334 static void hitag_reader_send_frame(const byte_t
* frame
, size_t frame_len
) {
335 // Send the content of the frame
336 for (size_t i
= 0; i
< frame_len
; i
++) {
337 if (frame
[0] == 0xf8) {
338 //Dbprintf("BIT: %d",(frame[i / 8] >> (7 - (i % 8))) & 1);
340 hitag_reader_send_bit((frame
[i
/ 8] >> (7 - (i
% 8))) & 1);
343 AT91C_BASE_TC0
->TC_CCR
= AT91C_TC_SWTRG
;
344 // Enable modulation, which means, drop the the field
346 // Wait for 4-10 times the carrier period
347 while (AT91C_BASE_TC0
->TC_CV
< T0
* 6)
349 // Disable modulation, just activates the field again
354 * to check if the right uid was selected
356 static int check_select(byte_t
* rx
, uint32_t uid
) {
357 unsigned char resp
[48];
360 for (i
= 0; i
< 48; i
++)
361 resp
[i
] = (rx
[i
/ 8] >> (7 - (i
% 8))) & 0x1;
362 for (i
= 0; i
< 32; i
++)
363 ans
+= resp
[5 + i
] << (31 - i
);
364 /*if (rx[0] == 0x01 && rx[1] == 0x15 && rx[2] == 0xc1 && rx[3] == 0x14
365 && rx[4] == 0x65 && rx[5] == 0x38)
366 Dbprintf("got uid %X", ans);*/
374 * handles all commands from a reader
376 static void hitagS_handle_reader_command(byte_t
* rx
, const size_t rxlen
,
377 byte_t
* tx
, size_t* txlen
) {
378 byte_t rx_air
[HITAG_FRAME_LEN
];
384 // Copy the (original) received frame how it is send over the air
385 memcpy(rx_air
, rx
, nbytes(rxlen
));
386 // Reset the transmission frame length
388 // Try to find out which command was send by selecting on length (in bits)
391 //UID request with a selected response protocol mode
392 tag
.pstate
= HT_READY
;
393 tag
.tstate
= HT_NO_OP
;
394 if ((rx
[0] & 0xf0) == 0x30) {
395 tag
.mode
= HT_STANDARD
;
399 if ((rx
[0] & 0xf0) == 0xc0) {
400 tag
.mode
= HT_ADVANCED
;
405 if ((rx
[0] & 0xf0) == 0xd0) {
406 tag
.mode
= HT_FAST_ADVANCED
;
410 //send uid as a response
412 for (i
= 0; i
< 4; i
++)
413 tx
[i
] = (tag
.uid
>> (24 - (i
* 8))) & 0xff;
417 //select command from reader received
418 if (check_select(rx
, tag
.uid
) == 1) {
419 //if the right tag was selected
430 case HT_FAST_ADVANCED
:
439 for (i
= 0; i
< 4; i
++)
440 tx
[i
] = (tag
.pages
[0][1] >> (i
* 8)) & 0xff;
442 if (tag
.mode
!= HT_STANDARD
) {
445 for (i
= 0; i
< 4; i
++)
446 calc_crc(&crc
, tx
[i
], 8);
453 //challenge message received
454 Dbprintf("Challenge for UID: %X", temp_uid
);
457 state
= hitag2_init(rev64(tag
.key
), rev32(tag
.pages
[0][0]),
458 rev32(((rx
[3] << 24) + (rx
[2] << 16) + (rx
[1] << 8) + rx
[0])));
460 ",{0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}",
461 rx
[0], rx
[1], rx
[2], rx
[3], rx
[4], rx
[5], rx
[6], rx
[7]);
471 case HT_FAST_ADVANCED
:
479 for (i
= 0; i
< 4; i
++)
481 //send con2,pwdh0,pwdl0,pwdl1 encrypted as a response
482 tx
[0] = hitag2_byte(&state
) ^ ((tag
.pages
[0][1] >> 16) & 0xff);
483 tx
[1] = hitag2_byte(&state
) ^ tag
.pwdh0
;
484 tx
[2] = hitag2_byte(&state
) ^ tag
.pwdl0
;
485 tx
[3] = hitag2_byte(&state
) ^ tag
.pwdl1
;
486 if (tag
.mode
!= HT_STANDARD
) {
490 calc_crc(&crc
, ((tag
.pages
[0][1] >> 16) & 0xff), 8);
491 calc_crc(&crc
, tag
.pwdh0
, 8);
492 calc_crc(&crc
, tag
.pwdl0
, 8);
493 calc_crc(&crc
, tag
.pwdl1
, 8);
494 tx
[4] = (crc
^ hitag2_byte(&state
));
497 * some readers do not allow to authenticate multiple times in a row with the same tag.
498 * use this to change the uid between authentications.
502 if (temp2 % 2 == 0) {
503 tag.uid = 0x11223344;
504 tag.pages[0][0] = 0x44332211;
506 tag.uid = 0x55667788;
507 tag.pages[0][0] = 0x88776655;
512 //data received to be written
513 if (tag
.tstate
== HT_WRITING_PAGE_DATA
) {
514 tag
.tstate
= HT_NO_OP
;
515 tag
.pages
[page_to_be_written
/ 4][page_to_be_written
% 4] = (rx
[0]
516 << 0) + (rx
[1] << 8) + (rx
[2] << 16) + (rx
[3] << 24);
520 page_to_be_written
= 0;
530 case HT_FAST_ADVANCED
:
537 } else if (tag
.tstate
== HT_WRITING_BLOCK_DATA
) {
538 tag
.pages
[page_to_be_written
/ 4][page_to_be_written
% 4] = (rx
[0]
539 << 24) + (rx
[1] << 16) + (rx
[2] << 8) + rx
[3];
552 case HT_FAST_ADVANCED
:
559 page_to_be_written
++;
561 if (block_data_left
== 0) {
562 tag
.tstate
= HT_NO_OP
;
563 page_to_be_written
= 0;
568 //write page, write block, read page or read block command received
569 if ((rx
[0] & 0xf0) == 0xc0) //read page
572 page
= ((rx
[0] & 0x0f) * 16) + ((rx
[1] & 0xf0) / 16);
574 tx
[0] = (tag
.pages
[page
/ 4][page
% 4]) & 0xff;
575 tx
[1] = (tag
.pages
[page
/ 4][page
% 4] >> 8) & 0xff;
576 tx
[2] = (tag
.pages
[page
/ 4][page
% 4] >> 16) & 0xff;
577 tx
[3] = (tag
.pages
[page
/ 4][page
% 4] >> 24) & 0xff;
578 if (tag
.LKP
&& page
== 1)
590 case HT_FAST_ADVANCED
:
598 if (tag
.mode
!= HT_STANDARD
) {
602 for (i
= 0; i
< 4; i
++)
603 calc_crc(&crc
, tx
[i
], 8);
607 if (tag
.LKP
&& (page
== 2 || page
== 3)) {
608 //if reader asks for key or password and the LKP-mark is set do not respond
612 } else if ((rx
[0] & 0xf0) == 0xd0) //read block
614 page
= ((rx
[0] & 0x0f) * 16) + ((rx
[1] & 0xf0) / 16);
616 //send page,...,page+3 data
617 for (i
= 0; i
< 4; i
++) {
618 tx
[0 + i
* 4] = (tag
.pages
[page
/ 4][page
% 4]) & 0xff;
619 tx
[1 + i
* 4] = (tag
.pages
[page
/ 4][page
% 4] >> 8) & 0xff;
620 tx
[2 + i
* 4] = (tag
.pages
[page
/ 4][page
% 4] >> 16) & 0xff;
621 tx
[3 + i
* 4] = (tag
.pages
[page
/ 4][page
% 4] >> 24) & 0xff;
634 case HT_FAST_ADVANCED
:
642 if (tag
.mode
!= HT_STANDARD
) {
646 for (i
= 0; i
< 16; i
++)
647 calc_crc(&crc
, tx
[i
], 8);
651 if ((page
- 4) % 4 != 0 || (tag
.LKP
&& (page
- 4) == 0)) {
655 } else if ((rx
[0] & 0xf0) == 0x80) //write page
657 page
= ((rx
[0] & 0x0f) * 16) + ((rx
[1] & 0xf0) / 16);
668 case HT_FAST_ADVANCED
:
675 if ((tag
.LCON
&& page
== 1)
676 || (tag
.LKP
&& (page
== 2 || page
== 3))) {
683 page_to_be_written
= page
;
684 tag
.tstate
= HT_WRITING_PAGE_DATA
;
687 } else if ((rx
[0] & 0xf0) == 0x90) //write block
689 page
= ((rx
[0] & 0x0f) * 6) + ((rx
[1] & 0xf0) / 16);
699 case HT_FAST_ADVANCED
:
706 if (page
% 4 != 0 || page
== 0) {
713 page_to_be_written
= page
;
715 tag
.tstate
= HT_WRITING_BLOCK_DATA
;
727 * to autenticate to a tag with the given key or challenge
729 static int hitagS_handle_tag_auth(hitag_function htf
,uint64_t key
, uint64_t NrAr
, byte_t
* rx
, const size_t rxlen
, byte_t
* tx
,
731 byte_t rx_air
[HITAG_FRAME_LEN
];
732 int response_bit
[200];
734 unsigned char mask
= 1;
735 unsigned char uid
[32];
736 byte_t uid1
= 0x00, uid2
= 0x00, uid3
= 0x00, uid4
= 0x00;
740 byte_t conf_pages
[3];
741 memcpy(rx_air
, rx
, nbytes(rxlen
));
744 if (tag
.pstate
== HT_READY
&& rxlen
>= 67) {
747 Dbprintf("authentication failed!");
751 for (i
= 0; i
< 10; i
++) {
752 for (j
= 0; j
< 8; j
++) {
754 if ((rx
[i
] & ((mask
<< 7) >> j
)) != 0)
760 for (i
= 5; i
< z
; i
+= 2) {
761 uid
[k
] = response_bit
[i
];
766 uid1
= (uid
[0] << 7) | (uid
[1] << 6) | (uid
[2] << 5) | (uid
[3] << 4)
767 | (uid
[4] << 3) | (uid
[5] << 2) | (uid
[6] << 1) | uid
[7];
768 uid2
= (uid
[8] << 7) | (uid
[9] << 6) | (uid
[10] << 5) | (uid
[11] << 4)
769 | (uid
[12] << 3) | (uid
[13] << 2) | (uid
[14] << 1) | uid
[15];
770 uid3
= (uid
[16] << 7) | (uid
[17] << 6) | (uid
[18] << 5) | (uid
[19] << 4)
771 | (uid
[20] << 3) | (uid
[21] << 2) | (uid
[22] << 1) | uid
[23];
772 uid4
= (uid
[24] << 7) | (uid
[25] << 6) | (uid
[26] << 5) | (uid
[27] << 4)
773 | (uid
[28] << 3) | (uid
[29] << 2) | (uid
[30] << 1) | uid
[31];
775 Dbprintf("UID: %02X %02X %02X %02X", uid1
, uid2
, uid3
, uid4
);
776 tag
.uid
= (uid4
<< 24 | uid3
<< 16 | uid2
<< 8 | uid1
);
781 calc_crc(&crc
, 0x00, 5);
782 calc_crc(&crc
, uid1
, 8);
783 calc_crc(&crc
, uid2
, 8);
784 calc_crc(&crc
, uid3
, 8);
785 calc_crc(&crc
, uid4
, 8);
786 for (i
= 0; i
< 100; i
++) {
789 for (i
= 0; i
< 5; i
++) {
792 for (i
= 5; i
< 37; i
++) {
793 response_bit
[i
] = uid
[i
- 5];
795 for (j
= 0; j
< 8; j
++) {
797 if ((crc
& ((mask
<< 7) >> j
)) != 0)
802 for (i
= 0; i
< 6; i
++) {
803 tx
[i
] = (response_bit
[k
] << 7) | (response_bit
[k
+ 1] << 6)
804 | (response_bit
[k
+ 2] << 5) | (response_bit
[k
+ 3] << 4)
805 | (response_bit
[k
+ 4] << 3) | (response_bit
[k
+ 5] << 2)
806 | (response_bit
[k
+ 6] << 1) | response_bit
[k
+ 7];
809 tag
.pstate
= HT_INIT
;
810 } else if (tag
.pstate
== HT_INIT
&& rxlen
== 44) {
811 // received configuration after select command
813 for (i
= 0; i
< 6; i
++) {
814 for (j
= 0; j
< 8; j
++) {
816 if ((rx
[i
] & ((mask
<< 7) >> j
)) != 0)
821 conf_pages
[0] = ((response_bit
[4] << 7) | (response_bit
[5] << 6)
822 | (response_bit
[6] << 5) | (response_bit
[7] << 4)
823 | (response_bit
[8] << 3) | (response_bit
[9] << 2)
824 | (response_bit
[10] << 1) | response_bit
[11]);
825 //check wich memorysize this tag has
826 if (response_bit
[10] == 0 && response_bit
[11] == 0)
827 tag
.max_page
= 32 / 32;
828 if (response_bit
[10] == 0 && response_bit
[11] == 1)
829 tag
.max_page
= 256 / 32;
830 if (response_bit
[10] == 1 && response_bit
[11] == 0)
831 tag
.max_page
= 2048 / 32;
832 conf_pages
[1] = ((response_bit
[12] << 7) | (response_bit
[13] << 6)
833 | (response_bit
[14] << 5) | (response_bit
[15] << 4)
834 | (response_bit
[16] << 3) | (response_bit
[17] << 2)
835 | (response_bit
[18] << 1) | response_bit
[19]);
836 tag
.auth
= response_bit
[12];
837 tag
.TTFC
= response_bit
[13];
838 //tag.TTFDR in response_bit[14] and response_bit[15]
839 //tag.TTFM in response_bit[16] and response_bit[17]
840 tag
.LCON
= response_bit
[18];
841 tag
.LKP
= response_bit
[19];
842 conf_pages
[2] = ((response_bit
[20] << 7) | (response_bit
[21] << 6)
843 | (response_bit
[22] << 5) | (response_bit
[23] << 4)
844 | (response_bit
[24] << 3) | (response_bit
[25] << 2)
845 | (response_bit
[26] << 1) | response_bit
[27]);
846 tag
.LCK7
= response_bit
[20];
847 tag
.LCK6
= response_bit
[21];
848 tag
.LCK5
= response_bit
[22];
849 tag
.LCK4
= response_bit
[23];
850 tag
.LCK3
= response_bit
[24];
851 tag
.LCK2
= response_bit
[25];
852 tag
.LCK1
= response_bit
[26];
853 tag
.LCK0
= response_bit
[27];
856 Dbprintf("conf0: %02X conf1: %02X conf2: %02X", conf_pages
[0],
857 conf_pages
[1], conf_pages
[2]);
859 //if the tag is in authentication mode try the key or challenge
862 if(htf
==02||htf
==04){ //RHTS_KEY //WHTS_KEY
863 state
= hitag2_init(rev64(key
), rev32(tag
.uid
),
866 for (i
= 0; i
< 4; i
++) {
867 auth_ks
[i
] = hitag2_byte(&state
) ^ 0xff;
871 tx
[1] = (rnd
>> 8) & 0xff;
872 tx
[2] = (rnd
>> 16) & 0xff;
873 tx
[3] = (rnd
>> 24) & 0xff;
880 Dbprintf("%02X %02X %02X %02X %02X %02X %02X %02X", tx
[0],
881 tx
[1], tx
[2], tx
[3], tx
[4], tx
[5], tx
[6], tx
[7]);
882 } else if(htf
==01 || htf
==03) { //RHTS_CHALLENGE //WHTS_CHALLENGE
883 for (i
= 0; i
< 8; i
++)
884 tx
[i
]=((NrAr
>>(56-(i
*8)))&0xff);
887 tag
.pstate
= HT_AUTHENTICATE
;
889 Dbprintf("authentication failed!");
892 } else if (tag
.auth
== 0) {
893 tag
.pstate
= HT_SELECTED
;
896 } else if (tag
.pstate
== HT_AUTHENTICATE
&& rxlen
== 44) {
897 //encrypted con2,password received.
899 calc_crc(&crc
, 0x80, 1);
900 calc_crc(&crc
, ((rx
[0] & 0x0f) * 16 + ((rx
[1] & 0xf0) / 16)), 8);
901 calc_crc(&crc
, ((rx
[1] & 0x0f) * 16 + ((rx
[2] & 0xf0) / 16)), 8);
902 calc_crc(&crc
, ((rx
[2] & 0x0f) * 16 + ((rx
[3] & 0xf0) / 16)), 8);
903 calc_crc(&crc
, ((rx
[3] & 0x0f) * 16 + ((rx
[4] & 0xf0) / 16)), 8);
905 Dbprintf("UID:::%X", tag
.uid
);
906 Dbprintf("RND:::%X", rnd
);
913 if(htf
==02 || htf
==04){ //RHTS_KEY //WHTS_KEY
915 state
= hitag2_init(rev64(key
), rev32(tag
.uid
), rev32(rnd
));
916 for (i
= 0; i
< 5; i
++)
918 pwdh0
= ((rx
[1] & 0x0f) * 16 + ((rx
[2] & 0xf0) / 16))
919 ^ hitag2_byte(&state
);
920 pwdl0
= ((rx
[2] & 0x0f) * 16 + ((rx
[3] & 0xf0) / 16))
921 ^ hitag2_byte(&state
);
922 pwdl1
= ((rx
[3] & 0x0f) * 16 + ((rx
[4] & 0xf0) / 16))
923 ^ hitag2_byte(&state
);
927 Dbprintf("pwdh0 %02X pwdl0 %02X pwdl1 %02X", pwdh0
, pwdl0
, pwdl1
);
930 //Dbprintf("%X %02X", rnd, ((rx[4] & 0x0f) * 16) + ((rx[5] & 0xf0) / 16));
933 tag
.pstate
= HT_SELECTED
; //tag is now ready for read/write commands
940 * Emulates a Hitag S Tag with the given data from the .hts file
942 void SimulateHitagSTag(bool tag_mem_supplied
, byte_t
* data
) {
947 byte_t rx
[HITAG_FRAME_LEN
];
949 //bool bQuitTraceFull = false;
951 byte_t txbuf
[HITAG_FRAME_LEN
];
954 // free eventually allocated BigBuf memory
955 BigBuf_free(); BigBuf_Clear_ext(false);
957 // Clean up trace and prepare it for storing frames
961 DbpString("Starting HitagS simulation");
964 tag
.pstate
= HT_READY
;
965 tag
.tstate
= HT_NO_OP
;
966 tag
.tstate
= HT_NO_OP
;
967 for (i
= 0; i
< 16; i
++)
968 for (j
= 0; j
< 4; j
++)
969 tag
.pages
[i
][j
] = 0x0;
970 //read tag data into memory
971 if (tag_mem_supplied
) {
972 DbpString("Loading hitagS memory...");
973 memcpy((byte_t
*)tag
.pages
,data
,4*64);
975 tag
.uid
=(uint32_t)tag
.pages
[0];
976 Dbprintf("Hitag S simulation started");
977 tag
.key
=(intptr_t)tag
.pages
[3];
979 tag
.key
+=((tag
.pages
[2][0])<<8)+tag
.pages
[2][1];
980 tag
.pwdl0
=tag
.pages
[2][3];
981 tag
.pwdl1
=tag
.pages
[2][2];
982 tag
.pwdh0
=tag
.pages
[1][0];
985 if((tag
.pages
[1][3]&0x2)==0 && (tag
.pages
[1][3]&0x1)==1)
987 if((tag
.pages
[1][3]&0x2)==0 && (tag
.pages
[1][3]&0x1)==0)
991 if((tag
.pages
[1][2]&0x80)==1)
994 if((tag
.pages
[1][2]&0x2)==1)
997 if((tag
.pages
[1][2]&0x1)==1)
1000 //0=read write 1=read only
1002 if((tag
.pages
[1][1]&0x80)==1)
1005 if((tag
.pages
[1][1]&0x40)==1)
1008 if((tag
.pages
[1][1]&0x20)==1)
1011 if((tag
.pages
[1][1]&0x10)==1)
1014 if((tag
.pages
[1][1]&0x8)==1)
1017 if((tag
.pages
[1][1]&0x4)==1)
1020 if((tag
.pages
[1][1]&0x2)==1)
1023 if((tag
.pages
[1][1]&0x1)==1)
1026 // Set up simulator mode, frequency divisor which will drive the FPGA
1027 // and analog mux selection.
1028 FpgaDownloadAndGo(FPGA_BITSTREAM_LF
);
1029 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT
| FPGA_LF_EDGE_DETECT_READER_FIELD
);
1030 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, 95); //125Khz
1031 SetAdcMuxFor(GPIO_MUXSEL_LOPKD
);
1034 // Configure output pin that is connected to the FPGA (for modulating)
1035 AT91C_BASE_PIOA
->PIO_OER
= GPIO_SSC_DOUT
;
1036 AT91C_BASE_PIOA
->PIO_PER
= GPIO_SSC_DOUT
;
1038 // Disable modulation at default, which means release resistance
1041 // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering
1042 AT91C_BASE_PMC
->PMC_PCER
= (1 << AT91C_ID_TC0
);
1044 // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the reader frames
1045 AT91C_BASE_PMC
->PMC_PCER
= (1 << AT91C_ID_TC1
);
1046 AT91C_BASE_PIOA
->PIO_BSR
= GPIO_SSC_FRAME
;
1048 // Disable timer during configuration
1049 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKDIS
;
1051 // Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
1052 // external trigger rising edge, load RA on rising edge of TIOA.
1053 AT91C_BASE_TC1
->TC_CMR
= AT91C_TC_CLKS_TIMER_DIV1_CLOCK
1054 | AT91C_TC_ETRGEDG_RISING
| AT91C_TC_ABETRG
| AT91C_TC_LDRA_RISING
;
1056 // Reset the received frame, frame count and timing info
1057 memset(rx
, 0x00, sizeof(rx
));
1062 // Enable and reset counter
1063 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKEN
| AT91C_TC_SWTRG
;
1065 while (!BUTTON_PRESS()) {
1069 // Receive frame, watch for at most T0*EOF periods
1070 while (AT91C_BASE_TC1
->TC_CV
< T0
* HITAG_T_EOF
) {
1071 // Check if rising edge in modulation is detected
1072 if (AT91C_BASE_TC1
->TC_SR
& AT91C_TC_LDRAS
) {
1073 // Retrieve the new timing values
1074 int ra
= (AT91C_BASE_TC1
->TC_RA
/ T0
) + overflow
;
1077 // Reset timer every frame, we have to capture the last edge for timing
1078 AT91C_BASE_TC0
->TC_CCR
= AT91C_TC_CLKEN
| AT91C_TC_SWTRG
;
1082 // Capture reader frame
1083 if (ra
>= HITAG_T_STOP
) {
1085 //DbpString("wierd0?");
1087 // Capture the T0 periods that have passed since last communication or field drop (reset)
1088 response
= (ra
- HITAG_T_LOW
);
1089 } else if (ra
>= HITAG_T_1_MIN
) {
1091 rx
[rxlen
/ 8] |= 1 << (7 - (rxlen
% 8));
1093 } else if (ra
>= HITAG_T_0_MIN
) {
1095 rx
[rxlen
/ 8] |= 0 << (7 - (rxlen
% 8));
1098 // Ignore wierd value, is to small to mean anything
1103 // Check if frame was captured
1107 if (!LogTraceHitag(rx
, rxlen
, response
, 0, true)) {
1108 DbpString("Trace full");
1113 // Disable timer 1 with external trigger to avoid triggers during our own modulation
1114 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKDIS
;
1116 // Process the incoming frame (rx) and prepare the outgoing frame (tx)
1117 hitagS_handle_reader_command(rx
, rxlen
, tx
, &txlen
);
1119 // Wait for HITAG_T_WAIT_1 carrier periods after the last reader bit,
1120 // not that since the clock counts since the rising edge, but T_Wait1 is
1121 // with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low)
1122 // periods. The gap time T_Low varies (4..10). All timer values are in
1123 // terms of T0 units
1124 while (AT91C_BASE_TC0
->TC_CV
< T0
* (HITAG_T_WAIT_1
- HITAG_T_LOW
))
1127 // Send and store the tag answer (if there is any)
1129 // Transmit the tag frame
1130 hitag_send_frame(tx
, txlen
);
1131 // Store the frame in the trace
1133 if (!LogTraceHitag(tx
, txlen
, 0, 0, false)) {
1134 DbpString("Trace full");
1140 // Reset the received frame and response timing info
1141 memset(rx
, 0x00, sizeof(rx
));
1144 // Enable and reset external trigger in timer for capturing future frames
1145 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKEN
| AT91C_TC_SWTRG
;
1148 // Reset the frame length
1150 // Save the timer overflow, will be 0 when frame was received
1151 overflow
+= (AT91C_BASE_TC1
->TC_CV
/ T0
);
1152 // Reset the timer to restart while-loop that receives frames
1153 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_SWTRG
;
1157 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKDIS
;
1158 AT91C_BASE_TC0
->TC_CCR
= AT91C_TC_CLKDIS
;
1159 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
1163 * Authenticates to the Tag with the given key or challenge.
1164 * If the key was given the password will be decrypted.
1165 * Reads every page of a hitag S transpoder.
1167 void ReadHitagS(hitag_function htf
, hitag_data
* htd
) {
1170 int response_bit
[200];
1172 byte_t rx
[HITAG_FRAME_LEN
];
1174 byte_t txbuf
[HITAG_FRAME_LEN
];
1181 int t_wait
= HITAG_T_WAIT_MAX
;
1183 bool bQuitTraceFull
= false;
1185 unsigned char mask
= 1;
1187 unsigned char pageData
[32];
1188 page_to_be_written
= 0;
1190 //read given key/challenge
1196 case 01: { //RHTS_CHALLENGE
1197 DbpString("Authenticating using nr,ar pair:");
1198 memcpy(NrAr_
,htd
->auth
.NrAr
,8);
1199 Dbhexdump(8,NrAr_
,false);
1200 NrAr
=NrAr_
[7] | ((uint64_t)NrAr_
[6]) << 8 | ((uint64_t)NrAr_
[5]) << 16 | ((uint64_t)NrAr_
[4]) << 24 | ((uint64_t)NrAr_
[3]) << 32 |
1201 ((uint64_t)NrAr_
[2]) << 40| ((uint64_t)NrAr_
[1]) << 48 | ((uint64_t)NrAr_
[0]) << 56;
1203 case 02: { //RHTS_KEY
1204 DbpString("Authenticating using key:");
1205 memcpy(key_
,htd
->crypto
.key
,6);
1206 Dbhexdump(6,key_
,false);
1207 key
=key_
[5] | ((uint64_t)key_
[4]) << 8 | ((uint64_t)key_
[3]) << 16 | ((uint64_t)key_
[2]) << 24 | ((uint64_t)key_
[1]) << 32 | ((uint64_t)key_
[0]) << 40;
1210 Dbprintf("Error , unknown function: %d",htf
);
1217 FpgaDownloadAndGo(FPGA_BITSTREAM_LF
);
1218 // Reset the return status
1219 bSuccessful
= false;
1221 // Clean up trace and prepare it for storing frames
1226 bQuitTraceFull
= true;
1230 // Configure output and enable pin that is connected to the FPGA (for modulating)
1231 AT91C_BASE_PIOA
->PIO_OER
= GPIO_SSC_DOUT
;
1232 AT91C_BASE_PIOA
->PIO_PER
= GPIO_SSC_DOUT
;
1234 // Set fpga in edge detect with reader field, we can modulate as reader now
1236 FPGA_MAJOR_MODE_LF_EDGE_DETECT
| FPGA_LF_EDGE_DETECT_READER_FIELD
);
1238 // Set Frequency divisor which will drive the FPGA and analog mux selection
1239 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, 95); //125Khz
1240 SetAdcMuxFor(GPIO_MUXSEL_LOPKD
);
1243 // Disable modulation at default, which means enable the field
1246 // Give it a bit of time for the resonant antenna to settle.
1249 // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering
1250 AT91C_BASE_PMC
->PMC_PCER
= (1 << AT91C_ID_TC0
);
1252 // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the tag frames
1253 AT91C_BASE_PMC
->PMC_PCER
= (1 << AT91C_ID_TC1
);
1254 AT91C_BASE_PIOA
->PIO_BSR
= GPIO_SSC_FRAME
;
1256 // Disable timer during configuration
1257 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKDIS
;
1259 // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
1260 // external trigger rising edge, load RA on falling edge of TIOA.
1261 AT91C_BASE_TC1
->TC_CMR
= AT91C_TC_CLKS_TIMER_DIV1_CLOCK
1263 | AT91C_TC_ETRGEDG_FALLING
| AT91C_TC_ABETRG
| AT91C_TC_LDRA_FALLING
;
1265 // Enable and reset counters
1266 AT91C_BASE_TC0
->TC_CCR
= AT91C_TC_CLKEN
| AT91C_TC_SWTRG
;
1267 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKEN
| AT91C_TC_SWTRG
;
1269 // Reset the received frame, frame count and timing info
1278 while (!bStop
&& !BUTTON_PRESS()) {
1282 // Check if frame was captured and store it
1286 if (!LogTraceHitag(rx
, rxlen
, response
, 0, false)) {
1287 DbpString("Trace full");
1288 if (bQuitTraceFull
) {
1297 // By default reset the transmission buffer
1302 //start authentication
1304 memcpy(tx
, "\xc0", nbytes(txlen
));
1305 tag
.pstate
= HT_READY
;
1306 tag
.tstate
= HT_NO_OP
;
1307 } else if (tag
.pstate
!= HT_SELECTED
) {
1308 if (hitagS_handle_tag_auth(htf
, key
,NrAr
,rx
, rxlen
, tx
, &txlen
) == -1)
1311 if (tag
.pstate
== HT_SELECTED
&& tag
.tstate
== HT_NO_OP
&& rxlen
> 0) {
1313 tag
.tstate
= HT_READING_PAGE
;
1316 tx
[0] = 0xc0 + (sendNum
/ 16);
1317 calc_crc(&crc
, tx
[0], 8);
1318 calc_crc(&crc
, 0x00 + ((sendNum
% 16) * 16), 4);
1319 tx
[1] = 0x00 + ((sendNum
% 16) * 16) + (crc
/ 16);
1320 tx
[2] = 0x00 + (crc
% 16) * 16;
1321 } else if (tag
.pstate
== HT_SELECTED
&& tag
.tstate
== HT_READING_PAGE
1323 //save received data
1325 for (i
= 0; i
< 5; i
++) {
1326 for (j
= 0; j
< 8; j
++) {
1327 response_bit
[z
] = 0;
1328 if ((rx
[i
] & ((mask
<< 7) >> j
)) != 0)
1329 response_bit
[z
] = 1;
1334 for (i
= 4; i
< 36; i
++) {
1335 pageData
[k
] = response_bit
[i
];
1338 for (i
= 0; i
< 4; i
++)
1339 tag
.pages
[sendNum
/ 4][sendNum
% 4] = 0x0;
1340 for (i
= 0; i
< 4; i
++) {
1341 tag
.pages
[sendNum
/ 4][sendNum
% 4] += ((pageData
[i
* 8] << 7)
1342 | (pageData
[1 + (i
* 8)] << 6)
1343 | (pageData
[2 + (i
* 8)] << 5)
1344 | (pageData
[3 + (i
* 8)] << 4)
1345 | (pageData
[4 + (i
* 8)] << 3)
1346 | (pageData
[5 + (i
* 8)] << 2)
1347 | (pageData
[6 + (i
* 8)] << 1) | pageData
[7 + (i
* 8)])
1350 if (tag
.auth
&& tag
.LKP
&& sendNum
== 1) {
1351 Dbprintf("Page[%2d]: %02X %02X %02X %02X", sendNum
, pwdh0
,
1352 (tag
.pages
[sendNum
/ 4][sendNum
% 4] >> 16) & 0xff,
1353 (tag
.pages
[sendNum
/ 4][sendNum
% 4] >> 8) & 0xff,
1354 tag
.pages
[sendNum
/ 4][sendNum
% 4] & 0xff);
1356 Dbprintf("Page[%2d]: %02X %02X %02X %02X", sendNum
,
1357 (tag
.pages
[sendNum
/ 4][sendNum
% 4] >> 24) & 0xff,
1358 (tag
.pages
[sendNum
/ 4][sendNum
% 4] >> 16) & 0xff,
1359 (tag
.pages
[sendNum
/ 4][sendNum
% 4] >> 8) & 0xff,
1360 tag
.pages
[sendNum
/ 4][sendNum
% 4] & 0xff);
1364 //display key and password if possible
1365 if (sendNum
== 2 && tag
.auth
== 1 && tag
.LKP
) {
1366 if (htf
== 02) { //RHTS_KEY
1367 Dbprintf("Page[ 2]: %02X %02X %02X %02X",
1368 (byte_t
)(key
>> 8) & 0xff,
1369 (byte_t
) key
& 0xff, pwdl1
, pwdl0
);
1370 Dbprintf("Page[ 3]: %02X %02X %02X %02X",
1371 (byte_t
)(key
>> 40) & 0xff,
1372 (byte_t
)(key
>> 32) & 0xff,
1373 (byte_t
)(key
>> 24) & 0xff,
1374 (byte_t
)(key
>> 16) & 0xff);
1376 //if the authentication is done with a challenge the key and password are unknown
1377 Dbprintf("Page[ 2]: __ __ __ __");
1378 Dbprintf("Page[ 3]: __ __ __ __");
1384 tx
[0] = 0xc0 + (sendNum
/ 16);
1385 calc_crc(&crc
, tx
[0], 8);
1386 calc_crc(&crc
, 0x00 + ((sendNum
% 16) * 16), 4);
1387 tx
[1] = 0x00 + ((sendNum
% 16) * 16) + (crc
/ 16);
1388 tx
[2] = 0x00 + (crc
% 16) * 16;
1389 if (sendNum
>= tag
.max_page
) {
1394 // Send and store the reader command
1395 // Disable timer 1 with external trigger to avoid triggers during our own modulation
1396 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKDIS
;
1398 // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting,
1399 // Since the clock counts since the last falling edge, a 'one' means that the
1400 // falling edge occured halfway the period. with respect to this falling edge,
1401 // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
1402 // All timer values are in terms of T0 units
1404 while (AT91C_BASE_TC0
->TC_CV
1405 < T0
* (t_wait
+ (HITAG_T_TAG_HALF_PERIOD
* lastbit
)))
1408 // Transmit the reader frame
1409 hitag_reader_send_frame(tx
, txlen
);
1411 // Enable and reset external trigger in timer for capturing future frames
1412 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKEN
| AT91C_TC_SWTRG
;
1414 // Add transmitted frame to total count
1418 // Store the frame in the trace
1419 if (!LogTraceHitag(tx
, txlen
, HITAG_T_WAIT_2
, 0, true)) {
1420 if (bQuitTraceFull
) {
1421 DbpString("Trace full");
1430 // Reset values for receiving frames
1431 memset(rx
, 0x00, sizeof(rx
));
1435 tag_sof
= reset_sof
;
1438 // Receive frame, watch for at most T0*EOF periods
1439 while (AT91C_BASE_TC1
->TC_CV
< T0
* HITAG_T_WAIT_MAX
) {
1440 // Check if falling edge in tag modulation is detected
1441 if (AT91C_BASE_TC1
->TC_SR
& AT91C_TC_LDRAS
) {
1442 // Retrieve the new timing values
1443 int ra
= (AT91C_BASE_TC1
->TC_RA
/ T0
);
1445 // Reset timer every frame, we have to capture the last edge for timing
1446 AT91C_BASE_TC0
->TC_CCR
= AT91C_TC_SWTRG
;
1450 // Capture tag frame (manchester decoding using only falling edges)
1451 if (ra
>= HITAG_T_EOF
) {
1453 //DbpString("wierd1?");
1455 // Capture the T0 periods that have passed since last communication or field drop (reset)
1456 // We always recieve a 'one' first, which has the falling edge after a half period |-_|
1457 response
= ra
- HITAG_T_TAG_HALF_PERIOD
;
1458 } else if (ra
>= HITAG_T_TAG_CAPTURE_FOUR_HALF
) {
1459 // Manchester coding example |-_|_-|-_| (101)
1460 rx
[rxlen
/ 8] |= 0 << (7 - (rxlen
% 8));
1462 rx
[rxlen
/ 8] |= 1 << (7 - (rxlen
% 8));
1464 } else if (ra
>= HITAG_T_TAG_CAPTURE_THREE_HALF
) {
1465 // Manchester coding example |_-|...|_-|-_| (0...01)
1466 rx
[rxlen
/ 8] |= 0 << (7 - (rxlen
% 8));
1468 // We have to skip this half period at start and add the 'one' the second time
1470 rx
[rxlen
/ 8] |= 1 << (7 - (rxlen
% 8));
1475 } else if (ra
>= HITAG_T_TAG_CAPTURE_TWO_HALF
) {
1476 // Manchester coding example |_-|_-| (00) or |-_|-_| (11)
1478 // Ignore bits that are transmitted during SOF
1481 // bit is same as last bit
1482 rx
[rxlen
/ 8] |= lastbit
<< (7 - (rxlen
% 8));
1486 // Ignore wierd value, is to small to mean anything
1490 // We can break this loop if we received the last bit from a frame
1491 if (AT91C_BASE_TC1
->TC_CV
> T0
* HITAG_T_EOF
) {
1500 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKDIS
;
1501 AT91C_BASE_TC0
->TC_CCR
= AT91C_TC_CLKDIS
;
1502 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
1503 cmd_send(CMD_ACK
, bSuccessful
, 0, 0, 0, 0);
1507 * Authenticates to the Tag with the given Key or Challenge.
1508 * Writes the given 32Bit data into page_
1510 void WritePageHitagS(hitag_function htf
, hitag_data
* htd
,int page_
) {
1513 byte_t rx
[HITAG_FRAME_LEN
];
1515 byte_t txbuf
[HITAG_FRAME_LEN
];
1522 int t_wait
= HITAG_T_WAIT_MAX
;
1524 bool bQuitTraceFull
= false;
1527 byte_t data
[4]= {0,0,0,0};
1529 //read given key/challenge, the page and the data
1535 case 03: { //WHTS_CHALLENGE
1536 memcpy(data
,htd
->auth
.data
,4);
1537 DbpString("Authenticating using nr,ar pair:");
1538 memcpy(NrAr_
,htd
->auth
.NrAr
,8);
1539 Dbhexdump(8,NrAr_
,false);
1540 NrAr
=NrAr_
[7] | ((uint64_t)NrAr_
[6]) << 8 | ((uint64_t)NrAr_
[5]) << 16 | ((uint64_t)NrAr_
[4]) << 24 | ((uint64_t)NrAr_
[3]) << 32 |
1541 ((uint64_t)NrAr_
[2]) << 40| ((uint64_t)NrAr_
[1]) << 48 | ((uint64_t)NrAr_
[0]) << 56;
1543 case 04: { //WHTS_KEY
1544 memcpy(data
,htd
->crypto
.data
,4);
1545 DbpString("Authenticating using key:");
1546 memcpy(key_
,htd
->crypto
.key
,6);
1547 Dbhexdump(6,key_
,false);
1548 key
=key_
[5] | ((uint64_t)key_
[4]) << 8 | ((uint64_t)key_
[3]) << 16 | ((uint64_t)key_
[2]) << 24 | ((uint64_t)key_
[1]) << 32 | ((uint64_t)key_
[0]) << 40;
1551 Dbprintf("Error , unknown function: %d",htf
);
1556 Dbprintf("Page: %d",page_
);
1557 Dbprintf("DATA: %02X %02X %02X %02X", data
[0], data
[1], data
[2], data
[3]);
1558 FpgaDownloadAndGo(FPGA_BITSTREAM_LF
);
1559 // Reset the return status
1560 bSuccessful
= false;
1562 tag
.pstate
= HT_READY
;
1563 tag
.tstate
= HT_NO_OP
;
1565 // Clean up trace and prepare it for storing frames
1570 bQuitTraceFull
= true;
1574 // Configure output and enable pin that is connected to the FPGA (for modulating)
1575 AT91C_BASE_PIOA
->PIO_OER
= GPIO_SSC_DOUT
;
1576 AT91C_BASE_PIOA
->PIO_PER
= GPIO_SSC_DOUT
;
1578 // Set fpga in edge detect with reader field, we can modulate as reader now
1580 FPGA_MAJOR_MODE_LF_EDGE_DETECT
| FPGA_LF_EDGE_DETECT_READER_FIELD
);
1582 // Set Frequency divisor which will drive the FPGA and analog mux selection
1583 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, 95); //125Khz
1584 SetAdcMuxFor(GPIO_MUXSEL_LOPKD
);
1587 // Disable modulation at default, which means enable the field
1590 // Give it a bit of time for the resonant antenna to settle.
1593 // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering
1594 AT91C_BASE_PMC
->PMC_PCER
= (1 << AT91C_ID_TC0
);
1596 // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the tag frames
1597 AT91C_BASE_PMC
->PMC_PCER
= (1 << AT91C_ID_TC1
);
1598 AT91C_BASE_PIOA
->PIO_BSR
= GPIO_SSC_FRAME
;
1600 // Disable timer during configuration
1601 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKDIS
;
1603 // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
1604 // external trigger rising edge, load RA on falling edge of TIOA.
1605 AT91C_BASE_TC1
->TC_CMR
= AT91C_TC_CLKS_TIMER_DIV1_CLOCK
1606 | AT91C_TC_ETRGEDG_FALLING
| AT91C_TC_ABETRG
1607 | AT91C_TC_LDRA_FALLING
;
1609 // Enable and reset counters
1610 AT91C_BASE_TC0
->TC_CCR
= AT91C_TC_CLKEN
| AT91C_TC_SWTRG
;
1611 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKEN
| AT91C_TC_SWTRG
;
1613 // Reset the received frame, frame count and timing info
1622 while (!bStop
&& !BUTTON_PRESS()) {
1626 // Check if frame was captured and store it
1630 if (!LogTraceHitag(rx
, rxlen
, response
, 0, false)) {
1631 DbpString("Trace full");
1632 if (bQuitTraceFull
) {
1641 //check for valid input
1644 "usage: lf hitag writer [03 | 04] [CHALLENGE | KEY] [page] [byte0] [byte1] [byte2] [byte3]");
1648 // By default reset the transmission buffer
1652 if (rxlen
== 0 && tag
.tstate
== HT_WRITING_PAGE_ACK
) {
1653 //no write access on this page
1654 Dbprintf("no write access on page %d", page_
);
1656 } else if (rxlen
== 0 && tag
.tstate
!= HT_WRITING_PAGE_DATA
) {
1657 //start the authetication
1659 memcpy(tx
, "\xc0", nbytes(txlen
));
1660 tag
.pstate
= HT_READY
;
1661 tag
.tstate
= HT_NO_OP
;
1662 } else if (tag
.pstate
!= HT_SELECTED
) {
1663 //try to authenticate with the given key or challenge
1664 if (hitagS_handle_tag_auth(htf
,key
,NrAr
,rx
, rxlen
, tx
, &txlen
) == -1)
1667 if (tag
.pstate
== HT_SELECTED
&& tag
.tstate
== HT_NO_OP
&& rxlen
> 0) {
1668 //check if the given page exists
1669 if (page
> tag
.max_page
) {
1670 Dbprintf("page number too big");
1673 //ask Tag for write permission
1674 tag
.tstate
= HT_WRITING_PAGE_ACK
;
1677 tx
[0] = 0x90 + (page
/ 16);
1678 calc_crc(&crc
, tx
[0], 8);
1679 calc_crc(&crc
, 0x00 + ((page
% 16) * 16), 4);
1680 tx
[1] = 0x00 + ((page
% 16) * 16) + (crc
/ 16);
1681 tx
[2] = 0x00 + (crc
% 16) * 16;
1682 } else if (tag
.pstate
== HT_SELECTED
&& tag
.tstate
== HT_WRITING_PAGE_ACK
1683 && rxlen
== 6 && rx
[0] == 0xf4) {
1684 //ACK recieved to write the page. send data
1685 tag
.tstate
= HT_WRITING_PAGE_DATA
;
1688 calc_crc(&crc
, data
[3], 8);
1689 calc_crc(&crc
, data
[2], 8);
1690 calc_crc(&crc
, data
[1], 8);
1691 calc_crc(&crc
, data
[0], 8);
1697 } else if (tag
.pstate
== HT_SELECTED
&& tag
.tstate
== HT_WRITING_PAGE_DATA
1698 && rxlen
== 6 && rx
[0] == 0xf4) {
1700 Dbprintf("Successful!");
1704 // Send and store the reader command
1705 // Disable timer 1 with external trigger to avoid triggers during our own modulation
1706 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKDIS
;
1708 // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting,
1709 // Since the clock counts since the last falling edge, a 'one' means that the
1710 // falling edge occured halfway the period. with respect to this falling edge,
1711 // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
1712 // All timer values are in terms of T0 units
1714 while (AT91C_BASE_TC0
->TC_CV
1715 < T0
* (t_wait
+ (HITAG_T_TAG_HALF_PERIOD
* lastbit
)))
1718 // Transmit the reader frame
1719 hitag_reader_send_frame(tx
, txlen
);
1721 // Enable and reset external trigger in timer for capturing future frames
1722 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKEN
| AT91C_TC_SWTRG
;
1724 // Add transmitted frame to total count
1728 // Store the frame in the trace
1729 if (!LogTraceHitag(tx
, txlen
, HITAG_T_WAIT_2
, 0, true)) {
1730 if (bQuitTraceFull
) {
1731 DbpString("Trace full");
1740 // Reset values for receiving frames
1741 memset(rx
, 0x00, sizeof(rx
));
1745 tag_sof
= reset_sof
;
1748 // Receive frame, watch for at most T0*EOF periods
1749 while (AT91C_BASE_TC1
->TC_CV
< T0
* HITAG_T_WAIT_MAX
) {
1750 // Check if falling edge in tag modulation is detected
1751 if (AT91C_BASE_TC1
->TC_SR
& AT91C_TC_LDRAS
) {
1752 // Retrieve the new timing values
1753 int ra
= (AT91C_BASE_TC1
->TC_RA
/ T0
);
1755 // Reset timer every frame, we have to capture the last edge for timing
1756 AT91C_BASE_TC0
->TC_CCR
= AT91C_TC_SWTRG
;
1760 // Capture tag frame (manchester decoding using only falling edges)
1761 if (ra
>= HITAG_T_EOF
) {
1763 //DbpString("wierd1?");
1765 // Capture the T0 periods that have passed since last communication or field drop (reset)
1766 // We always recieve a 'one' first, which has the falling edge after a half period |-_|
1767 response
= ra
- HITAG_T_TAG_HALF_PERIOD
;
1768 } else if (ra
>= HITAG_T_TAG_CAPTURE_FOUR_HALF
) {
1769 // Manchester coding example |-_|_-|-_| (101)
1770 rx
[rxlen
/ 8] |= 0 << (7 - (rxlen
% 8));
1772 rx
[rxlen
/ 8] |= 1 << (7 - (rxlen
% 8));
1774 } else if (ra
>= HITAG_T_TAG_CAPTURE_THREE_HALF
) {
1775 // Manchester coding example |_-|...|_-|-_| (0...01)
1776 rx
[rxlen
/ 8] |= 0 << (7 - (rxlen
% 8));
1778 // We have to skip this half period at start and add the 'one' the second time
1780 rx
[rxlen
/ 8] |= 1 << (7 - (rxlen
% 8));
1785 } else if (ra
>= HITAG_T_TAG_CAPTURE_TWO_HALF
) {
1786 // Manchester coding example |_-|_-| (00) or |-_|-_| (11)
1788 // Ignore bits that are transmitted during SOF
1791 // bit is same as last bit
1792 rx
[rxlen
/ 8] |= lastbit
<< (7 - (rxlen
% 8));
1796 // Ignore wierd value, is to small to mean anything
1800 // We can break this loop if we received the last bit from a frame
1801 if (AT91C_BASE_TC1
->TC_CV
> T0
* HITAG_T_EOF
) {
1810 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKDIS
;
1811 AT91C_BASE_TC0
->TC_CCR
= AT91C_TC_CLKDIS
;
1812 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
1813 cmd_send(CMD_ACK
, bSuccessful
, 0, 0, 0, 0);
1817 * Tries to authenticate to a Hitag S Transponder with the given challenges from a .cc file.
1818 * Displays all Challenges that failed.
1819 * When collecting Challenges to break the key it is possible that some data
1820 * is not received correctly due to Antenna problems. This function
1821 * detects these challenges.
1823 void check_challenges(bool file_given
, byte_t
* data
) {
1828 byte_t rx
[HITAG_FRAME_LEN
];
1829 byte_t unlocker
[60][8];
1832 byte_t txbuf
[HITAG_FRAME_LEN
];
1839 int t_wait
= HITAG_T_WAIT_MAX
;
1842 bool bQuitTraceFull
= false;
1843 int response_bit
[200];
1844 unsigned char mask
= 1;
1845 unsigned char uid
[32];
1848 FpgaDownloadAndGo(FPGA_BITSTREAM_LF
);
1849 // Reset the return status
1850 bSuccessful
= false;
1852 // Clean up trace and prepare it for storing frames
1857 bQuitTraceFull
= true;
1861 // Configure output and enable pin that is connected to the FPGA (for modulating)
1862 AT91C_BASE_PIOA
->PIO_OER
= GPIO_SSC_DOUT
;
1863 AT91C_BASE_PIOA
->PIO_PER
= GPIO_SSC_DOUT
;
1865 // Set fpga in edge detect with reader field, we can modulate as reader now
1867 FPGA_MAJOR_MODE_LF_EDGE_DETECT
| FPGA_LF_EDGE_DETECT_READER_FIELD
);
1869 // Set Frequency divisor which will drive the FPGA and analog mux selection
1870 FpgaSendCommand(FPGA_CMD_SET_DIVISOR
, 95); //125Khz
1871 SetAdcMuxFor(GPIO_MUXSEL_LOPKD
);
1874 // Disable modulation at default, which means enable the field
1877 // Give it a bit of time for the resonant antenna to settle.
1880 // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering
1881 AT91C_BASE_PMC
->PMC_PCER
= (1 << AT91C_ID_TC0
);
1883 // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the tag frames
1884 AT91C_BASE_PMC
->PMC_PCER
= (1 << AT91C_ID_TC1
);
1885 AT91C_BASE_PIOA
->PIO_BSR
= GPIO_SSC_FRAME
;
1887 // Disable timer during configuration
1888 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKDIS
;
1890 // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
1891 // external trigger rising edge, load RA on falling edge of TIOA.
1892 AT91C_BASE_TC1
->TC_CMR
= AT91C_TC_CLKS_TIMER_DIV1_CLOCK
1894 | AT91C_TC_ETRGEDG_FALLING
| AT91C_TC_ABETRG
| AT91C_TC_LDRA_FALLING
;
1896 // Enable and reset counters
1897 AT91C_BASE_TC0
->TC_CCR
= AT91C_TC_CLKEN
| AT91C_TC_SWTRG
;
1898 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKEN
| AT91C_TC_SWTRG
;
1900 // Reset the received frame, frame count and timing info
1910 DbpString("Loading challenges...");
1911 memcpy((byte_t
*)unlocker
,data
,60*8);
1914 while (file_given
&& !bStop
&& !BUTTON_PRESS()) {
1918 // Check if frame was captured and store it
1922 if (!LogTraceHitag(rx
, rxlen
, response
, 0, false)) {
1923 DbpString("Trace full");
1924 if (bQuitTraceFull
) {
1938 Dbprintf("Challenge failed: %02X %02X %02X %02X %02X %02X %02X %02X",
1939 unlocker
[u1
- 1][0], unlocker
[u1
- 1][1],
1940 unlocker
[u1
- 1][2], unlocker
[u1
- 1][3],
1941 unlocker
[u1
- 1][4], unlocker
[u1
- 1][5],
1942 unlocker
[u1
- 1][6], unlocker
[u1
- 1][7]);
1945 //start new authentication
1946 memcpy(tx
, "\xc0", nbytes(txlen
));
1947 } else if (rxlen
>= 67 && STATE
== 0) {
1950 for (i
= 0; i
< 10; i
++) {
1951 for (j
= 0; j
< 8; j
++) {
1952 response_bit
[z
] = 0;
1953 if ((rx
[i
] & ((mask
<< 7) >> j
)) != 0)
1954 response_bit
[z
] = 1;
1959 for (i
= 5; i
< z
; i
+= 2) {
1960 uid
[k
] = response_bit
[i
];
1965 uid_byte
[0] = (uid
[0] << 7) | (uid
[1] << 6) | (uid
[2] << 5)
1966 | (uid
[3] << 4) | (uid
[4] << 3) | (uid
[5] << 2)
1967 | (uid
[6] << 1) | uid
[7];
1968 uid_byte
[1] = (uid
[8] << 7) | (uid
[9] << 6) | (uid
[10] << 5)
1969 | (uid
[11] << 4) | (uid
[12] << 3) | (uid
[13] << 2)
1970 | (uid
[14] << 1) | uid
[15];
1971 uid_byte
[2] = (uid
[16] << 7) | (uid
[17] << 6) | (uid
[18] << 5)
1972 | (uid
[19] << 4) | (uid
[20] << 3) | (uid
[21] << 2)
1973 | (uid
[22] << 1) | uid
[23];
1974 uid_byte
[3] = (uid
[24] << 7) | (uid
[25] << 6) | (uid
[26] << 5)
1975 | (uid
[27] << 4) | (uid
[28] << 3) | (uid
[29] << 2)
1976 | (uid
[30] << 1) | uid
[31];
1977 //Dbhexdump(10, rx, rxlen);
1981 calc_crc(&crc
, 0x00, 5);
1982 calc_crc(&crc
, uid_byte
[0], 8);
1983 calc_crc(&crc
, uid_byte
[1], 8);
1984 calc_crc(&crc
, uid_byte
[2], 8);
1985 calc_crc(&crc
, uid_byte
[3], 8);
1986 for (i
= 0; i
< 100; i
++) {
1987 response_bit
[i
] = 0;
1989 for (i
= 0; i
< 5; i
++) {
1990 response_bit
[i
] = 0;
1992 for (i
= 5; i
< 37; i
++) {
1993 response_bit
[i
] = uid
[i
- 5];
1995 for (j
= 0; j
< 8; j
++) {
1996 response_bit
[i
] = 0;
1997 if ((crc
& ((mask
<< 7) >> j
)) != 0)
1998 response_bit
[i
] = 1;
2002 for (i
= 0; i
< 6; i
++) {
2003 tx
[i
] = (response_bit
[k
] << 7) | (response_bit
[k
+ 1] << 6)
2004 | (response_bit
[k
+ 2] << 5)
2005 | (response_bit
[k
+ 3] << 4)
2006 | (response_bit
[k
+ 4] << 3)
2007 | (response_bit
[k
+ 5] << 2)
2008 | (response_bit
[k
+ 6] << 1) | response_bit
[k
+ 7];
2012 } else if (STATE
== 1 && rxlen
== 44) {
2013 //received configuration
2016 for (i
= 0; i
< 6; i
++) {
2017 for (j
= 0; j
< 8; j
++) {
2018 response_bit
[z
] = 0;
2019 if ((rx
[i
] & ((mask
<< 7) >> j
)) != 0)
2020 response_bit
[z
] = 1;
2026 if (u1
>= (sizeof(unlocker
) / sizeof(unlocker
[0])))
2028 for (i
= 0; i
< 8; i
++)
2029 tx
[i
] = unlocker
[u1
][i
];
2032 } else if (STATE
== 2 && rxlen
>= 44) {
2036 // Send and store the reader command
2037 // Disable timer 1 with external trigger to avoid triggers during our own modulation
2038 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKDIS
;
2040 // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting,
2041 // Since the clock counts since the last falling edge, a 'one' means that the
2042 // falling edge occured halfway the period. with respect to this falling edge,
2043 // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
2044 // All timer values are in terms of T0 units
2046 while (AT91C_BASE_TC0
->TC_CV
2047 < T0
* (t_wait
+ (HITAG_T_TAG_HALF_PERIOD
* lastbit
)))
2050 // Transmit the reader frame
2051 hitag_reader_send_frame(tx
, txlen
);
2053 // Enable and reset external trigger in timer for capturing future frames
2054 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKEN
| AT91C_TC_SWTRG
;
2056 // Add transmitted frame to total count
2060 // Store the frame in the trace
2061 if (!LogTraceHitag(tx
, txlen
, HITAG_T_WAIT_2
, 0, true)) {
2062 if (bQuitTraceFull
) {
2063 DbpString("Trace full");
2072 // Reset values for receiving frames
2073 memset(rx
, 0x00, sizeof(rx
));
2077 tag_sof
= reset_sof
;
2080 // Receive frame, watch for at most T0*EOF periods
2081 while (AT91C_BASE_TC1
->TC_CV
< T0
* HITAG_T_WAIT_MAX
) {
2082 // Check if falling edge in tag modulation is detected
2083 if (AT91C_BASE_TC1
->TC_SR
& AT91C_TC_LDRAS
) {
2084 // Retrieve the new timing values
2085 int ra
= (AT91C_BASE_TC1
->TC_RA
/ T0
);
2087 // Reset timer every frame, we have to capture the last edge for timing
2088 AT91C_BASE_TC0
->TC_CCR
= AT91C_TC_SWTRG
;
2092 // Capture tag frame (manchester decoding using only falling edges)
2093 if (ra
>= HITAG_T_EOF
) {
2095 //DbpString("wierd1?");
2097 // Capture the T0 periods that have passed since last communication or field drop (reset)
2098 // We always recieve a 'one' first, which has the falling edge after a half period |-_|
2099 response
= ra
- HITAG_T_TAG_HALF_PERIOD
;
2100 } else if (ra
>= HITAG_T_TAG_CAPTURE_FOUR_HALF
) {
2101 // Manchester coding example |-_|_-|-_| (101)
2102 rx
[rxlen
/ 8] |= 0 << (7 - (rxlen
% 8));
2104 rx
[rxlen
/ 8] |= 1 << (7 - (rxlen
% 8));
2106 } else if (ra
>= HITAG_T_TAG_CAPTURE_THREE_HALF
) {
2107 // Manchester coding example |_-|...|_-|-_| (0...01)
2108 rx
[rxlen
/ 8] |= 0 << (7 - (rxlen
% 8));
2110 // We have to skip this half period at start and add the 'one' the second time
2112 rx
[rxlen
/ 8] |= 1 << (7 - (rxlen
% 8));
2117 } else if (ra
>= HITAG_T_TAG_CAPTURE_TWO_HALF
) {
2118 // Manchester coding example |_-|_-| (00) or |-_|-_| (11)
2120 // Ignore bits that are transmitted during SOF
2123 // bit is same as last bit
2124 rx
[rxlen
/ 8] |= lastbit
<< (7 - (rxlen
% 8));
2128 // Ignore wierd value, is to small to mean anything
2132 // We can break this loop if we received the last bit from a frame
2133 if (AT91C_BASE_TC1
->TC_CV
> T0
* HITAG_T_EOF
) {
2141 AT91C_BASE_TC1
->TC_CCR
= AT91C_TC_CLKDIS
;
2142 AT91C_BASE_TC0
->TC_CCR
= AT91C_TC_CLKDIS
;
2143 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
2144 cmd_send(CMD_ACK
, bSuccessful
, 0, 0, 0, 0);