So do please start a new thread. This way it will be easier to follow.
]]>btw: I found some funny facts about the advant stuff we writte about in the other thread. Would it be of any interest to make a new thread about advant where a start to write the "known facts" about it, as some kind of a starting point for further attacs?
]]>and thanks for the heads-up on crc4 calc. I'll take a look at it.
]]>And for the CRC: You are right, the LegicCRC8 routine is working, but the raw data pakets are checked by a 4 bit CRC. This routine will do the job:
/* calculate crc for a legic command */
static int LegicCRC(int byte_index, int value, int cmd_sz) {
crc_clear(&legic_crc);
crc_update(&legic_crc, 1, 1); /* CMD_READ */
crc_update(&legic_crc, byte_index, cmd_sz-1);
crc_update(&legic_crc, value, 8);
return crc_finish(&legic_crc);
}
... i tried to fix this, but I had no luck. What I noticed while tracing both (old and your new) variants line by line: The new code have some trouble with bit based calculations as shown above. I always get false results this way. Pumping for example complete bytes (8 bit) the routine (the new one) work fine.
Since I don't have more time currently I stopped here for now... I just want to let you know about this.
The 0x07 >> 4 will always clear it out. Are you sure this shift is correct?
[edit]
Found other place, the correct mask is 0x70 >> 4, fix pushed to repo.
The crc8legic should be the same still after my changes. Ive tested against UID and what the MCC should be. So that is a strange one.
Easy to test, 'hf legic crc b uidbytes' should give you the correcct mcc
pm3 --> hf legic crc h
Calculates the legic crc8/crc16 on the input hexbytes.
There must be an even number of hexsymbols as input.
Usage: hf legic crc8 [h] b <hexbytes> u <uidcrc> c <crc type>
Options:
b <hexbytes> : hex bytes
u <uidcrc> : MCC hexbyte
c <crc type> : 8|16 bit crc size
Samples:
hf legic crc8 b deadbeef1122
hf legic crc8 b deadbeef1122 u 9A c 16
pm3 -->
edit:
I think the crc is ok, its the data fetching from the device which brings zero, which makes all crc calcs wrong.
I compiled your fork and flashed it to my PM3... but something is screwed up. I always get CRC erros on reading a card:
#db# setting up legic card
#db# MIM256 card found, reading card ...
#db# !!! crc mismatch: expected c but got e !!!
#db# operation aborted
I've reverted your changes done on the CRC routines (replaced LegicCRC8) but this gives no better results. I didn't go any deeper yet, since I don't ave enought time today. But for now I can say: The current implementation breaks the Legic stuff.
I will go deeper in this issue this week (maybe already tomorror).
Edit:
Ohh... I just reviewed your CRC code changes in a too fast way: After reverting the changed to crc_update too, the legic reading works. But as I stated in the post above: "hf legic decode" gives just zero-values:
pm3 --> hf legic decode
CDF: System Area
------------------------------------------------------
MCD: 00, MSN: 00 00 00, MCC: 00 Fail
DCF: 0 (00 00), Token Type=IM (OLE=0)
ADF: User Area
------------------------------------------------------
Unsegmented card - WRP: 00, WRC: 00, RD: 0
Remaining segment payload: (I 8 | Remain LEN 1002)
row | data
-----+------------------------------------------------
[00] | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[01] | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[02] | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[03] | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
(...)
The GetEMLFromBigBuf needs to be GetFromBigBuf (I din't go any deeped in the difference yet... I'm new to PM3, I have to learn a lot about the routines available )
Your CRC changes screwed up the CRC calculation, maybe the changed POLY is wrong or the reflect-stuff will break correct calculation.
]]>I tried to get ride of the old BigBuff handeling in the legic code, its not changed to deal with how the bigbuffer can be used today (or since a year back when Piwi re-wrote it)
]]>Linle 71 of cmdhflegic.c:
GetEMLFromBigBuf(data_buf, sizeof(data_buf), 0);
I changed this to GetFromBigBuf, since I got not data (read before) in the buffer... it was just filled with zeros that way. On Monday I will check the firmware running on a PM3.
btw I saw you added your reworked code for signal interpretation. I will take a closer look next week on this... hmmm... I didn't take a closer look yet, but would it be possible the processor is slightly to slow for this kind of code?
]]>... btw: I will post some data from Legic advant media in the other thread in the next few minutes
]]>[edit] nop, you changed some more. I think I got your changes now into my fork. Haven't tested them yet
]]>unfortunately I won't download packages, that contain binaries from insecure sources ( yes I'm sometimes kind of paranoid )
Oh, this is not paranoid I use to run unknown code always in VMs where all changes are lost in space on closing them Safty first...
Anyway: You could compile the source on Linux, this works. I did it in a VM for the first time.
CRC16 on Legic Prime Data Segments?
Yes! ... what you talking about is the successor of the simple LRC from low-level communication with official Legic reader modules/chips. The older advant 2000 series have both choices: LRC and CRC. The 4000 series only CRC.
The 0x0000-Statement doesn't work, yes. This only worked the first few (beta) releases. Some day they realized a such fucking MCU have problems with CRC calculation will mess up more things than just the communication...
Anyway: You can use two kinds of CRCs in data segments. 8-bit and 16-bit. This is couz of the reason a larger data chunk is not really well protected with a 8 bit CRC - there could be a couple of bit flips giving the same result, this risk will be even higher on larger data chunks. The crc16 is no new stuff, it exits for a long time now... I think even SM-05 modules are able to handle this (should I verify next time...). This have nothing to do with advant.
but it would have helped if you used the github for this
You are right I'm so sorry! I'm some kind of a old shool SVN user I never tried to get in touch with GIT. I used WinMerge to merge your sources with Icsom's, so I was able to modify it on the way directly in this editor. So there was no need for versioning stuff for me. I maybe should give GIT a try some day
Regarding crc16 on data segments, can you give me a complete datasegment with crc in it and the UID+uidcrc.
Of course: Freshly generated with a demo GAM:
RAW data:
40 f2 48 fc ed 60 ea 9f
ff 00 00 00 11 01 21 80
08 40 2a c1 00 00 cc 2d
e4 ad 92 ed ec ef ee ff
d9 bb 40 87 c8 11 3a b7
a9 8b 35 e1 46 35 ed ed
ed ed ed ed ed ed ed 00
00 00 00 00 00 00 00 00
(I stripped the unused area)
And the decoded data:
CDF: System Area
------------------------------------------------------
MCD: 40, MSN: f2 48 fc, MCC: ed OK
DCF: 60000 (60 ea), Token Type=IM-S (OLE=0)
WRP=15, WRC=1, RD=1, SSC=ff
Remaining Header Area
00 00 00 11 01 21 80 08 40 2A C1 00 00
ADF: User Area
------------------------------------------------------
Segment 01
raw header | 0x21 0xC0 0x09 0x40
Segment len: 33, Flag: 0xC (valid:1, last:1), WRP: 09, WRC: 04, RD: 0, CRC: 0x7F (OK)
WRC protected area: (I 27 | K 0 | WRC 4)
row | data
-----+------------------------------------------------
[00] | 00 01 02 03
Remaining write protected area: (I 31 | K 31 | WRC 4 | WRP 9 WRP_LEN 5)
row | data
-----+------------------------------------------------
[00] | 12 34 56 AD 6A
Remaining segment payload: (I 36 | K 36 | Remain LEN 19)
row | data
-----+------------------------------------------------
[00] | 25 FC D7 5A 44 66 D8 0C AB D8 00 00 00 00 00 00
[01] | 00 00 00
-----+------------------------------------------------
(by the way I found the "decode" function will not put the hex-bytes in the log... something to fix for me )
I added a well known KGH, expect the fact I used a crc16 instead of crc8. This crc16 are the last 2 bytes after the BCD encoded card number (AD-6A), I expluded WRC/WRP/RD flag in calculation (so it's just UID, stamp and card number 123456). Than I added some random data and put another crc16: AB-D8.
]]>Maybe we start to find the parameters for CRC16 mode of data segments now?
CRC16 on Legic Prime Data Segments?
Have never seen those ... on all Tags I have seen CRC8 was used only.
CRC16 was only used for Transport (consistency check) between Host and Security-Module and that is a ordinary CRC-CCIT (CRC16) but you can set it to 0x0000, then it will be ignored by the security-module.
from the documentation:
If a host system is not able to calculate a 16 bit CRC (e.g. low performance CPU), the CRC value in the command
can be set to 0x0000. In this case, the CRC is ignored by the SM-4200 and no consistency check is performed.
As an alternative, the CRC value can be calculated in advance and added to the command as a static number.
The answer of the SM-4200 always contains a CRC value.
unsigned int CRC16(unsigned char * p, int n)
{
int i;
int k;
unsigned int polynom = 0x8408;
unsigned int crc = 0xFFFF;
for (i = 0; i < n; i++)
{
crc ^= p[i];
for (k = 0; k < 8; k++)
{
// CCITT
// inital value
if(crc&1) crc=(crc>>1)^polynom;
else crc = crc >> 1;
}
}
return crc;
}