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.
I've been researching why iclass tag simulation fails. This topic maybe should have been under iclass, but I have also had problems simulating mifare-tags against certain readers (especially with the latest fpga-revisions), and I have a feeling there may be similar issues there, which I've yet to investigate.
How I have done:
1. Using an omnikey reader (set to iclass reading only). Above that, a pm3 antenna, to which I've hooked up an oscilloscope. Above that a legit iclass tag.
2. Using an omnikey reader, above that a pm3 antenna connected to oscilloscope. Above that, a second antenna connected to the pm3. The pm3 was set to 'hf sim iclas...'. I used the latest git version, with one modification: lighting LED_C when the pm3 received signals from the reader. This was to get a trigger for the oscilloscope. So one channel on the scope was measuring the LED_C voltage.
(although, I'm not yet a 'scope' wiz, so I didn't manage to trigger on that. Instead I just fired blindly a few times and captured it anyway. The scope has pretty good sample memory, so it worked ok).
carl55 did some similar measurements a while back, you can check his results here: http://www.proxclone.com/pdfs/iclass_id … timing.pdf
So, my results so far..
Here we see the legit reader and legit tag. Unfortunately, I made a bad screenshot which does not properly show the measures. But each grid is 100us, so it's around 340us between end of reader transmission and tag SOF.
On the image below, I've zoomed in on the tag SOF. It clearly shows the 24 peaks. Each grid is 10us.
Here you can see what the ISO-15693 specification SOF looks like. 24 pulses followed by a zero-period, then 8 more pulses.
Here is a snapshot of a 8 modulations. Shows a modulated "0". 8 pulses within 18.88 us, total length 37.76 us. Measured length: 38us - which is within the margin of error.
And this is the spec:
So, that's the background. Let's look at how the pm3 behaves in tag mode. (The blue is the signal, and the yellow my oscilloscope trigger attempt)
Simulated tag, legit reader. The time before SOF is 280 us. This is a bit faster than the legit tag (which was ~340), but should be easy to fix:
Here we see the timing of the latter part of the SOF. The time should be 56.64 us (see spec above). Measured: 57 us. Within margin of error.
This picture hows the SOF ones in more details: measured time 56.40 us. But... There should be 24 peaks, shows 48 peaks. The timing seems correct, but the frequency of the modulated signal appears doubled. Compare with the legit SOF above with its 24 peaks.
Here we look at the end part of the tag SOF. Shows the end of SOF. Time should be 37.76us, measured 37.40 us. 16 peaks, should be 8. Frequency is doubled.
So, to conclude... The modulation frequency is doubled. The timings are correct, but something is way wrong.. When sending a SOF, 24 1-bits are placed in ToSend, but somehow each of those ones becomes two peaks - I have the feeling that whatever component is responsible for shifting in the next bit uses the correct frequency (thus the total length's are correct) but whatever component transmits them on the air uses double frequency.
EDIT: edited for clarity
Last edited by holiman (2014-05-10 23:25:12)
Offline
The questions is, wether iClass is ISO14443A or ISO15693.
iClass.c uses FPGA_HF_ISO14443A_TAGSIM_MOD in SendIClassAnswer(). The subcarrier frequency for ISO14443A is fc/16, for ISO-15693 it is fc/32. Therefore the doubled number of pulses.
In iso15693.c TransmitTo15693Reader() uses another FPGA mode (FPGA_MAJOR_MODE_HF_SIMULATOR), which should give you the correct subcarrier frequency.
Offline
Might want to check this out: http://rsmart.com.cn/datasheet/chip_cl/Picopass.pdf
I have never looked in to the FPGA but I'm guessing you'll have to stick with fc/32.
Offline
15693 it is, indeed. However, I can't quite make it work.
Using the same as iso15693.c:
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR);
This yields no modulation, which is explained by looking at the fpga-code https://github.com/Proxmark/proxmark3/blob/master/fpga/hi_simulate.v:
// Modulating carrier frequency is fc/16, reuse ssp_clk divider for that
reg modulating_carrier;
always @(mod_type or ssp_clk or ssp_dout)
if(mod_type == 3'b000)
modulating_carrier <= 1'b0; // no modulation
else if(mod_type == 3'b001)
modulating_carrier <= ssp_dout ^ ssp_clk_divider[3]; // XOR means BPSK
else if(mod_type == 3'b010)
modulating_carrier <= ssp_dout & ssp_clk_divider[5]; // switch 212kHz subcarrier on/off
else
modulating_carrier <= 1'b0; // yet unused
// This one is all LF, so doesn't matter
assign pwr_oe2 = modulating_carrier;
// Toggle only one of these, since we are already producing much deeper
// modulation than a real tag would.
assign pwr_oe1 = modulating_carrier;
assign pwr_oe4 = modulating_carrier;
I also tested
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR|FPGA_HF_SIMULATOR_MODULATE_212K);
This yields half the frequency (as could be expected). So, 24 SOF peaks (correct) but over 110us (instead of 56us). I haven't tested the BPSK option, because there is no phase shift keying going on here and the frequency of that can't be right either, so I don't feel any need to even test that.
I've not yet written a line of verilog in my life, but I believe something like this is needed:
else of(mod_type == 3'b100)
modulating_carrier <= ssp_dout & ssp_clk_divider[4];
Alternatively:
else of(mod_type == 3'b100)
modulating_carrier <= ssp_dout & ssp_clk;
And then we'll need to define another option in apps.h:
#define FPGA_HF_SIMULATOR_MODULATE_424K (4<<0)
amirite?
Offline
Oh, and if this looks right, could someone please build me an fpga-image to test that with? It'd be appreciated...
Offline
holiman
Yes, you are right. 13.56 mhz/32=424 khz
Unfortunately, I can't build fpga image because I'm far away from my PC. You can download Xilinx tools 10.1 from torrents.
Also have a look at new ISO15693 sim code:
https://github.com/douniwan5788/proxmark3/tree/newWorking15693sim
Offline
i built it with 10.1, man that was annoying... glad i moved to 11+
fpga.bit is the first one, fpga_alt.bit is the alternative one, fpga_ori.bit is the current code in github just to verify i built it ok.
http://www.goth.am/proxmark/
Offline
HA!
@vivat, that's hilarious : one month ago, you committed this into your branch:
else if(mod_type == 3'b100)
modulating_carrier <= ssp_dout & ssp_clk_divider[4]; // switch 423kHz subcarrier on/off
How close are you to having the code stable enough to submit to main?
@charliex, thanks a lot!
Last edited by holiman (2014-05-13 20:40:13)
Offline
np, lemme know if you need a rev. i'll be around.
Offline
It's all Radiowar's commits.
Offline
Funny. With the patch, I get the correct modulation frequency.. But now there's still 48 peaks where there should be 24 .. over double the time, of course. It's like I took the screenshots from above and just expanded them to the correct frequency... progressing sideways here..
Offline
In commit fdcd43eb15 I see:
static void CodeIClassTagAnswer(const uint8_t *cmd, int len)
{
int i;
ToSendReset();
// Send SOF
ToSend[++ToSendMax] = 0x00;
ToSend[++ToSendMax] = 0x00;
ToSend[++ToSendMax] = 0x00;
ToSend[++ToSendMax] = 0xff;//
ToSend[++ToSendMax] = 0xff;//48 peaks
ToSend[++ToSendMax] = 0xff;//
ToSend[++ToSendMax] = 0x00;
ToSend[++ToSendMax] = 0xff;
...
That's why you get 48 peaks
Offline
Hm. I don't see..
0xff = 1111 1111 == 8 peaks?
Should be 24 afaict... ?
Offline
I'm getting ok with reading verilog code, and have a grip on that. But I don't see where ssp_dout comes from. It is an input to the fpga, through fpga.v it is passed to e.g. the hi_simulate logic. But what code is responsible for toggling that at the correct time, setting receive-ready register on the ARM?
Offline
I think I understand the issue now. Somehow, (still unclear to me), the next byte is sent from ARM to FPGA whenever ssp_frame is set to 1.
We have a clock (ssp_clk) which toggles every f/32, that is, toggling with 424KHz frequency.
The ssp_frame is set to one every time a counter counts to 8 (overflows to zero). That means the current byte is finished,
time to get the next.
The counter, however, only increases at negedge. So if the ssp_clk toggles: 01010101 (8 toggles), there are only half as many negedges. Every other toggle is a posedge.
reg [2:0] ssp_frame_divider_to_arm;
always @(posedge ssp_clk)
ssp_frame_divider_to_arm <= (ssp_frame_divider_to_arm + 1);
reg [2:0] ssp_frame_divider_from_arm;
always @(negedge ssp_clk)
ssp_frame_divider_from_arm <= (ssp_frame_divider_from_arm + 1);
reg ssp_frame;
always @(ssp_frame_divider_to_arm or ssp_frame_divider_from_arm or mod_type)
if(mod_type == 3'b000) // not modulating, so listening, to ARM
ssp_frame = (ssp_frame_divider_to_arm == 3'b000);
else
ssp_frame = (ssp_frame_divider_from_arm == 3'b000);
This can be changed in different ways, but the code is written to accommodate other clocks. Afacit, changing this behaviour would affect legicrf-simulation and possibly iso14443. References in codebase:
#ack-grep FPGA_MAJOR_MODE_HF_SIMULATOR
armsrc/iso14443.c
297: FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
404: FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK);
armsrc/legicrf.c
692: FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_212K);
armsrc/iso15693.c
269: FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR); // No requirement to energise my coils
armsrc/apps.h
87:#define FPGA_MAJOR_MODE_HF_SIMULATOR (4<<5)
armsrc/iclass.c
1233: FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR|FPGA_HF_SIMULATOR_MODULATE_424K);
Offline
ssp_clk is either derived from the 13.56mhz xtal with a divider, or the 24mhz PCK0 from the ARM (lf) the frame marks the start of the data, then ssp_clk tells the arm when to sample the data line out,. typically we only care about posedge or negedge as the transition, or whatevers on the data line at the transition. hopefully i understood what you were looking for.
Offline
I was wrong above, it is correct behaviour to only count at negedges. A bit isn't transmitted until a nededge occurs. But something is still fishy...
@charliex thanks. But: "sample data line out" ? That's for receiving, right? In my case, the ARM is trying to send data (as tag) to the FPGA. I'm interested in the mechanics that make allow the ARM to send the next byte, or actually, the mechanics that make the FPGA toggle to next byte. Since I'm seeing double the number of bits/bytes over the air, my theory is that the byte-swapping uses the wrong timer, somehow.
I've seen there's a debug pin on the board, connected to the FPGA debug out. I'll try to use that to see what gets signalled.
Offline
While peeking around, it strikes me that there are more things we could do on the FPGA-side. For example, modulation.
The iso15693 tag->reader has a pretty simple coding scheme, where each 18.88us timeslot is either a series of pulses or zero.
So the SOF could for example be described as 00011101, if each 1 is encoded into 18.88 us slot with 8 pulses.
A binary one would be encoded "01" or "10" (I don't remember which) by the ARM.
Is there any disadvantage in putting that encoding into the FPGA instead?
For example
- "Yes, we're on the limit of what we can cram into the FPGA already"
- "Yes, that's not how we do things"
It would decrease the complexity of the ARM code a bit, but that particular mode couldn't be reused for other purposes, being a special iso 15693 mode.
EDIT: more example
Last edited by holiman (2014-05-16 08:46:13)
Offline
Nope, as far as I see there is no disadvantage to also interpret comparable encoding schemes like Manchester, except when you really want to dump/investigate the demodulated signal, in stead of decoded signals. However, many DSP's support decoding as well as demodulation before delivering it to a micro-controller.
Offline
More specific questions related to arm<-> communication :
What fpga-operation flags the RXRDY-flag in the status register?
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY))
What fpga-operation flags the TXRDY-flag in the status register ?
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))
Specifically, what fpga output wire(s) are involved ?
Offline
The arm communicates almost like SPI ( we changed ours in the STM32 to actually be SPI )
Frame is just that it 'frames' the communication, it basically says, i expect 8 or 16 bits of data, a short time after the leading edge of SSP_FRAME, the SSP_CLK is how it knows when the data on dout/din is valid, so on a high clock+transition time it samples SSP_DIN or DOUT depending on whos the master/slave
in lo_read.v
// example of ssp transfer of binary value 1100101
// start of transfer is indicated by the rise of the ssp_frame signal
// ssp_din changes on the rising edge of the ssp_clk clock and is clocked into
// the ARM by the falling edge of ssp_clk
// __________________
// ssp_frame__| |__
// _____ ___ ___
// ssp_din __| |_______| |___| |______
// _ _ _ _ _ _ _ _ _ _
// ssp_clk |_| |_| |_| |_| |_| |_| |_| |_| |_| |_
SSC_RXRDY gets flagged when right number of bits have been clocked in since the start of frame.
Last edited by charliex (2014-05-16 17:51:39)
Offline
Thanks for explaining.
I wanted to see if the error was "double bits" or "double bytes". Double bits would mean that each bit was modulated into two peaks, double bytes would mean that framing was wrong, and that each byte was transmitted twice. So, I tested changing the SOF, instead of FF,FF,FF, I sent FF, 5F, FF. The 5 is in binary 0101.
Here's the result:
As you can see, there's first 16 peaks, then the cursors are around the 5F-section. The marked area is "0101111101011111" == 5F5F. Apparently, the byte 5F is used twice, but individual bits are modulated correctly. So, it's the framing that's off. I'm downloading xilinx suite now, to get down to business with the fpga and be able to run some tests on the verilog code.
EDITed for clarity
Last edited by holiman (2014-05-17 20:33:52)
Offline
I've spent a lot of time now trying to get xilinx to work. After failing linux64, trying opensuse64+32compat, windows virtual (not enough space, the thing requires 15 G) and finally succeeding in installing it on ubuntu 64-bit, but failing to simulate simple verilog code AND crashing the system, I have given up on it.
However, iverilog + gtkwave works perfectly for verilog simulation. Really nice! Since I've given up on emulating the entire flow, however, I'd like to be able to compile (synthesize?) the fgpa-code into the final fpagimage.
So, first question: What is the absolute minimum I need to do/install/configure in order to do a "make fpga", or whatever the command is?
Second question: the dependencies which make ARM spit out another byte at the ssp_frame signal, that must be implemented in code somewhere... Where is that? Or is that a physical connection on the board?
Offline
i havent installed ISE on linux yet, but on windows, grab 10.1 webpack and install it, generate a webpack license and run the batch file, it should be very similar for linux.
PCK0 is a 24Mhz signal generated by the ARM that is connected to the FPGA
1356mhz is generated from the 13.56Mhz XTAL on the proxmark board also connected to the FPGA
Offline
So, now I've finally got simulation working against my omnikey reader. In the end, I made only small changes to hi_simulate. I have also implemented fpga-style modulation, but it's not fit to commit yet. I've updated head with a working fpga version, and also the iclass-fixes branch . The iclass-fixes-branch contains a simulation mode (hf iclass sim 2) which iterates over carl55's uids, in order to extract keys. I've yet to test it against a credentialed reader, but this time I the 'scope traces look gooooood.
Offline