Research, development and trades concerning the powerful Proxmark3 device.
Remember; sharing is caring. Bring something back to the community.
"Learn the tools of the trade the hard way." +Fravia
You are not logged in.
Time changes and with it the technology
Proxmark3 @ discord
Users of this forum, please be aware that information stored on this site is not private.
This post is about getting deep into understanding the iClass signalry and PM3' arm-fpga. Its my way to trying to understand and let others learn.
ref: DS Picopass 2KS V1-0.pdf http://www.proxmark.org/files/Documents … 20V1-0.pdf
ref: iclass.c https://github.com/Proxmark/proxmark3/b … c/iclass.c
So currently the iClass implements ISO15693 protocoll,
Reader to chip communication is:
Coding 1 out of 4, (defines two bits at one time)
Coding 1 out of 256
Chip to reader communication is:
manchester
According to the datasheet page 52, the communication is based upon the following,
Start-Of-Frame (SOF) - dataframe (DF) - End-Of-Frame (EOF)
SOF takes 75.52 us
DF takes 75.52 us
EOF takes 35.76 us
The transfer is done LSB (remember this)
Datasheet page 51
-- 1 out of 4 coding (Reader to chip) defines two bits at one time, in one frame.
bit| signal (in 1 frame)
---+--------------------
00 | 10 11 11 11
01 | 11 10 11 11
10 | 11 11 10 11
11 | 11 11 11 10
The signal breaks down to one bit == 9.44us, (8 bits * 9.44 == 75.52us)
1 = modulation
0 = no modulation
Using this lookup table above, we take an sample
-- sample sending 0xE1 ( 1110 0001 -> 11 10 00 01 -->(lsb) 10 00 01 11)
LSB first:
10 00 01 11
11 11 10 11 - 10 11 11 11 - 11 10 11 11 - 11 11 11 10
All well so far, so what about SOF and EOF ? It turns out they don't have the same frame length (!?!) and they look like this.
SOF takes 75.52us 01 11 10 11
EOF takes 37.76us 11 01
Now with SOF - DF - EOF it would look like
|---SOF---| |---------Data frame 0xE1---------------------| |EOF|
01 11 10 11 11 11 10 11 10 11 11 11 11 10 11 11 11 11 11 10 11 01
Back to PM3 and SNIFFING.
When reading signals from antenna we use the following modes, which might be a surprise
FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER
Since we are looking at ISO15693, but the answers for this lays in the fpga-code. (to be written)
The signal is collected in DMA buffers, which we reserve space in BigBuffer.
The DMA buffer is only 128 bytes long. From this we pop the collected signal into the OutOfNDecoding() function, which is responsible for the decoding of the collected signal data when it comes from Reader-To-Chip communcation.
Converting : 01 11 10 11 11 11 10 11 10 11 11 11 11 10 11 11 11 11 11 10 11 01 into 0xE1
This is the black magic, need to verify signal and the decoding...
...to be done...
Offline
FPGA -> ARM when sniffing...
ref: https://github.com/Proxmark/proxmark3/b … so14443a.v
Lets see what is it we are getting from the FPGA?
This part defines when we collect data.
https://github.com/Proxmark/proxmark3/b … 43a.v#L198
if (mod_type == `SNIFFER)
begin
// detect a rising edge of reader's signal and sync modulation detector to the tag's answer:
if (~pre_after_hysteresis && after_hysteresis && deep_modulation)
// reader signal rising edge detected at negedge_cnt[3:0]. This signal had been delayed
// 9 ticks by the RF part + 3 ticks by the A/D converter + 1 tick to assign to after_hysteresis.
// Then the same as above.
// - 9 - 3 - 1 + 4 + 3 + 7 - 4 = -3
begin
mod_detect_reset_time <= negedge_cnt[3:0] - 4'd3;
end
end
Next part is more interesting in that sense, we get to know we collecting 4bits from reader and 4bits from tag, when sniffing.
https://github.com/Proxmark/proxmark3/b … 43a.v#L255
question, what does this 4bits actually mean? Is it ONE bit of information in the communication?
No, it is four bits of the sampled signal in four sample occasions.
We see how
one bit (after_hysteresis) of reader data is shifted into the 4bits at every sample occasion
one bit (curbit) of tag data is shifted into the 4bits at every sample occasion
// Tag+Reader -> PM3
// sample 4 bits reader data and 4 bits tag data for sniffing
reg [3:0] reader_data;
reg [3:0] tag_data;
always @(negedge adc_clk)
begin
if(negedge_cnt[3:0] == 4'd0)
begin
reader_data[3:0] <= {reader_data[2:0], after_hysteresis};
tag_data[3:0] <= {tag_data[2:0], curbit};
end
end
This part tells use exact which data we collect. When reader data, the low nibble is all zero (ie tag data empty),
And with tagdata, we get both reader & tag data in the byte.
https://github.com/Proxmark/proxmark3/b … 43a.v#L429
if (mod_type == `SNIFFER)
begin
if(deep_modulation) // a reader is sending (or there's no field at all)
begin
to_arm <= {reader_data[3:0], 4'b0000}; // don't send tag data
end
else
begin
to_arm <= {reader_data[3:0], tag_data[3:0]};
end
end
https://github.com/Proxmark/proxmark3/b … 43a.v#L537
here you see sniffed data gets hook onto bit_to_arm,
https://github.com/Proxmark/proxmark3/b … 43a.v#L551
here you see ssp_din gets assign the sniffed data.
Now we have gotten one byte of data,
HIGH nibble is reader related communication
LOW nibble is tag related communication
However it now make sense what you see here, this below is from ISO14443a part hf 14a sniff but shows more clear the HIGH/LOW nibble data.
https://github.com/Proxmark/proxmark3/b … 43a.c#L679
if(!TagIsActive) { // no need to try decoding reader data if the tag is sending
uint8_t readerdata = (previous_data & 0xF0) | (*data >> 4);
if (MillerDecoding(readerdata, (rsamples-1)*4)) {
the variable Readerdata now contains 8bits of sniffed reader communication. previous HIGHnibble and current HIGH, which all gets feed into the MillerDecoding.
Offline
So, I modified 'hf iclass sniff' to output some more data. The trace is here: https://pastebin.com/Dru2WPMA
So this is the collected reader signal, each byte is HIGH nibble from two samples.
#db# reader:
#db# ff ff ff ff ff ff ff ff
#db# ff ff ff ff ff ff ff ff
#db# ff ff ff ff ff ff ff ff
#db# ff ff ff ff ff ff f0 00
#db# 00 00 00 00 00 00 00 00
#db# 00 00 00 00 00 00 0f 3b
#db# 00 f0 b0 00 00 00 00 00
#db# 00 00 00 00 00 00 03 10
#db# 00 00 00 00 00 00 06 00
#db# 0a f2 00 00 00 00 00 00
To start with basic RFID, reader 99% of the time speaks first. This is not the case with active tag, the ones with their own power source but that is another story for now.
iClass readers always begins with the command ACT_ALL == 0xA but the HIGH nibble consists of some parity and other options.
remember all communication is in LSB. The reader also expects card answer 350us afterwards.
I.e A = 1010, plus parity = 1+1=0, == 0x0A = 0000 1010 --> LSB( 0101 0000) (0x50)
Lets take the first bytes which looks like a reader message:
0F 3B 00 F0 B0 [0000 1111 0011 1011 0000 0000 1111 0000 1011]
What could this be? remember SOF [0111 1011] and EOF [1101]
00 00 11 11 00 11 10 11 00 00 00 00 11 11 00 00 10 11
01 11 10 11 11 01
No, that doesn't match up quite. the SOF misses one bit, and the EOF is reversed. we can't see any 0x0A either..
Next bytes that looks like something, the 0x0A is there but no SOF or EOF.
----------
Looking at a TAG response to 0x0A, then it should be manchester encoded.
10 = 0
01 = 1
06 00 0A F2 00 = 00 00 01 10 00 00 00 00 00 00 10 10 11 11 00 10 00 00 00 00
1 0 - - - - -
this doesn't match up at all..
What to conclude for now, I must have missunderstood the FPGA signal data. Back to the source code to figure out whats wrong.
Offline
Now, looking at the OutOfNDecodingfunction (softwarebased UART) and sniffer function again
// FOR READER SIDE COMMUMICATION...
decbyter <<= 2;
decbyter ^= (smpl & 0x30);
div++;
if((div + 1) % 2 == 0) {
smpl = decbyter;
if(OutOfNDecoding((smpl & 0xF0) >> 4))
smpl == SAMPLE byte from FPGA.
decbyter = decode byte for reader.
Generally it calls OutOfNDecoding every other byte, [see mod 2 (% 2)], which would match up with the 4bits of data from fpga on every byte but the leftshift two times and xor the lower 00xx0000 part doesn't make sense.
Its like it only wants to take the lower 2 bits of the 4bits sample.. If you use 2bits, you would need 4 loops to get 1 byte.
Now its more 2bits and 2loops generating a xx00xx00 byte. Has this something to do with sample rate?
Taking the above sample data
0F 3B 00 F0 B0 [0000 1111 0011 1011 0000 0000 1111 0000 1011]
and remove higher 2bits in every nibble
[00 11 11 11 00 00 11 00 11]
rearrange it
[001111110000110011]
Still no match of the following
SO 01111011
0x0A 01010000
EOF 1101
Offline