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.
Pages: 1
I'm wanting to properly emulate a LF tag on the Proxmark3 (Hitag2, specifically) with full bidirectional communication between tag and reader and am suspecting that the current FPGA code does not really support this. Also, I haven't seen any documentation with regards to the currently supported FPGA major modes, so let me first state what I think I understood from reading the source and then you can correct me:
The only modes accessing the LF path are FPGA_MAJOR_MODE_LF_READER (corresponding to lo_read.v), FPGA_MAJOR_MODE_LF_SIMULATOR (lo_simulate.v) and FPGA_MAJOR_MODE_LF_PASSTHRU (lo_passthru.v)
lo_read.v and lo_passthru.v both actively drive the antenna, so are useless for simple tag emulation
lo_simulate.v connects the AT91SAM7 SSC output to PWR_OE{1,2,4}, sets PWR_OE3 to 0 and sets PWR_LO to low. As far as I can tell the output enable on the coil drivers is inverting, so setting PWR_OE3=0 and PWR_LO=0 continously drives the antenna at GND level. When the AT91SAM7 has SSC_DOUT set to high the remaining output drivers are in tri-state, otherwise they too will drive the antenna to GND level. For some reason though, SimulateTagLowFrequency() calls these two states OPEN_COIL and SHORT_COIL. The AT91SAM7 SSC clock input is connected to CROSS_LO which (through a buffer) directly comes from the antenna (if the relay is switched to the peak detect path).
So, the lo_simulate.v code can switch the LF antenna between slightly connected to GND and strongly connected to GND, and gives the unfiltered carrier as a clock signal to the AT91SAM7.
Now, in theory the carrier signal would be good enough to receive. I even came up with an elaborate plan to use the AT91SAM7's timer/counter unit as a kind of envelope detector. Alas, I just looked at the signal on an oscilloscope, and it's completely useless. The clock signal is there, regardless of whether the carrier is currently full or modulated, it just gets worse during the modulation phase. Even when the carrier is completely off for a prolonged period of time there are glitches on that line. That's due to the fact that the proxmark only has an opamp between the antenna signal and CROSS_LO, a Schmitt-Trigger (as seen on the OpenPICC) would be better.
Now, looking around, I fear that a change to the FPGA code is necessary, so any advice would be great. I haven't done any FPGA or Verilog yet, ever.
What I guess would be great would be an envelope detector on the FPGA, working off the LORAW signal. However, looking at that signal on the scope, it too seems to be useless because it's either at maximum or at minimum all the time. Instead, looking at the LOPKD signal, this can probably be used. I admit that I have no idea how the peak detection circuitry works, but I think it would be possible to use that signal. Now, in the FPGA I need either (or both) a configurable threshold on the A/D values, or a mode to submit the A/D values through the SSC onto the AT91SAM7, much like the existing lo_read code, but without driving the antenna. The latter would allow the (possibly dynamic) threshold to be computed in the AT91SAM7.
Offline
comparator that squares up cross_lo (ic5a, tlv3502) has 6 mv internal hysteresis per datasheet. but that's not enough to make carrier detect off that signal work. kind of a tricky way to do that anyways.
the loraw signal is no good as you say. i think the lopkd signal is what you want anyways, except it gets high pass filtered so it will always return to ~128 if there have been no transitions for a while, no matter what the absolute level. might be okay if the reader is doing manchester or something (so signal is zero-mean). signal will be really big compared to reader mode so everything will saturate but that's okay.
if it's not zero mean (or if period is slow vs. high pass time constant) then you could put some hysteresis on the lopkd signal in the fpga; should get big spikes up and down on the rising and falling edges of the signal from the reader. that's what they did for the hf tag simulation.
or do hysteresis in software i guess. the hf tags are too fast for that but should be okay for a few hundred k/s.
Offline
Thanks for the insight.
i think the lopkd signal is what you want anyways, except it gets high pass filtered so it will always return to ~128 if there have been no transitions for a while, no matter what the absolute level. might be okay if the reader is doing manchester or something (so signal is zero-mean). signal will be really big compared to reader mode so everything will saturate but that's okay.
Yeah, the signal will not be zero-mean since basically every protocol out there tries to minimize the field-off time as much as possible in order to keep powering the tag. For reference, here is a screenshot of the signal in question:
The upper waveform is directly from the antenna (TP2), the lower waveform is from after the analog mux (TP1) and shows the LOPKD path. The signal shape varies with antenna to reader distance, but I think a simple threshold somewhere near the upper bound and then only looking for rising edges should work quite fine.
Now, I'm trying to set up an environment to compile the FPGA code in order so that I can modify it. I assume the Xilinx WebPack for Linux is fine?
Offline
Ok, phew, I finally managed to get the Xilinx tools for Linux running. A few hints:
The Proxmark3 uses a Spartan-II. Spartan-II support has been removed from ISE 11.1, you need to download 10.1. The Xilinx website will offer a link to the WebPack 10.1 download on the page for the 11.1 download. On http://www.xilinx.com/tools/webpack.htm click the "Download WebPack" link, jump through a few hoops and registrations until you've reached the entitlement center, then there's a link to download older versions in one of the corners.
The WebPack does not support 64bit Linux, for unclear reasons. However, if you have some 32bit libraries installed (some 64bit distributions will offer them as compatibility packages), the installation works just fine if you have it believe to be running on a 32bit system:
$ linux32 ./setup
After the installation is complete, in /opt/Xilinx/10.1/ by default, you get get /opt/Xilinx/10.1/ISE/settings32.sh and .../settings32.csh, you need to source these files before you can use the tools. Do not put them in your startup files, though. E.g. to run the main GUI use
$ . /opt/Xilinx/10.1/ISE/settings32.sh # Note that there's a space between the . and the first /
$ ise
I translated the shipped go.bat to a Makefile, for easier execution (you still need to source the settings32.sh before using the Makefile). It should even work on Windows, or if not should only need a few modifications to the defined variables to get to work (I can't test), with one exception: For some reason tools/rbt2c.pl has »local $/ = "\r\n";« from which the \r needs to be removed to work under Linux. I believe that it should still work without the \r under Windows, please advise.
UNAME := $(shell uname)
ifeq ($(UNAME), Linux)
WRAPPED_C_STREAM = ../armsrc/fpgaimg.c
TOOLS_DIR = ../tools/
XILINX_TOOLS_PREFIX =
DELETE=rm -rf
else
WRAPPED_C_STREAM = ..\\armsrc\\fpgaimg.c
TOOLS_DIR = ..\\tools\\
XILINX_TOOLS_PREFIX=
DELETE=del /r
endif
all: fpga.ngc fpga.ngd fpga.ncd fpga-placed.ncd fpga.rbt $(WRAPPED_C_STREAM)
clean:
$(DELETE) fpga.bgn fpga.drc fpga.ncd fpga.ngd fpga_par.xrpt fpga-placed.pad fpga-placed.par fpga-placed.xpi fpga_usage.xml xlnx_auto_0.ise xst.srp
$(DELETE) fpga.bit fpga.map fpga.ngc fpga_ngdbuild.xrpt fpga.pcf fpga-placed_pad.csv fpga-placed.ptwx fpga.rbt xlnx_auto_0_xdb
$(DELETE) fpga.bld fpga.mrp fpga.ngc_xst.xrpt fpga.ngm fpga-placed.ncd fpga-placed_pad.txt fpga-placed.unroutes fpga_summary.xml netlist.lst xst
.PHONY: all clean
fpga.ngc: fpga.v fpga.ucf xst.scr util.v lo_simulate.v lo_read.v lo_passthru.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v
$(DELETE) fpga.ngc
$(XILINX_TOOLS_PREFIX)xst -ifn xst.scr
fpga.ngd: fpga.ngc
$(DELETE) fpga.ngd
$(XILINX_TOOLS_PREFIX)ngdbuild -aul -p xc2s30-6vq100 -nt timestamp -uc fpga.ucf fpga.ngc fpga.ngd
fpga.ncd: fpga.ngd
$(DELETE) fpga.ncd
$(XILINX_TOOLS_PREFIX)map -p xc2s30-6vq100 fpga.ngd
fpga-placed.ncd: fpga.ncd
$(DELETE) fpga-placed.ncd
$(XILINX_TOOLS_PREFIX)par fpga.ncd fpga-placed.ncd
fpga.rbt: fpga-placed.ncd
$(DELETE) fpga.bit fpga.drc fpga.rbt
$(XILINX_TOOLS_PREFIX)bitgen -b fpga-placed.ncd fpga.bit
$(WRAPPED_C_STREAM): fpga.rbt
perl $(TOOLS_DIR)rbt2c.pl fpga.rbt > $(WRAPPED_C_STREAM)
Offline
I started down a similar path and got LF commands working:
http://www.proxmark.org/forum/topic/251 … o-lf-tags/
as you can see, it is possible to send commands to the Hitag2 using this method (in this case, the 'START AUTH' command)...
I also had the hassle with downloading various versions of the Xilinx kit and ended up sorting it out:
http://www.proxmark.org/forum/topic/282 … velopment/
so we really ought to get the new Wiki manual to replace the main link on the homepage, where we can easily post these things in one place and not keep re-inventing the wheel!
Offline
Moin,
I started down a similar path and got LF commands working:
Yes, I saw that code, but since it's actively powering the tag (e.g. acting as a reader) it's not useful for tag emulation. Instead I'm now modifying the lo_simulate.v code to output the received demodulated signal on SSP_FRAME and should have a proper Hitag2 type tag emulation by tomorrow.
Offline
Nice! I look forward to playing with that...
Offline
Ok, here's the patch: http://www.ploetzli.ch/forumtst/proxmar … idir.patch
This adds:
Defines in at91sam7s128.h for the Timer/Counter peripheral
A new USB command CMD_LF_SIMULATE_BIDIR
A new prox tool command losimbidir
A function in lfops.c, triggered by this command, that will receive data from a Hitag2 reader and is capable of responding (for now, only the two most important frames to get tag detection working, but it's trivially extendable)
It modifies:
fpga.v and lo_simulate.v to give the divisor into the lo_simulate block as an argument
lo_simulate.v to use the SSP_FRAME signal (PA15 on the AT91SAM7) to carry a version of the ADC value with threshold and hysteresis.
fpgaimg.c with the compiled bitstream code with the above modifications. This bitstream is backwards compatible with the existing bitstream, e.g. everything should still work. Obviously, for the new emulation code you need the new bitstream.
Offline
Henryk, I was looking at the lo_simulate FPGA code and I see you were the last to update it in r188. Can you please explain what the intent was with the additional code. I understand the hysteresis (I think I can optimize the code a bit) but what confuses me is the fact that the A/D read is trigered off the pck0 clock divided down.
Shouldn't the A/D read be trigered instead by the cross_lo signal since in simulation mode we pretend to be a passive tag and we're "driven" by the external reader carrier?
If you could clarify that I could update the code and simulate it.
Last edited by d18c7db (2010-02-11 01:20:24)
Offline
At that point I didn't know much anything about FPGA programming so I just copied and pasted my way through. The clock code is from lo_read.v. However, it's still correct, I believe, since the reader carrier will be switched off for data transmission.
There are two ways to receive an 100% ASK signal: A) Generate your own timing and sample the carrier at some rate related to the bitrate, that's what this code does. B) The other way would be to count carrier edges between pauses (and then have some sort of simple timer to detect pauses, doesn't need to be very accurate but only needs to detect stretches of significantly more than one carrier period without carrier edges), which is in principle more reliable (and mostly independent of the carrier frequency), but only works with protocols where the pause duration doesn't matter.
The code implements A: Pro: Generic and always applicable (even for NRZ encoding on the carrier), Con: needs own carrier signal which most likely isn't synchronized with the original carrier, so there might be some drift with relation to the data signal (which is solved through supersampling and relating all timing not to a fixed grid but to the last detected edge).
I chose A because it's easier to implement and to debug in a quick way. Changing this to B needs some work, but might be worth it. I suspect the general applicability of A isn't really this much of an issue: I believe most protocols would be receivable with B, since this is roughly what a real tag does. The only protocol that I know off the top of my head that needs A is ISO 14443-B, but that uses 10% ASK, so you have a continuous carrier to base your clock off.
Offline
I'm having some trouble with the tag emulation. The proxmark can read the 11000, gets in the right state (passw mode) en starts sending its UID, but the reader doesn't respond and on the scope I don't see any response either. The carrier signal is already gone when I expect the load modulation from the response. Same behaviour as when there is no tag in sight.
I tried changing the T_wresp value but that doesn't help either.
Any ideas?
Offline
Pages: 1