Initial commit for the firmware. Used the 20090306_ela version as baseline.

It is identical to the popular 20081211, with the doob addition (20090301), a
linux client, and two additional commands for LF analysis. Let me know if
you find issues here!
This commit is contained in:
edouard@lafargue.name 2009-04-09 06:43:20 +00:00
commit 6658905f18
91 changed files with 16661 additions and 0 deletions

155
doc/CHANGES.TXT Normal file
View file

@ -0,0 +1,155 @@
################
## 2009/03/28 ##
################
winsrc/command.cpp
Added two new LF commands for tag exploration :
- askdemod: takes 2 arguments, one is the clock rate, one is the modulation
convention (high mod is 1 or high mod is zero)
This command demodulates the stream into a binary stream into
the trace buffer (0's and 1's)
- mandemod: manchester decoding of a bitstream: takes a binary stream from
the trace buffer (see askdemod) and attempts to do manchester decoding
to it. One argument: clock rate. Outputs the bitstream to the scrollback buffer.
Those two helped me to validate that the unknown tag I had was indeed an EM4100 type of tag
################
## 2008/12/11 ##
################
bootrom/bootrom.c
Significant changes to bootloader. Use of Chip ID register to detect if running on a SAM7S512 then configure FLASH
waitstates as per SummoningDark's suggestion for a SAM7S512 or SAM7S256.
Deleted idle loops waiting blindly for clocks to settle and now using status registers to detect when clocks are stable.
*************************
* IMPORTANT INFORMATION *
**************************************************************************************************************************
* With this boot code, the device can now only be flashed if button is held down after power on or a software reset.
* The flash procedure is this:
* Hold down button. Either plug in USB or software reset it. _While_holding_down_button_ (red and yellow LEDs are lit) you can
* issue one or more of the "prox bootrom <file>" "prox fpga <file>" "prox load <file>", be sure to hold button down for the
* entire duration of the flash process. Only release the button when flashing is complete and you want to let the board boot.
* This process may be less convenient but it's safer and avoids "unintentional" flashing of the board.
**************************************************************************************************************************
LED boot sequence now changed, C (red) lights up when boot code jumps from flash to RAM boot code, A (yellow) lights up after
clocks have been initialized, B (green) lights up when jumping from boot code to main code, then D (red led away from the others)
lights up while code is being downloaded to FPGA, then all leds turn off and board is ready for action.
With these changes the board now boots and is ready to use in about 3 seconds. Also since the USB bus is not initialized
twice (once during boot, then again when the main code runs) unless the button is held down at boot, this seems to avoid
the double USB connect and "USB device not recognized" when device is connected to the USB bus or software reset.
################
## 2008/12/06 ##
################
armsrc/fpga.c
Implemented function SetupSpi() to initialize the Serial Peripheral Interface (SPI) in preparation to adding an LCD to the board.
Changed FpgaWriteConfWord() to use the SPI communication now instead of bit banging the serial data to the FPGA.
fpga/fpga.v
The FPGA config word serializer required non standard SPI communication (ie for shifting in a 8 bit word, it required a 9th clock
cycle with NCS high to load the word from the shift register to the conf register). This was OK for manually bitbanging it but not
suitable for using SPI comms. The serializer was fixed to load the conf word from the shift register on a NCS lo-hi transition and
not require additional clocking.
armsrc/fpgaimg.c
Recompiled FPGA code after changes above.
armsrc/LCD.c
LCD driver for PCF8833 based LCDs like those found on Nokia models 2600,2650,3100,3120,5140,6030,6100,6610,7210,7250 maybe
others. These color LCDs have a resolution of 132x132 and a serial interface. They are very cheap like even down to $2/pc
This LCD driver is a straight rip of that found at http://www.sparkfun.com/datasheets/LCD/Jimbo-Nokia-SAM7-Example.zip with
very small changes, mainly to integrate it and make it compile with our codebase. Also comented out the circle subroutines
to keep the code to integer math only.
armsrc/fonts.c
Font definition for LCD driver
armsrc/appmain.c
Fixed a small bug in CmdHIDdemodFSK (added case 4) which prevented reading some tags. When a logic 0 is immediately followed
by the start of the next transmisson (special pattern) a pattern of 4 bit duration lengths is created.
################
## 2008/11/27 ##
################
armsrc/appmain.c
Implemented an HID tag FSK demodulator (CmdHIDdemodFSK) to obtain the tag ID code from the raw sampled waveform.
Implemented CmdHIDsimTAG which takes a 44bit HID tag ID as a hex number then creates the waveform and simulates the tag
winsrc/command.cpp
Added command "hidfskdemod" that calls CmdHIDdemodFSK, the ARM FSK demodulator for HID tags.
include/usb-cmd.h
New defines CMD_HID_DEMOD_FSK and CMD_HID_SIM_TAG
2008/11/25
common/iso14443_crc.c
Moved CRC calculation code into this file as it's common to both ARM and Windows side. This file is now included as needed.
################
## 2008/11/21 ##
################
armsrc/Makefile
Changes to split up the compilation of the ARM and produce separate S files for the FPGA code and the ARM code.
armsrc/appmain.c
Replaced some of the hex value params in FpgaWriteConfWord with more explanatory defines.
Changes to the Tune command as it assumes wrong HF capacitor value (130pF) and produces wrong voltage readings.
Combined some of the integer arithmetic statements to improve accuracy slightly, since the voltage divider ratio is not an integer.
Voltage divider resistor network is 10M/240k = ratio of 41.6666
Originally the calculation was rounding the ratio down to 41
3300 (mV) * 41 * sample_value / 1024
New calculation without rounding error is
3300 (mV) * 41.66666 * sample_value / 1024 => 137500 * sample_value / 1024
New define BUTTON_PRESS() returns status of button
armsrc/fpga.c
The current board can only take a X2S30 as there is no larger FPGA in PQFP100 package and
the smaller X2S15 FPGA can't fit the current code. The X2S30 FPGA config is fixed at 336,768 bits
The FPGA code base address and length is hard coded to occupy FLASH region 0x2000 - 0xC470.
armsrc/ldscript-fpga
New file to place the FPGA code at FLASH address 0x2000
bootrom/Makefile
Slight changes, commented out the generation of byteswapped S file, the other S files are generated in the same section of the makefile now.
bootrom/bootrom.c
Changed some thumb code with a one line ARM code which is clearer and more explicit. Processor runs in ARM mode at reset anyway.
Changed jump to RAM address, used to jump to 0x2000 (now FPGA area), now jumps to 0x10000.
bootrom/flash-reset.s
Changed name of CMain to CopyBootToRAM. Streamlined reset code, fixed up stack pointer initialization.
bootrom/fromflash.c
Removed the whole section of initializing clocks, this is redundant as it's being done once we jump to boot code in RAM
All fromflash.c does now is copy the boot code to ram and jumps to it.
bootrom/ram-reset.s
Fixed up stack pointer initialization that caused crash when using "loread"
include/at91sam7s128.h
New defines for debug register, lets you identify what processor flavour the code runs on, RAM and FLASH sizes, etc.
include/proxmark3.h
New useful defines for relay and button
winsrc/Makefile
Added new define /D_CRT_SECURE_NO_WARNINGS to elliminate a _whole bunch_ of bogus compilation warnings
winsrc/command.cpp
Changed CmdLosamples to take a numeric argument (number of samples x4 to retrieve from buffer)
New command Quit to exit the program from the GUI command prompt.
winsrc/gui.cpp
Fixup compilation warnings.
winsrc/prox.cpp
Tidy up printing to stdout, flashing progress now updates on the same line instead of scrolling up.
New command line parameter to load FPGA image to FLASH.

39
doc/README.TXT Normal file
View file

@ -0,0 +1,39 @@
This is a bare minimum compile environment for the proxmark3 sources.
CONTENTS
This bundle contains the ARM cross compiler in devkitARM and a _tiny_ subset
of the Visual C++ 2008 Express Edition in devkitWIN which is the bare minimum
required for compilation of this current source.
If you plan on further source code development you are strongly encouraged
to download the full Visual C++ 2008 available for free download from
http://www.microsoft.com/express/download/
CAVEATS
There is no provision in this environment for compiling the FPGA source. To
do that you need to download the free (registration required) ISE WebPack
from Xilinx at http://www.xilinx.com/ise/logic_design_prod/webpack.htm
Be warned, the pack is huge, 2Gb download and >4Gb installed.
USAGE
First of all run the .msi file in devkitWIN\vcredist_x86 to install the VC++
redistributables, without these, nmake, cl and link won't run.
Get a command prompts in the cockpit directory and pretty much run the batch
files in the order they appear:
0setpath.bat - sets the environment vars for the compile environment
1makearm.bat - compiles the files in armsrc, output files in armsrc\obj
2makeboot.bat - compiles the files in bootrom, output files in bootrom\obj
3makewin.bat - compiles the files in winsrc, output files in winsrc\obj
4flashos.bat - attempts to upload the OS image to the proxmark3 board
ACKNOWLEDGMENTS
Thanks to J Westhues for the original proxmark, Roel and the proxmark.org
community. This pack may contain F/OSS or free but copyrighted software
from Xilinx, Microsoft and others. All trademarks are the property of
their respective owners. All rights reserved.

BIN
doc/component-placement.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
doc/proxmark3.pdf Normal file

Binary file not shown.

BIN
doc/proxmark3.xls Normal file

Binary file not shown.

BIN
doc/schematics.pdf Normal file

Binary file not shown.

276
doc/system.txt Normal file
View file

@ -0,0 +1,276 @@
This is outdated.
---
INTRODUCTION TO THE proxmark3
=============================
The proxmark3 device is designed to manipulate RFID tags in a number of
different ways. For example, a proxmark3 can:
* read a low-frequency (~100 kHz) or high-frequency (13.56 MHz) tag,
including the ISO-standard tags; standards that require
bidirectional communication between the reader and the tag are
not a problem
* emulate a low- or high-frequency tag, in a way very similar to the
way that a real tag behaves (e.g., it derives its timing from the
incident carrier)
* eavesdrop on the signals exchanged between another reader and tag
* measure the resonant frequency of an antenna, to a certain extent
(this is a convenience when building a test setup for the previous
three functions)
The proxmark3 may be thought of as a direct-sampling software radio.
There is some complication, though, because of the usual dynamic range
issue in dealing with signals in RFID systems (large signal due to
the reader, small signal due to the tag). Some analog processing is
therefore used to fix this before the signal is digitized. (Although,
it is possible to digitize the signal from the antenna directly, with
appropriate population options. It is just not usually a good idea.)
SYSTEM ARCHITECTURE
===================
The ANTENNA sends and receives signals over the air. It is external to
the board; it connects through SV2. Separate pins on the connector are
used for the low- and high-frequency antennas, and the analog receive
paths are separate. The antennas are inductive loops, which are resonated
by on-board capacitors.
On the transmit side, the antennas are excited by large numbers of
paralleled bus driver buffers. By tri-stating some of the buffers, it
is possible to vary the transmit strength. This may be used to generate
a modulated carrier. The buffers are driven by signals from the FPGA,
as are the output enables. The antennas are excited as series circuits,
which permits a large input power for a relatively small input voltage.
By driving all of the buffers low, it is possible to make the antenna
look to the receive path like a parallel LC circuit; this provides a
high-voltage output signal. This is typically what will be done when we
are not actively transmitting a carrier (i.e., behaving as a reader).
On the receive side, there are two possibilities, which are selected by
RLY1. A mechanical relay is used, because the signal from the antenna is
likely to be more positive or negative than the highest or lowest supply
voltages on-board. In the usual case (PEAK-DETECTED mode), the received
signal is peak-detected by an analog circuit, then filtered slightly,
and then digitized by the ADC. This is the case for both the low- and
high-frequency paths, although the details of the circuits for the
two cases are somewhat different. This receive path would typically
be selected when the device is behaving as a reader, or when it is
eavesdropping at close range.
It is also possible to digitize the signal from the antenna directly (RAW
mode), after passing it through a gain stage. This is more likely to be
useful in reading signals at long range, but the available dynamic range
will be poor, since it is limited by the 8-bit A/D. These modes would be
very appropriate, for example, for the heavily-discussed attacks in which
a tag's ID is learned from the data broadcast by a reader performing an
anticollision loop, because there is no dynamic range problem there. It
would also be possible to program the proxmark3 to receive broadcast AM
radio, with certain changes in component values.
In either case, an analog signal is digitized by the ADC (IC8), and
from there goes in to the FPGA (IC1). The FPGA is big enough that it
can perform DSP operations itself. For some high-frequency standards,
the subcarriers are fast enough that it would be inconvenient to do all
the math on a general-purpose CPU. The FPGA can therefore correlate for
the desired signal itself, and simply report the total to the ARM. For
low-frequency tags, it probably makes sense just to pass data straight
through to the ARM.
The FPGA communicates with the ARM through either its SPI port (the ARM
is the master) or its generic synchronous serial port (again, the ARM
is the master). The ARM connects to the outside world over USB.
DETAILS: POWER DISTRIBUTION
===========================
I make a half-hearted attempt to meet the USB power specs; this adds a
bit of complexity. I have not made measurements to determine how close
I come to succeeding, but I think that the suspend current might turn
out to be a pain.
The +3V3 rail is always powered, whenever we are plugged in to USB. This
is generated by an LDO, which burns a quiescent current of 150 uA
(typical) already. The only thing powered from the +3V3 rail is the ARM,
which can presumably do smart power control when we are in suspend.
The ARM generates two signals to switch power to the rest of the board:
FPGA_ON, and NVDD_ON. When NVDD_ON goes low, the Vdd rail comes up to
about five volts (the filtered-but-unregulated USB voltage). This powers
most of the analog circuitry, including the ADC and all of the opamps
and comparators in the receive path, and the coil drivers as well. Vdd
also feeds the +3V3-FPGA and +2v5 regulators, which power only the
FPGA. These regulators are enabled by FPGA_ON, so the FPGA is powered
only when NVDD_ON is asserted low, and FPGA_ON is asserted high.
DETAILS: FPGA
=============
The FPGA is a Spartan-II. This is a little bit old, but it is widely
available, inexpensive, and five-volt tolerant. For development, the FPGA
is configured over JTAG (SV5). In operation, the FPGA is configured in
slave serial mode by the ARM, from a bitstream stored in the ARM's flash.
Power to the FPGA is managed by regulators IC13 and IC12, both of which
have shutdown. These generate the FPGA's VCCO (+3v3) and VCCINT (+2v5)
supplies. I am a little bit worried about the power-on surge, since we
run off USB. At the very minimum, the FPGA should not get power until
we have enumerated and requested the full 500 mA available from USB. The
large electrolytic capacitors C37 and C38 will presumably help with this.
The logic is written in Verilog, of course for webpack. I have structured
the FPGA in terms of `major modes:' the FPGA's `major mode' determines
which of several modules is connected to the FPGA's I/O pins. A separate
module is used for each of the FPGA's function; for example, there is
now a module to read a 125 kHz tag, simulate a 125 kHz tag, transmit to
an ISO 15693 tag, and receive from an ISO 15693 tag.
DETAILS: ANALOG RECEIVE PATH
============================
For `slow' signals, I use an MCP6294 opamp. This has a GBW of 10 MHz,
which is more than enough for the low-frequency stuff, and enough for
all of the subcarrier frequencies that I know of at high frequency. In
practice, the `slow' signals are all the signals following the peak
detector. These signals are usually centred around the generated
voltage Vmid.
For `fast' signals, I use an AD8052. This is a very fast voltage-feedback
amplifier (~100 MHz GBW). I use it immediately after the antenna for
both the low- and high-frequency cases, as a sort of an ugly LNA. It is
not optimal, but it certainly made the design easy.
An ordinary CD4066 is used to multiplex the four possible signals
(low/high frequency paths, RAW/PEAK-DETECTED). There is a potential
problem at startup, when the ARM is in reset; there are pull-ups on the
lines that control the mux, so all of the switches turn on. This shorts
the four opamp outputs together through the on-resistance of the switch.
All four outputs float to the same DC voltage with no signal, however,
and the on-resistance of the switches is fairly large, so I don't think
that will be a problem in practice.
Comparators are used to generate clock signals when the device is
emulating a tag. These clock signals are generated from the signal on the
antenna, and therefore from the signal transmitted by the reader. This
allows us to clock ourselves off the reader, just like a real tag would.
These signals go in to the FPGA. There is a potential problem when the
FPGA is powered down; these outputs might go high and try to power the
FPGA through the protection diodes. My present solution to this is a
couple of resistors, which is not very elegeant.
The high-frequency peak-detected receive path contains population options
for many features that I do not currently use. A lot of these are just
me guessing that if I provide options for different series and shunt
passives, perhaps it will come in handy in some way. The Zener diodes D10
and D11 are optional, but may protect the front end from an overvoltage
(which will fry the peak detector diodes) when the `simulated tag'
is read by a powerful reader.
DETAILS: ANALOG TRANSMIT PATH
=============================
The coil drivers are just ACT244 bus buffers. I parallel eight of them
for each antenna (eight for the high-frequency antenna, eight for the
low-frequency antenna). This should easily provide a hundred milliamps
coil drive or so, which is more than enough for anything that I imagine
doing with the device. The drivers hit the coil with a square wave
voltage, however, which means that it is only the bandpass filter effect
of a resonant antenna that suppresses the odd harmonics. In practice it
would probably take heroic efforts (high antenna Q) to meet the FCC/CE
harmonic specs; and in practice no one cares.
The tx strength, given good antenna tuning, is determined by the series
resistors. Choose the ratios to stay within the rated current of the
buffers, and to achieve the desired power ratios by enabling or disabling
nOEs for the desired modulation index. It is useful to populate one of the
resistors as a high value (~10k) for the simulated tag modes; this allows
us to look at the incident carrier without loading the reader very much.
DETAILS: ARM
============
Atmel makes a number of pin-compatible ARMs, with slightly different
peripherals, and different amounts of flash and RAM. It is necessary
to choose a device with enough flash not just for the ARM's program,
but also for the FPGA image (which is loaded by the ARM).
The ARM is responsible for programming the FPGA. It also supplies a
clock to the FPGA (although the FPGA clock can also run off the 13.56
MHz clock not used for anything else, which is obviously asynchronous
to anything in the ARM).
It is necessary to use JTAG to bring the ARM for the first time; at
that point you can load a bootrom, and subsequently load new software
over USB. It might be possible to use the ARM's pre-loaded bootloader
(see datasheet) instead of JTAG, but I wanted the JTAG anyways for
debugging, so I did not bother. I used a Wiggler clone, with Macraigor's
OCD Commander. More expensive tools would work as well.
USB SOFTWARE
============
At present I enumerate as an HID device. This saves me writing a driver,
but it forces me to do interrupt transfers for everything. This limits
speed and is not very elegant. A real USB driver would be nice, maybe
even one that could do stuff like going isochronous to stream samples
from the A/D for processing on the PC.
PRETENDING TO BE A TAG
======================
It is not possible, with the given topology, to open-circuit the antenna
entirely and still look at the signal received on it. The simulated tag
modes must therefore switch between slight loading and heavy loading,
not open- and short-circuts across the antenna, evening though they do
not depend upon the incident carrier for power (just timing information).
RECEIVING SIGNAL STRAIGHT FROM THE ANTENNAS
===========================================
There is a path straight from the antenna to the A/D, bypassing the peak
detector assembly. This goes through a gain stage (just a fast voltage
feedback opamp), and from there straight in to the mux.
It is necessary to energize the relay to connect these paths. If the
coil is driven (as if to excite and read a tag) while these paths are
connected, then damage will probably result. Most likely the opamp
will fry.
READING A TAG
=============
The tag is excited by a carrier transmitted by the reader. This is
generated by IC9 and IC10, using some combination of buffers. The transmit
power is determined by selecting the right combination of PWR_OEx pins;
drive more of them low for more power. This can be used to modulate the
transmitted signal, and thus send information to the tag.
The received signal from the antenna is first peak-detected, and then
high-pass filtered to reject the unmodulated carrier. The signal is
amplified a bit, and goes in to the A/D mux from there. The A/D is
controlled by the FPGA. For 13.56 MHz tags, it is easiest to do everything
synchronous to the 13.56 MHz carrier.
INTERFACE FROM THE ARM TO THE FPGA
==================================
The FPGA and the ARM can communicate in two main ways: using the ARM's
general-purpose synchronous serial port (the SSP), or using the ARM's
SPI port. The SPI port is used to configure the FPGA. The ARM writes a
configuration word to the FPGA, which determines what operation will
be performed (e.g. read 13.56 MHz vs. read 125 kHz vs. read 134 kHz
vs...). The SPI is used exclusively for configuration.
The SSP is used for actual data sent over the air. The ARM's SSP can
work in slave mode, which means that we can send the data using clocks
generated by the FPGA (either from the PCK0 clock, which the ARM itself
supplies, or from the 13.56 MHz clock, which is certainly not going to
be synchronous to anything in the ARM), which saves synchronizing logic
in the FPGA. The SSP is bi-directional and full-duplex.