diff --git a/README.txt b/README.txt index 05829dac..cb2c7f3c 100644 --- a/README.txt +++ b/README.txt @@ -1,68 +1,87 @@ -The iceman fork. - NOTICE: +(2014-03-26) +This is now the official Proxmark repository! -The official Proxmark repository is found here: https://github.com/Proxmark/proxmark3 +INTRODUCTION: +The proxmark3 is a powerful general purpose RFID tool, the size of a deck +of cards, designed to snoop, listen and emulate everything from +Low Frequency (125kHz) to High Frequency (13.56MHz) tags. -NEWS: +This repository contains enough software, logic (for the FPGA), and design +documentation for the hardware that you could, at least in theory, +do something useful with a proxmark3. -Whats in this fork? I have scraped the web for different enhancements to the PM3 source code and not all of them ever found their way to the master branch. -Among the stuff is +RESOURCES: - * Jonor's hf 14a raw timing patch - * Piwi's updates. (usually gets into the master) - * Holiman's iclass, (usually gets into the master) - * Marshmellow's LF fixes - * Midnitesnake's Ultralight, Ultralight-c enhancements - * Izsh's lf peak modification / iir-filtering - * Aspers's tips and tricks from inside the PM3-gui-tool, settings.xml and other stuff. - * My own desfire, Ultralight extras, LF T55xx enhancements, bugs fixes (filelength, hf mf commands ), TNP3xxx lua scripts, Awid26, skidata scripts (will come) - * other obscure patches like for the sammy-mode, (offline you know), tagidentifications, defaultkeys. - -Give me a hint, and I'll see if I can't merge in the stuff you have. - -I don't actually know how to make small pull-request to github :( and that is the number one reason for me not pushing a lot of things back to the PM3 master. - -PM3 GUI: - -I do tend to rename and move stuff around, the official PM3-GUI from Gaucho will not work so well. *sorry* - - + * This repository! + https://github.com/Proxmark/proxmark3 + + * The Wiki + https://github.com/Proxmark/proxmark3/wiki + + * The GitHub page + http://proxmark.github.io/proxmark3/ + + * The Forum + http://www.proxmark.org/forum + + * The IRC chanel + irc.freenode.org #proxmark3 + -or- + http://webchat.freenode.net/?channels=#proxmark3 + DEVELOPMENT: -This fork is adjusted to compile on windows/mingw environment with Qt5.3.1 & GCC 4.8 -For people with linux you will need to patch some source code and some small change to one makefile. If you are lazy, you google the forum and find asper's or holimans makefile or you find your solution below. +The tools required to build or run the project will vary depending on +your operating system. Please refer to the Wiki for details. -Common errors linux/macOS finds -Error: - * loclass/fileutils.c:15:2: warning: implicit declaration of function ‘_stat’ [-Wimplicit-function-declaration] -Solution: - * Remove the "unscore" sign. In linux you use without underscore, in windows you need a underscore. - -Error: - * \client\makefile the parameter -lgdi32 -Solution: - * Remove parameter. - -Error: - * Using older Qt4.6 gives compilation errors. -Solution - * Upgrade to Qt5.3.1 - OR - * Change these two line in \client\makefile - CXXFLAGS = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui -I$(QTDIR)/include/QtWidgets -I/mingw/include - QTLDLIBS = -L$(QTDIR)/lib -lQt5Core -lQt5Gui -lQt5Widgets - - TO - - CXXFLAGS = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui - QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4 - + * https://github.com/Proxmark/proxmark3/wiki -An old Qt4 version makefile is found here: http://www.icesql.se/proxmark3/code/linuxmakefile.txt but this one doesn't have all new files in it. So I don't recommend it. +OBTAINING HARDWARE: + +The Proxmark 3 is available for purcahse (assembled and tested) from the +following locations: + + * http://proxmark3.com/ + * http://www.xfpga.com/ + +Most of the ultra-low-volume contract assemblers could put +something like this together with a reasonable yield. A run of around +a dozen units is probably cost-effective. The BOM includes (possibly- +outdated) component pricing, and everything is available from Digikey +and the usual distributors. + +If you've never assembled a modern circuit board by hand, then this is +not a good place to start. Some of the components (e.g. the crystals) +must not be assembled with a soldering iron, and require hot air. + +The schematics are included; the component values given are not +necessarily correct for all situations, but it should be possible to do +nearly anything you would want with appropriate population options. + +The printed circuit board artwork is also available, as Gerbers and an +Excellon drill file. +LICENSING: -January 2015, Sweden -iceman at host iuse.se \ No newline at end of file +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Jonathan Westhues +user jwesthues, at host cq.cx + +May 2007, Cambridge MA diff --git a/armsrc/LCD.c b/armsrc/LCD.c index 87be5e3a..65d64ac9 100644 --- a/armsrc/LCD.c +++ b/armsrc/LCD.c @@ -6,7 +6,7 @@ // LCD code //----------------------------------------------------------------------------- -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" #include "LCD.h" #include "fonts.h" diff --git a/armsrc/Makefile b/armsrc/Makefile index 69e4738a..f87cf0a1 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -10,16 +10,15 @@ APP_INCLUDES = apps.h #remove one of the following defines and comment out the relevant line #in the next section to remove that particular feature from compilation -APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -fno-strict-aliasing +APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG #-DWITH_LCD #SRC_LCD = fonts.c LCD.c SRC_LF = lfops.c hitag2.c SRC_ISO15693 = iso15693.c iso15693tools.c -SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c -SRC_ISO14443b = iso14443.c -SRC_CRAPTO1 = crapto1.c crypto1.c des.c aes.c desfire_key.c desfire_crypto.c mifaredesfire.c -SRC_CRC = iso14443crc.c crc.c crc16.c crc32.c +SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c +SRC_ISO14443b = iso14443.c +SRC_CRAPTO1 = crapto1.c crypto1.c THUMBSRC = start.c \ $(SRC_LCD) \ @@ -35,14 +34,15 @@ THUMBSRC = start.c \ # These are to be compiled in ARM mode ARMSRC = fpgaloader.c \ legicrf.c \ + iso14443crc.c \ + crc16.c \ lfdemod.c \ $(SRC_ISO14443a) \ $(SRC_ISO14443b) \ $(SRC_CRAPTO1) \ - $(SRC_CRC) \ legic_prng.c \ - iclass.c - + iclass.c \ + crc.c # stdint.h provided locally until GCC 4.5 becomes C99 compliant APP_CFLAGS += -I. diff --git a/armsrc/aes.c b/armsrc/aes.c deleted file mode 100644 index 3df006bb..00000000 --- a/armsrc/aes.c +++ /dev/null @@ -1,1168 +0,0 @@ -#include "stdio.h" -#include "aes.h" - -static const unsigned int Te0[256] = { - 0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL, - 0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL, - 0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL, - 0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL, - 0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL, - 0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL, - 0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL, - 0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL, - 0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL, - 0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL, - 0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL, - 0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL, - 0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL, - 0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL, - 0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL, - 0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL, - 0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL, - 0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL, - 0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL, - 0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL, - 0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL, - 0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL, - 0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL, - 0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL, - 0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL, - 0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL, - 0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL, - 0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL, - 0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL, - 0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL, - 0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL, - 0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL, - 0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL, - 0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL, - 0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL, - 0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL, - 0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL, - 0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL, - 0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL, - 0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL, - 0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL, - 0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL, - 0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL, - 0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL, - 0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL, - 0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL, - 0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL, - 0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL, - 0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL, - 0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL, - 0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL, - 0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL, - 0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL, - 0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL, - 0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL, - 0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL, - 0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL, - 0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL, - 0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL, - 0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL, - 0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL, - 0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL, - 0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL, - 0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL, -}; -static const unsigned int Te1[256] = { - 0xa5c66363UL, 0x84f87c7cUL, 0x99ee7777UL, 0x8df67b7bUL, - 0x0dfff2f2UL, 0xbdd66b6bUL, 0xb1de6f6fUL, 0x5491c5c5UL, - 0x50603030UL, 0x03020101UL, 0xa9ce6767UL, 0x7d562b2bUL, - 0x19e7fefeUL, 0x62b5d7d7UL, 0xe64dababUL, 0x9aec7676UL, - 0x458fcacaUL, 0x9d1f8282UL, 0x4089c9c9UL, 0x87fa7d7dUL, - 0x15effafaUL, 0xebb25959UL, 0xc98e4747UL, 0x0bfbf0f0UL, - 0xec41adadUL, 0x67b3d4d4UL, 0xfd5fa2a2UL, 0xea45afafUL, - 0xbf239c9cUL, 0xf753a4a4UL, 0x96e47272UL, 0x5b9bc0c0UL, - 0xc275b7b7UL, 0x1ce1fdfdUL, 0xae3d9393UL, 0x6a4c2626UL, - 0x5a6c3636UL, 0x417e3f3fUL, 0x02f5f7f7UL, 0x4f83ccccUL, - 0x5c683434UL, 0xf451a5a5UL, 0x34d1e5e5UL, 0x08f9f1f1UL, - 0x93e27171UL, 0x73abd8d8UL, 0x53623131UL, 0x3f2a1515UL, - 0x0c080404UL, 0x5295c7c7UL, 0x65462323UL, 0x5e9dc3c3UL, - 0x28301818UL, 0xa1379696UL, 0x0f0a0505UL, 0xb52f9a9aUL, - 0x090e0707UL, 0x36241212UL, 0x9b1b8080UL, 0x3ddfe2e2UL, - 0x26cdebebUL, 0x694e2727UL, 0xcd7fb2b2UL, 0x9fea7575UL, - 0x1b120909UL, 0x9e1d8383UL, 0x74582c2cUL, 0x2e341a1aUL, - 0x2d361b1bUL, 0xb2dc6e6eUL, 0xeeb45a5aUL, 0xfb5ba0a0UL, - 0xf6a45252UL, 0x4d763b3bUL, 0x61b7d6d6UL, 0xce7db3b3UL, - 0x7b522929UL, 0x3edde3e3UL, 0x715e2f2fUL, 0x97138484UL, - 0xf5a65353UL, 0x68b9d1d1UL, 0x00000000UL, 0x2cc1ededUL, - 0x60402020UL, 0x1fe3fcfcUL, 0xc879b1b1UL, 0xedb65b5bUL, - 0xbed46a6aUL, 0x468dcbcbUL, 0xd967bebeUL, 0x4b723939UL, - 0xde944a4aUL, 0xd4984c4cUL, 0xe8b05858UL, 0x4a85cfcfUL, - 0x6bbbd0d0UL, 0x2ac5efefUL, 0xe54faaaaUL, 0x16edfbfbUL, - 0xc5864343UL, 0xd79a4d4dUL, 0x55663333UL, 0x94118585UL, - 0xcf8a4545UL, 0x10e9f9f9UL, 0x06040202UL, 0x81fe7f7fUL, - 0xf0a05050UL, 0x44783c3cUL, 0xba259f9fUL, 0xe34ba8a8UL, - 0xf3a25151UL, 0xfe5da3a3UL, 0xc0804040UL, 0x8a058f8fUL, - 0xad3f9292UL, 0xbc219d9dUL, 0x48703838UL, 0x04f1f5f5UL, - 0xdf63bcbcUL, 0xc177b6b6UL, 0x75afdadaUL, 0x63422121UL, - 0x30201010UL, 0x1ae5ffffUL, 0x0efdf3f3UL, 0x6dbfd2d2UL, - 0x4c81cdcdUL, 0x14180c0cUL, 0x35261313UL, 0x2fc3ececUL, - 0xe1be5f5fUL, 0xa2359797UL, 0xcc884444UL, 0x392e1717UL, - 0x5793c4c4UL, 0xf255a7a7UL, 0x82fc7e7eUL, 0x477a3d3dUL, - 0xacc86464UL, 0xe7ba5d5dUL, 0x2b321919UL, 0x95e67373UL, - 0xa0c06060UL, 0x98198181UL, 0xd19e4f4fUL, 0x7fa3dcdcUL, - 0x66442222UL, 0x7e542a2aUL, 0xab3b9090UL, 0x830b8888UL, - 0xca8c4646UL, 0x29c7eeeeUL, 0xd36bb8b8UL, 0x3c281414UL, - 0x79a7dedeUL, 0xe2bc5e5eUL, 0x1d160b0bUL, 0x76addbdbUL, - 0x3bdbe0e0UL, 0x56643232UL, 0x4e743a3aUL, 0x1e140a0aUL, - 0xdb924949UL, 0x0a0c0606UL, 0x6c482424UL, 0xe4b85c5cUL, - 0x5d9fc2c2UL, 0x6ebdd3d3UL, 0xef43acacUL, 0xa6c46262UL, - 0xa8399191UL, 0xa4319595UL, 0x37d3e4e4UL, 0x8bf27979UL, - 0x32d5e7e7UL, 0x438bc8c8UL, 0x596e3737UL, 0xb7da6d6dUL, - 0x8c018d8dUL, 0x64b1d5d5UL, 0xd29c4e4eUL, 0xe049a9a9UL, - 0xb4d86c6cUL, 0xfaac5656UL, 0x07f3f4f4UL, 0x25cfeaeaUL, - 0xafca6565UL, 0x8ef47a7aUL, 0xe947aeaeUL, 0x18100808UL, - 0xd56fbabaUL, 0x88f07878UL, 0x6f4a2525UL, 0x725c2e2eUL, - 0x24381c1cUL, 0xf157a6a6UL, 0xc773b4b4UL, 0x5197c6c6UL, - 0x23cbe8e8UL, 0x7ca1ddddUL, 0x9ce87474UL, 0x213e1f1fUL, - 0xdd964b4bUL, 0xdc61bdbdUL, 0x860d8b8bUL, 0x850f8a8aUL, - 0x90e07070UL, 0x427c3e3eUL, 0xc471b5b5UL, 0xaacc6666UL, - 0xd8904848UL, 0x05060303UL, 0x01f7f6f6UL, 0x121c0e0eUL, - 0xa3c26161UL, 0x5f6a3535UL, 0xf9ae5757UL, 0xd069b9b9UL, - 0x91178686UL, 0x5899c1c1UL, 0x273a1d1dUL, 0xb9279e9eUL, - 0x38d9e1e1UL, 0x13ebf8f8UL, 0xb32b9898UL, 0x33221111UL, - 0xbbd26969UL, 0x70a9d9d9UL, 0x89078e8eUL, 0xa7339494UL, - 0xb62d9b9bUL, 0x223c1e1eUL, 0x92158787UL, 0x20c9e9e9UL, - 0x4987ceceUL, 0xffaa5555UL, 0x78502828UL, 0x7aa5dfdfUL, - 0x8f038c8cUL, 0xf859a1a1UL, 0x80098989UL, 0x171a0d0dUL, - 0xda65bfbfUL, 0x31d7e6e6UL, 0xc6844242UL, 0xb8d06868UL, - 0xc3824141UL, 0xb0299999UL, 0x775a2d2dUL, 0x111e0f0fUL, - 0xcb7bb0b0UL, 0xfca85454UL, 0xd66dbbbbUL, 0x3a2c1616UL, -}; -static const unsigned int Te2[256] = { - 0x63a5c663UL, 0x7c84f87cUL, 0x7799ee77UL, 0x7b8df67bUL, - 0xf20dfff2UL, 0x6bbdd66bUL, 0x6fb1de6fUL, 0xc55491c5UL, - 0x30506030UL, 0x01030201UL, 0x67a9ce67UL, 0x2b7d562bUL, - 0xfe19e7feUL, 0xd762b5d7UL, 0xabe64dabUL, 0x769aec76UL, - 0xca458fcaUL, 0x829d1f82UL, 0xc94089c9UL, 0x7d87fa7dUL, - 0xfa15effaUL, 0x59ebb259UL, 0x47c98e47UL, 0xf00bfbf0UL, - 0xadec41adUL, 0xd467b3d4UL, 0xa2fd5fa2UL, 0xafea45afUL, - 0x9cbf239cUL, 0xa4f753a4UL, 0x7296e472UL, 0xc05b9bc0UL, - 0xb7c275b7UL, 0xfd1ce1fdUL, 0x93ae3d93UL, 0x266a4c26UL, - 0x365a6c36UL, 0x3f417e3fUL, 0xf702f5f7UL, 0xcc4f83ccUL, - 0x345c6834UL, 0xa5f451a5UL, 0xe534d1e5UL, 0xf108f9f1UL, - 0x7193e271UL, 0xd873abd8UL, 0x31536231UL, 0x153f2a15UL, - 0x040c0804UL, 0xc75295c7UL, 0x23654623UL, 0xc35e9dc3UL, - 0x18283018UL, 0x96a13796UL, 0x050f0a05UL, 0x9ab52f9aUL, - 0x07090e07UL, 0x12362412UL, 0x809b1b80UL, 0xe23ddfe2UL, - 0xeb26cdebUL, 0x27694e27UL, 0xb2cd7fb2UL, 0x759fea75UL, - 0x091b1209UL, 0x839e1d83UL, 0x2c74582cUL, 0x1a2e341aUL, - 0x1b2d361bUL, 0x6eb2dc6eUL, 0x5aeeb45aUL, 0xa0fb5ba0UL, - 0x52f6a452UL, 0x3b4d763bUL, 0xd661b7d6UL, 0xb3ce7db3UL, - 0x297b5229UL, 0xe33edde3UL, 0x2f715e2fUL, 0x84971384UL, - 0x53f5a653UL, 0xd168b9d1UL, 0x00000000UL, 0xed2cc1edUL, - 0x20604020UL, 0xfc1fe3fcUL, 0xb1c879b1UL, 0x5bedb65bUL, - 0x6abed46aUL, 0xcb468dcbUL, 0xbed967beUL, 0x394b7239UL, - 0x4ade944aUL, 0x4cd4984cUL, 0x58e8b058UL, 0xcf4a85cfUL, - 0xd06bbbd0UL, 0xef2ac5efUL, 0xaae54faaUL, 0xfb16edfbUL, - 0x43c58643UL, 0x4dd79a4dUL, 0x33556633UL, 0x85941185UL, - 0x45cf8a45UL, 0xf910e9f9UL, 0x02060402UL, 0x7f81fe7fUL, - 0x50f0a050UL, 0x3c44783cUL, 0x9fba259fUL, 0xa8e34ba8UL, - 0x51f3a251UL, 0xa3fe5da3UL, 0x40c08040UL, 0x8f8a058fUL, - 0x92ad3f92UL, 0x9dbc219dUL, 0x38487038UL, 0xf504f1f5UL, - 0xbcdf63bcUL, 0xb6c177b6UL, 0xda75afdaUL, 0x21634221UL, - 0x10302010UL, 0xff1ae5ffUL, 0xf30efdf3UL, 0xd26dbfd2UL, - 0xcd4c81cdUL, 0x0c14180cUL, 0x13352613UL, 0xec2fc3ecUL, - 0x5fe1be5fUL, 0x97a23597UL, 0x44cc8844UL, 0x17392e17UL, - 0xc45793c4UL, 0xa7f255a7UL, 0x7e82fc7eUL, 0x3d477a3dUL, - 0x64acc864UL, 0x5de7ba5dUL, 0x192b3219UL, 0x7395e673UL, - 0x60a0c060UL, 0x81981981UL, 0x4fd19e4fUL, 0xdc7fa3dcUL, - 0x22664422UL, 0x2a7e542aUL, 0x90ab3b90UL, 0x88830b88UL, - 0x46ca8c46UL, 0xee29c7eeUL, 0xb8d36bb8UL, 0x143c2814UL, - 0xde79a7deUL, 0x5ee2bc5eUL, 0x0b1d160bUL, 0xdb76addbUL, - 0xe03bdbe0UL, 0x32566432UL, 0x3a4e743aUL, 0x0a1e140aUL, - 0x49db9249UL, 0x060a0c06UL, 0x246c4824UL, 0x5ce4b85cUL, - 0xc25d9fc2UL, 0xd36ebdd3UL, 0xacef43acUL, 0x62a6c462UL, - 0x91a83991UL, 0x95a43195UL, 0xe437d3e4UL, 0x798bf279UL, - 0xe732d5e7UL, 0xc8438bc8UL, 0x37596e37UL, 0x6db7da6dUL, - 0x8d8c018dUL, 0xd564b1d5UL, 0x4ed29c4eUL, 0xa9e049a9UL, - 0x6cb4d86cUL, 0x56faac56UL, 0xf407f3f4UL, 0xea25cfeaUL, - 0x65afca65UL, 0x7a8ef47aUL, 0xaee947aeUL, 0x08181008UL, - 0xbad56fbaUL, 0x7888f078UL, 0x256f4a25UL, 0x2e725c2eUL, - 0x1c24381cUL, 0xa6f157a6UL, 0xb4c773b4UL, 0xc65197c6UL, - 0xe823cbe8UL, 0xdd7ca1ddUL, 0x749ce874UL, 0x1f213e1fUL, - 0x4bdd964bUL, 0xbddc61bdUL, 0x8b860d8bUL, 0x8a850f8aUL, - 0x7090e070UL, 0x3e427c3eUL, 0xb5c471b5UL, 0x66aacc66UL, - 0x48d89048UL, 0x03050603UL, 0xf601f7f6UL, 0x0e121c0eUL, - 0x61a3c261UL, 0x355f6a35UL, 0x57f9ae57UL, 0xb9d069b9UL, - 0x86911786UL, 0xc15899c1UL, 0x1d273a1dUL, 0x9eb9279eUL, - 0xe138d9e1UL, 0xf813ebf8UL, 0x98b32b98UL, 0x11332211UL, - 0x69bbd269UL, 0xd970a9d9UL, 0x8e89078eUL, 0x94a73394UL, - 0x9bb62d9bUL, 0x1e223c1eUL, 0x87921587UL, 0xe920c9e9UL, - 0xce4987ceUL, 0x55ffaa55UL, 0x28785028UL, 0xdf7aa5dfUL, - 0x8c8f038cUL, 0xa1f859a1UL, 0x89800989UL, 0x0d171a0dUL, - 0xbfda65bfUL, 0xe631d7e6UL, 0x42c68442UL, 0x68b8d068UL, - 0x41c38241UL, 0x99b02999UL, 0x2d775a2dUL, 0x0f111e0fUL, - 0xb0cb7bb0UL, 0x54fca854UL, 0xbbd66dbbUL, 0x163a2c16UL, -}; -static const unsigned int Te3[256] = { - 0x6363a5c6UL, 0x7c7c84f8UL, 0x777799eeUL, 0x7b7b8df6UL, - 0xf2f20dffUL, 0x6b6bbdd6UL, 0x6f6fb1deUL, 0xc5c55491UL, - 0x30305060UL, 0x01010302UL, 0x6767a9ceUL, 0x2b2b7d56UL, - 0xfefe19e7UL, 0xd7d762b5UL, 0xababe64dUL, 0x76769aecUL, - 0xcaca458fUL, 0x82829d1fUL, 0xc9c94089UL, 0x7d7d87faUL, - 0xfafa15efUL, 0x5959ebb2UL, 0x4747c98eUL, 0xf0f00bfbUL, - 0xadadec41UL, 0xd4d467b3UL, 0xa2a2fd5fUL, 0xafafea45UL, - 0x9c9cbf23UL, 0xa4a4f753UL, 0x727296e4UL, 0xc0c05b9bUL, - 0xb7b7c275UL, 0xfdfd1ce1UL, 0x9393ae3dUL, 0x26266a4cUL, - 0x36365a6cUL, 0x3f3f417eUL, 0xf7f702f5UL, 0xcccc4f83UL, - 0x34345c68UL, 0xa5a5f451UL, 0xe5e534d1UL, 0xf1f108f9UL, - 0x717193e2UL, 0xd8d873abUL, 0x31315362UL, 0x15153f2aUL, - 0x04040c08UL, 0xc7c75295UL, 0x23236546UL, 0xc3c35e9dUL, - 0x18182830UL, 0x9696a137UL, 0x05050f0aUL, 0x9a9ab52fUL, - 0x0707090eUL, 0x12123624UL, 0x80809b1bUL, 0xe2e23ddfUL, - 0xebeb26cdUL, 0x2727694eUL, 0xb2b2cd7fUL, 0x75759feaUL, - 0x09091b12UL, 0x83839e1dUL, 0x2c2c7458UL, 0x1a1a2e34UL, - 0x1b1b2d36UL, 0x6e6eb2dcUL, 0x5a5aeeb4UL, 0xa0a0fb5bUL, - 0x5252f6a4UL, 0x3b3b4d76UL, 0xd6d661b7UL, 0xb3b3ce7dUL, - 0x29297b52UL, 0xe3e33eddUL, 0x2f2f715eUL, 0x84849713UL, - 0x5353f5a6UL, 0xd1d168b9UL, 0x00000000UL, 0xeded2cc1UL, - 0x20206040UL, 0xfcfc1fe3UL, 0xb1b1c879UL, 0x5b5bedb6UL, - 0x6a6abed4UL, 0xcbcb468dUL, 0xbebed967UL, 0x39394b72UL, - 0x4a4ade94UL, 0x4c4cd498UL, 0x5858e8b0UL, 0xcfcf4a85UL, - 0xd0d06bbbUL, 0xefef2ac5UL, 0xaaaae54fUL, 0xfbfb16edUL, - 0x4343c586UL, 0x4d4dd79aUL, 0x33335566UL, 0x85859411UL, - 0x4545cf8aUL, 0xf9f910e9UL, 0x02020604UL, 0x7f7f81feUL, - 0x5050f0a0UL, 0x3c3c4478UL, 0x9f9fba25UL, 0xa8a8e34bUL, - 0x5151f3a2UL, 0xa3a3fe5dUL, 0x4040c080UL, 0x8f8f8a05UL, - 0x9292ad3fUL, 0x9d9dbc21UL, 0x38384870UL, 0xf5f504f1UL, - 0xbcbcdf63UL, 0xb6b6c177UL, 0xdada75afUL, 0x21216342UL, - 0x10103020UL, 0xffff1ae5UL, 0xf3f30efdUL, 0xd2d26dbfUL, - 0xcdcd4c81UL, 0x0c0c1418UL, 0x13133526UL, 0xecec2fc3UL, - 0x5f5fe1beUL, 0x9797a235UL, 0x4444cc88UL, 0x1717392eUL, - 0xc4c45793UL, 0xa7a7f255UL, 0x7e7e82fcUL, 0x3d3d477aUL, - 0x6464acc8UL, 0x5d5de7baUL, 0x19192b32UL, 0x737395e6UL, - 0x6060a0c0UL, 0x81819819UL, 0x4f4fd19eUL, 0xdcdc7fa3UL, - 0x22226644UL, 0x2a2a7e54UL, 0x9090ab3bUL, 0x8888830bUL, - 0x4646ca8cUL, 0xeeee29c7UL, 0xb8b8d36bUL, 0x14143c28UL, - 0xdede79a7UL, 0x5e5ee2bcUL, 0x0b0b1d16UL, 0xdbdb76adUL, - 0xe0e03bdbUL, 0x32325664UL, 0x3a3a4e74UL, 0x0a0a1e14UL, - 0x4949db92UL, 0x06060a0cUL, 0x24246c48UL, 0x5c5ce4b8UL, - 0xc2c25d9fUL, 0xd3d36ebdUL, 0xacacef43UL, 0x6262a6c4UL, - 0x9191a839UL, 0x9595a431UL, 0xe4e437d3UL, 0x79798bf2UL, - 0xe7e732d5UL, 0xc8c8438bUL, 0x3737596eUL, 0x6d6db7daUL, - 0x8d8d8c01UL, 0xd5d564b1UL, 0x4e4ed29cUL, 0xa9a9e049UL, - 0x6c6cb4d8UL, 0x5656faacUL, 0xf4f407f3UL, 0xeaea25cfUL, - 0x6565afcaUL, 0x7a7a8ef4UL, 0xaeaee947UL, 0x08081810UL, - 0xbabad56fUL, 0x787888f0UL, 0x25256f4aUL, 0x2e2e725cUL, - 0x1c1c2438UL, 0xa6a6f157UL, 0xb4b4c773UL, 0xc6c65197UL, - 0xe8e823cbUL, 0xdddd7ca1UL, 0x74749ce8UL, 0x1f1f213eUL, - 0x4b4bdd96UL, 0xbdbddc61UL, 0x8b8b860dUL, 0x8a8a850fUL, - 0x707090e0UL, 0x3e3e427cUL, 0xb5b5c471UL, 0x6666aaccUL, - 0x4848d890UL, 0x03030506UL, 0xf6f601f7UL, 0x0e0e121cUL, - 0x6161a3c2UL, 0x35355f6aUL, 0x5757f9aeUL, 0xb9b9d069UL, - 0x86869117UL, 0xc1c15899UL, 0x1d1d273aUL, 0x9e9eb927UL, - 0xe1e138d9UL, 0xf8f813ebUL, 0x9898b32bUL, 0x11113322UL, - 0x6969bbd2UL, 0xd9d970a9UL, 0x8e8e8907UL, 0x9494a733UL, - 0x9b9bb62dUL, 0x1e1e223cUL, 0x87879215UL, 0xe9e920c9UL, - 0xcece4987UL, 0x5555ffaaUL, 0x28287850UL, 0xdfdf7aa5UL, - 0x8c8c8f03UL, 0xa1a1f859UL, 0x89898009UL, 0x0d0d171aUL, - 0xbfbfda65UL, 0xe6e631d7UL, 0x4242c684UL, 0x6868b8d0UL, - 0x4141c382UL, 0x9999b029UL, 0x2d2d775aUL, 0x0f0f111eUL, - 0xb0b0cb7bUL, 0x5454fca8UL, 0xbbbbd66dUL, 0x16163a2cUL, -}; -static const unsigned int Te4[256] = { - 0x63636363UL, 0x7c7c7c7cUL, 0x77777777UL, 0x7b7b7b7bUL, - 0xf2f2f2f2UL, 0x6b6b6b6bUL, 0x6f6f6f6fUL, 0xc5c5c5c5UL, - 0x30303030UL, 0x01010101UL, 0x67676767UL, 0x2b2b2b2bUL, - 0xfefefefeUL, 0xd7d7d7d7UL, 0xababababUL, 0x76767676UL, - 0xcacacacaUL, 0x82828282UL, 0xc9c9c9c9UL, 0x7d7d7d7dUL, - 0xfafafafaUL, 0x59595959UL, 0x47474747UL, 0xf0f0f0f0UL, - 0xadadadadUL, 0xd4d4d4d4UL, 0xa2a2a2a2UL, 0xafafafafUL, - 0x9c9c9c9cUL, 0xa4a4a4a4UL, 0x72727272UL, 0xc0c0c0c0UL, - 0xb7b7b7b7UL, 0xfdfdfdfdUL, 0x93939393UL, 0x26262626UL, - 0x36363636UL, 0x3f3f3f3fUL, 0xf7f7f7f7UL, 0xccccccccUL, - 0x34343434UL, 0xa5a5a5a5UL, 0xe5e5e5e5UL, 0xf1f1f1f1UL, - 0x71717171UL, 0xd8d8d8d8UL, 0x31313131UL, 0x15151515UL, - 0x04040404UL, 0xc7c7c7c7UL, 0x23232323UL, 0xc3c3c3c3UL, - 0x18181818UL, 0x96969696UL, 0x05050505UL, 0x9a9a9a9aUL, - 0x07070707UL, 0x12121212UL, 0x80808080UL, 0xe2e2e2e2UL, - 0xebebebebUL, 0x27272727UL, 0xb2b2b2b2UL, 0x75757575UL, - 0x09090909UL, 0x83838383UL, 0x2c2c2c2cUL, 0x1a1a1a1aUL, - 0x1b1b1b1bUL, 0x6e6e6e6eUL, 0x5a5a5a5aUL, 0xa0a0a0a0UL, - 0x52525252UL, 0x3b3b3b3bUL, 0xd6d6d6d6UL, 0xb3b3b3b3UL, - 0x29292929UL, 0xe3e3e3e3UL, 0x2f2f2f2fUL, 0x84848484UL, - 0x53535353UL, 0xd1d1d1d1UL, 0x00000000UL, 0xededededUL, - 0x20202020UL, 0xfcfcfcfcUL, 0xb1b1b1b1UL, 0x5b5b5b5bUL, - 0x6a6a6a6aUL, 0xcbcbcbcbUL, 0xbebebebeUL, 0x39393939UL, - 0x4a4a4a4aUL, 0x4c4c4c4cUL, 0x58585858UL, 0xcfcfcfcfUL, - 0xd0d0d0d0UL, 0xefefefefUL, 0xaaaaaaaaUL, 0xfbfbfbfbUL, - 0x43434343UL, 0x4d4d4d4dUL, 0x33333333UL, 0x85858585UL, - 0x45454545UL, 0xf9f9f9f9UL, 0x02020202UL, 0x7f7f7f7fUL, - 0x50505050UL, 0x3c3c3c3cUL, 0x9f9f9f9fUL, 0xa8a8a8a8UL, - 0x51515151UL, 0xa3a3a3a3UL, 0x40404040UL, 0x8f8f8f8fUL, - 0x92929292UL, 0x9d9d9d9dUL, 0x38383838UL, 0xf5f5f5f5UL, - 0xbcbcbcbcUL, 0xb6b6b6b6UL, 0xdadadadaUL, 0x21212121UL, - 0x10101010UL, 0xffffffffUL, 0xf3f3f3f3UL, 0xd2d2d2d2UL, - 0xcdcdcdcdUL, 0x0c0c0c0cUL, 0x13131313UL, 0xececececUL, - 0x5f5f5f5fUL, 0x97979797UL, 0x44444444UL, 0x17171717UL, - 0xc4c4c4c4UL, 0xa7a7a7a7UL, 0x7e7e7e7eUL, 0x3d3d3d3dUL, - 0x64646464UL, 0x5d5d5d5dUL, 0x19191919UL, 0x73737373UL, - 0x60606060UL, 0x81818181UL, 0x4f4f4f4fUL, 0xdcdcdcdcUL, - 0x22222222UL, 0x2a2a2a2aUL, 0x90909090UL, 0x88888888UL, - 0x46464646UL, 0xeeeeeeeeUL, 0xb8b8b8b8UL, 0x14141414UL, - 0xdedededeUL, 0x5e5e5e5eUL, 0x0b0b0b0bUL, 0xdbdbdbdbUL, - 0xe0e0e0e0UL, 0x32323232UL, 0x3a3a3a3aUL, 0x0a0a0a0aUL, - 0x49494949UL, 0x06060606UL, 0x24242424UL, 0x5c5c5c5cUL, - 0xc2c2c2c2UL, 0xd3d3d3d3UL, 0xacacacacUL, 0x62626262UL, - 0x91919191UL, 0x95959595UL, 0xe4e4e4e4UL, 0x79797979UL, - 0xe7e7e7e7UL, 0xc8c8c8c8UL, 0x37373737UL, 0x6d6d6d6dUL, - 0x8d8d8d8dUL, 0xd5d5d5d5UL, 0x4e4e4e4eUL, 0xa9a9a9a9UL, - 0x6c6c6c6cUL, 0x56565656UL, 0xf4f4f4f4UL, 0xeaeaeaeaUL, - 0x65656565UL, 0x7a7a7a7aUL, 0xaeaeaeaeUL, 0x08080808UL, - 0xbabababaUL, 0x78787878UL, 0x25252525UL, 0x2e2e2e2eUL, - 0x1c1c1c1cUL, 0xa6a6a6a6UL, 0xb4b4b4b4UL, 0xc6c6c6c6UL, - 0xe8e8e8e8UL, 0xddddddddUL, 0x74747474UL, 0x1f1f1f1fUL, - 0x4b4b4b4bUL, 0xbdbdbdbdUL, 0x8b8b8b8bUL, 0x8a8a8a8aUL, - 0x70707070UL, 0x3e3e3e3eUL, 0xb5b5b5b5UL, 0x66666666UL, - 0x48484848UL, 0x03030303UL, 0xf6f6f6f6UL, 0x0e0e0e0eUL, - 0x61616161UL, 0x35353535UL, 0x57575757UL, 0xb9b9b9b9UL, - 0x86868686UL, 0xc1c1c1c1UL, 0x1d1d1d1dUL, 0x9e9e9e9eUL, - 0xe1e1e1e1UL, 0xf8f8f8f8UL, 0x98989898UL, 0x11111111UL, - 0x69696969UL, 0xd9d9d9d9UL, 0x8e8e8e8eUL, 0x94949494UL, - 0x9b9b9b9bUL, 0x1e1e1e1eUL, 0x87878787UL, 0xe9e9e9e9UL, - 0xcecececeUL, 0x55555555UL, 0x28282828UL, 0xdfdfdfdfUL, - 0x8c8c8c8cUL, 0xa1a1a1a1UL, 0x89898989UL, 0x0d0d0d0dUL, - 0xbfbfbfbfUL, 0xe6e6e6e6UL, 0x42424242UL, 0x68686868UL, - 0x41414141UL, 0x99999999UL, 0x2d2d2d2dUL, 0x0f0f0f0fUL, - 0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL, -}; -static const unsigned int Td0[256] = { - 0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL, - 0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL, - 0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL, - 0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL, - 0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL, - 0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL, - 0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL, - 0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL, - 0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL, - 0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL, - 0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL, - 0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL, - 0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL, - 0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL, - 0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL, - 0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL, - 0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL, - 0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL, - 0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL, - 0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL, - 0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL, - 0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL, - 0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL, - 0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL, - 0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL, - 0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL, - 0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL, - 0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL, - 0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL, - 0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL, - 0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL, - 0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL, - 0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL, - 0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL, - 0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL, - 0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL, - 0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL, - 0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL, - 0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL, - 0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL, - 0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL, - 0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL, - 0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL, - 0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL, - 0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL, - 0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL, - 0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL, - 0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL, - 0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL, - 0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL, - 0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL, - 0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL, - 0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL, - 0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL, - 0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL, - 0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL, - 0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL, - 0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL, - 0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL, - 0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL, - 0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL, - 0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL, - 0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL, - 0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL, -}; -static const unsigned int Td1[256] = { - 0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL, - 0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL, - 0x552030faUL, 0xf6ad766dUL, 0x9188cc76UL, 0x25f5024cUL, - 0xfc4fe5d7UL, 0xd7c52acbUL, 0x80263544UL, 0x8fb562a3UL, - 0x49deb15aUL, 0x6725ba1bUL, 0x9845ea0eUL, 0xe15dfec0UL, - 0x02c32f75UL, 0x12814cf0UL, 0xa38d4697UL, 0xc66bd3f9UL, - 0xe7038f5fUL, 0x9515929cUL, 0xebbf6d7aUL, 0xda955259UL, - 0x2dd4be83UL, 0xd3587421UL, 0x2949e069UL, 0x448ec9c8UL, - 0x6a75c289UL, 0x78f48e79UL, 0x6b99583eUL, 0xdd27b971UL, - 0xb6bee14fUL, 0x17f088adUL, 0x66c920acUL, 0xb47dce3aUL, - 0x1863df4aUL, 0x82e51a31UL, 0x60975133UL, 0x4562537fUL, - 0xe0b16477UL, 0x84bb6baeUL, 0x1cfe81a0UL, 0x94f9082bUL, - 0x58704868UL, 0x198f45fdUL, 0x8794de6cUL, 0xb7527bf8UL, - 0x23ab73d3UL, 0xe2724b02UL, 0x57e31f8fUL, 0x2a6655abUL, - 0x07b2eb28UL, 0x032fb5c2UL, 0x9a86c57bUL, 0xa5d33708UL, - 0xf2302887UL, 0xb223bfa5UL, 0xba02036aUL, 0x5ced1682UL, - 0x2b8acf1cUL, 0x92a779b4UL, 0xf0f307f2UL, 0xa14e69e2UL, - 0xcd65daf4UL, 0xd50605beUL, 0x1fd13462UL, 0x8ac4a6feUL, - 0x9d342e53UL, 0xa0a2f355UL, 0x32058ae1UL, 0x75a4f6ebUL, - 0x390b83ecUL, 0xaa4060efUL, 0x065e719fUL, 0x51bd6e10UL, - 0xf93e218aUL, 0x3d96dd06UL, 0xaedd3e05UL, 0x464de6bdUL, - 0xb591548dUL, 0x0571c45dUL, 0x6f0406d4UL, 0xff605015UL, - 0x241998fbUL, 0x97d6bde9UL, 0xcc894043UL, 0x7767d99eUL, - 0xbdb0e842UL, 0x8807898bUL, 0x38e7195bUL, 0xdb79c8eeUL, - 0x47a17c0aUL, 0xe97c420fUL, 0xc9f8841eUL, 0x00000000UL, - 0x83098086UL, 0x48322bedUL, 0xac1e1170UL, 0x4e6c5a72UL, - 0xfbfd0effUL, 0x560f8538UL, 0x1e3daed5UL, 0x27362d39UL, - 0x640a0fd9UL, 0x21685ca6UL, 0xd19b5b54UL, 0x3a24362eUL, - 0xb10c0a67UL, 0x0f9357e7UL, 0xd2b4ee96UL, 0x9e1b9b91UL, - 0x4f80c0c5UL, 0xa261dc20UL, 0x695a774bUL, 0x161c121aUL, - 0x0ae293baUL, 0xe5c0a02aUL, 0x433c22e0UL, 0x1d121b17UL, - 0x0b0e090dUL, 0xadf28bc7UL, 0xb92db6a8UL, 0xc8141ea9UL, - 0x8557f119UL, 0x4caf7507UL, 0xbbee99ddUL, 0xfda37f60UL, - 0x9ff70126UL, 0xbc5c72f5UL, 0xc544663bUL, 0x345bfb7eUL, - 0x768b4329UL, 0xdccb23c6UL, 0x68b6edfcUL, 0x63b8e4f1UL, - 0xcad731dcUL, 0x10426385UL, 0x40139722UL, 0x2084c611UL, - 0x7d854a24UL, 0xf8d2bb3dUL, 0x11aef932UL, 0x6dc729a1UL, - 0x4b1d9e2fUL, 0xf3dcb230UL, 0xec0d8652UL, 0xd077c1e3UL, - 0x6c2bb316UL, 0x99a970b9UL, 0xfa119448UL, 0x2247e964UL, - 0xc4a8fc8cUL, 0x1aa0f03fUL, 0xd8567d2cUL, 0xef223390UL, - 0xc787494eUL, 0xc1d938d1UL, 0xfe8ccaa2UL, 0x3698d40bUL, - 0xcfa6f581UL, 0x28a57adeUL, 0x26dab78eUL, 0xa43fadbfUL, - 0xe42c3a9dUL, 0x0d507892UL, 0x9b6a5fccUL, 0x62547e46UL, - 0xc2f68d13UL, 0xe890d8b8UL, 0x5e2e39f7UL, 0xf582c3afUL, - 0xbe9f5d80UL, 0x7c69d093UL, 0xa96fd52dUL, 0xb3cf2512UL, - 0x3bc8ac99UL, 0xa710187dUL, 0x6ee89c63UL, 0x7bdb3bbbUL, - 0x09cd2678UL, 0xf46e5918UL, 0x01ec9ab7UL, 0xa8834f9aUL, - 0x65e6956eUL, 0x7eaaffe6UL, 0x0821bccfUL, 0xe6ef15e8UL, - 0xd9bae79bUL, 0xce4a6f36UL, 0xd4ea9f09UL, 0xd629b07cUL, - 0xaf31a4b2UL, 0x312a3f23UL, 0x30c6a594UL, 0xc035a266UL, - 0x37744ebcUL, 0xa6fc82caUL, 0xb0e090d0UL, 0x1533a7d8UL, - 0x4af10498UL, 0xf741ecdaUL, 0x0e7fcd50UL, 0x2f1791f6UL, - 0x8d764dd6UL, 0x4d43efb0UL, 0x54ccaa4dUL, 0xdfe49604UL, - 0xe39ed1b5UL, 0x1b4c6a88UL, 0xb8c12c1fUL, 0x7f466551UL, - 0x049d5eeaUL, 0x5d018c35UL, 0x73fa8774UL, 0x2efb0b41UL, - 0x5ab3671dUL, 0x5292dbd2UL, 0x33e91056UL, 0x136dd647UL, - 0x8c9ad761UL, 0x7a37a10cUL, 0x8e59f814UL, 0x89eb133cUL, - 0xeecea927UL, 0x35b761c9UL, 0xede11ce5UL, 0x3c7a47b1UL, - 0x599cd2dfUL, 0x3f55f273UL, 0x791814ceUL, 0xbf73c737UL, - 0xea53f7cdUL, 0x5b5ffdaaUL, 0x14df3d6fUL, 0x867844dbUL, - 0x81caaff3UL, 0x3eb968c4UL, 0x2c382434UL, 0x5fc2a340UL, - 0x72161dc3UL, 0x0cbce225UL, 0x8b283c49UL, 0x41ff0d95UL, - 0x7139a801UL, 0xde080cb3UL, 0x9cd8b4e4UL, 0x906456c1UL, - 0x617bcb84UL, 0x70d532b6UL, 0x74486c5cUL, 0x42d0b857UL, -}; -static const unsigned int Td2[256] = { - 0xa75051f4UL, 0x65537e41UL, 0xa4c31a17UL, 0x5e963a27UL, - 0x6bcb3babUL, 0x45f11f9dUL, 0x58abacfaUL, 0x03934be3UL, - 0xfa552030UL, 0x6df6ad76UL, 0x769188ccUL, 0x4c25f502UL, - 0xd7fc4fe5UL, 0xcbd7c52aUL, 0x44802635UL, 0xa38fb562UL, - 0x5a49deb1UL, 0x1b6725baUL, 0x0e9845eaUL, 0xc0e15dfeUL, - 0x7502c32fUL, 0xf012814cUL, 0x97a38d46UL, 0xf9c66bd3UL, - 0x5fe7038fUL, 0x9c951592UL, 0x7aebbf6dUL, 0x59da9552UL, - 0x832dd4beUL, 0x21d35874UL, 0x692949e0UL, 0xc8448ec9UL, - 0x896a75c2UL, 0x7978f48eUL, 0x3e6b9958UL, 0x71dd27b9UL, - 0x4fb6bee1UL, 0xad17f088UL, 0xac66c920UL, 0x3ab47dceUL, - 0x4a1863dfUL, 0x3182e51aUL, 0x33609751UL, 0x7f456253UL, - 0x77e0b164UL, 0xae84bb6bUL, 0xa01cfe81UL, 0x2b94f908UL, - 0x68587048UL, 0xfd198f45UL, 0x6c8794deUL, 0xf8b7527bUL, - 0xd323ab73UL, 0x02e2724bUL, 0x8f57e31fUL, 0xab2a6655UL, - 0x2807b2ebUL, 0xc2032fb5UL, 0x7b9a86c5UL, 0x08a5d337UL, - 0x87f23028UL, 0xa5b223bfUL, 0x6aba0203UL, 0x825ced16UL, - 0x1c2b8acfUL, 0xb492a779UL, 0xf2f0f307UL, 0xe2a14e69UL, - 0xf4cd65daUL, 0xbed50605UL, 0x621fd134UL, 0xfe8ac4a6UL, - 0x539d342eUL, 0x55a0a2f3UL, 0xe132058aUL, 0xeb75a4f6UL, - 0xec390b83UL, 0xefaa4060UL, 0x9f065e71UL, 0x1051bd6eUL, - 0x8af93e21UL, 0x063d96ddUL, 0x05aedd3eUL, 0xbd464de6UL, - 0x8db59154UL, 0x5d0571c4UL, 0xd46f0406UL, 0x15ff6050UL, - 0xfb241998UL, 0xe997d6bdUL, 0x43cc8940UL, 0x9e7767d9UL, - 0x42bdb0e8UL, 0x8b880789UL, 0x5b38e719UL, 0xeedb79c8UL, - 0x0a47a17cUL, 0x0fe97c42UL, 0x1ec9f884UL, 0x00000000UL, - 0x86830980UL, 0xed48322bUL, 0x70ac1e11UL, 0x724e6c5aUL, - 0xfffbfd0eUL, 0x38560f85UL, 0xd51e3daeUL, 0x3927362dUL, - 0xd9640a0fUL, 0xa621685cUL, 0x54d19b5bUL, 0x2e3a2436UL, - 0x67b10c0aUL, 0xe70f9357UL, 0x96d2b4eeUL, 0x919e1b9bUL, - 0xc54f80c0UL, 0x20a261dcUL, 0x4b695a77UL, 0x1a161c12UL, - 0xba0ae293UL, 0x2ae5c0a0UL, 0xe0433c22UL, 0x171d121bUL, - 0x0d0b0e09UL, 0xc7adf28bUL, 0xa8b92db6UL, 0xa9c8141eUL, - 0x198557f1UL, 0x074caf75UL, 0xddbbee99UL, 0x60fda37fUL, - 0x269ff701UL, 0xf5bc5c72UL, 0x3bc54466UL, 0x7e345bfbUL, - 0x29768b43UL, 0xc6dccb23UL, 0xfc68b6edUL, 0xf163b8e4UL, - 0xdccad731UL, 0x85104263UL, 0x22401397UL, 0x112084c6UL, - 0x247d854aUL, 0x3df8d2bbUL, 0x3211aef9UL, 0xa16dc729UL, - 0x2f4b1d9eUL, 0x30f3dcb2UL, 0x52ec0d86UL, 0xe3d077c1UL, - 0x166c2bb3UL, 0xb999a970UL, 0x48fa1194UL, 0x642247e9UL, - 0x8cc4a8fcUL, 0x3f1aa0f0UL, 0x2cd8567dUL, 0x90ef2233UL, - 0x4ec78749UL, 0xd1c1d938UL, 0xa2fe8ccaUL, 0x0b3698d4UL, - 0x81cfa6f5UL, 0xde28a57aUL, 0x8e26dab7UL, 0xbfa43fadUL, - 0x9de42c3aUL, 0x920d5078UL, 0xcc9b6a5fUL, 0x4662547eUL, - 0x13c2f68dUL, 0xb8e890d8UL, 0xf75e2e39UL, 0xaff582c3UL, - 0x80be9f5dUL, 0x937c69d0UL, 0x2da96fd5UL, 0x12b3cf25UL, - 0x993bc8acUL, 0x7da71018UL, 0x636ee89cUL, 0xbb7bdb3bUL, - 0x7809cd26UL, 0x18f46e59UL, 0xb701ec9aUL, 0x9aa8834fUL, - 0x6e65e695UL, 0xe67eaaffUL, 0xcf0821bcUL, 0xe8e6ef15UL, - 0x9bd9bae7UL, 0x36ce4a6fUL, 0x09d4ea9fUL, 0x7cd629b0UL, - 0xb2af31a4UL, 0x23312a3fUL, 0x9430c6a5UL, 0x66c035a2UL, - 0xbc37744eUL, 0xcaa6fc82UL, 0xd0b0e090UL, 0xd81533a7UL, - 0x984af104UL, 0xdaf741ecUL, 0x500e7fcdUL, 0xf62f1791UL, - 0xd68d764dUL, 0xb04d43efUL, 0x4d54ccaaUL, 0x04dfe496UL, - 0xb5e39ed1UL, 0x881b4c6aUL, 0x1fb8c12cUL, 0x517f4665UL, - 0xea049d5eUL, 0x355d018cUL, 0x7473fa87UL, 0x412efb0bUL, - 0x1d5ab367UL, 0xd25292dbUL, 0x5633e910UL, 0x47136dd6UL, - 0x618c9ad7UL, 0x0c7a37a1UL, 0x148e59f8UL, 0x3c89eb13UL, - 0x27eecea9UL, 0xc935b761UL, 0xe5ede11cUL, 0xb13c7a47UL, - 0xdf599cd2UL, 0x733f55f2UL, 0xce791814UL, 0x37bf73c7UL, - 0xcdea53f7UL, 0xaa5b5ffdUL, 0x6f14df3dUL, 0xdb867844UL, - 0xf381caafUL, 0xc43eb968UL, 0x342c3824UL, 0x405fc2a3UL, - 0xc372161dUL, 0x250cbce2UL, 0x498b283cUL, 0x9541ff0dUL, - 0x017139a8UL, 0xb3de080cUL, 0xe49cd8b4UL, 0xc1906456UL, - 0x84617bcbUL, 0xb670d532UL, 0x5c74486cUL, 0x5742d0b8UL, -}; -static const unsigned int Td3[256] = { - 0xf4a75051UL, 0x4165537eUL, 0x17a4c31aUL, 0x275e963aUL, - 0xab6bcb3bUL, 0x9d45f11fUL, 0xfa58abacUL, 0xe303934bUL, - 0x30fa5520UL, 0x766df6adUL, 0xcc769188UL, 0x024c25f5UL, - 0xe5d7fc4fUL, 0x2acbd7c5UL, 0x35448026UL, 0x62a38fb5UL, - 0xb15a49deUL, 0xba1b6725UL, 0xea0e9845UL, 0xfec0e15dUL, - 0x2f7502c3UL, 0x4cf01281UL, 0x4697a38dUL, 0xd3f9c66bUL, - 0x8f5fe703UL, 0x929c9515UL, 0x6d7aebbfUL, 0x5259da95UL, - 0xbe832dd4UL, 0x7421d358UL, 0xe0692949UL, 0xc9c8448eUL, - 0xc2896a75UL, 0x8e7978f4UL, 0x583e6b99UL, 0xb971dd27UL, - 0xe14fb6beUL, 0x88ad17f0UL, 0x20ac66c9UL, 0xce3ab47dUL, - 0xdf4a1863UL, 0x1a3182e5UL, 0x51336097UL, 0x537f4562UL, - 0x6477e0b1UL, 0x6bae84bbUL, 0x81a01cfeUL, 0x082b94f9UL, - 0x48685870UL, 0x45fd198fUL, 0xde6c8794UL, 0x7bf8b752UL, - 0x73d323abUL, 0x4b02e272UL, 0x1f8f57e3UL, 0x55ab2a66UL, - 0xeb2807b2UL, 0xb5c2032fUL, 0xc57b9a86UL, 0x3708a5d3UL, - 0x2887f230UL, 0xbfa5b223UL, 0x036aba02UL, 0x16825cedUL, - 0xcf1c2b8aUL, 0x79b492a7UL, 0x07f2f0f3UL, 0x69e2a14eUL, - 0xdaf4cd65UL, 0x05bed506UL, 0x34621fd1UL, 0xa6fe8ac4UL, - 0x2e539d34UL, 0xf355a0a2UL, 0x8ae13205UL, 0xf6eb75a4UL, - 0x83ec390bUL, 0x60efaa40UL, 0x719f065eUL, 0x6e1051bdUL, - 0x218af93eUL, 0xdd063d96UL, 0x3e05aeddUL, 0xe6bd464dUL, - 0x548db591UL, 0xc45d0571UL, 0x06d46f04UL, 0x5015ff60UL, - 0x98fb2419UL, 0xbde997d6UL, 0x4043cc89UL, 0xd99e7767UL, - 0xe842bdb0UL, 0x898b8807UL, 0x195b38e7UL, 0xc8eedb79UL, - 0x7c0a47a1UL, 0x420fe97cUL, 0x841ec9f8UL, 0x00000000UL, - 0x80868309UL, 0x2bed4832UL, 0x1170ac1eUL, 0x5a724e6cUL, - 0x0efffbfdUL, 0x8538560fUL, 0xaed51e3dUL, 0x2d392736UL, - 0x0fd9640aUL, 0x5ca62168UL, 0x5b54d19bUL, 0x362e3a24UL, - 0x0a67b10cUL, 0x57e70f93UL, 0xee96d2b4UL, 0x9b919e1bUL, - 0xc0c54f80UL, 0xdc20a261UL, 0x774b695aUL, 0x121a161cUL, - 0x93ba0ae2UL, 0xa02ae5c0UL, 0x22e0433cUL, 0x1b171d12UL, - 0x090d0b0eUL, 0x8bc7adf2UL, 0xb6a8b92dUL, 0x1ea9c814UL, - 0xf1198557UL, 0x75074cafUL, 0x99ddbbeeUL, 0x7f60fda3UL, - 0x01269ff7UL, 0x72f5bc5cUL, 0x663bc544UL, 0xfb7e345bUL, - 0x4329768bUL, 0x23c6dccbUL, 0xedfc68b6UL, 0xe4f163b8UL, - 0x31dccad7UL, 0x63851042UL, 0x97224013UL, 0xc6112084UL, - 0x4a247d85UL, 0xbb3df8d2UL, 0xf93211aeUL, 0x29a16dc7UL, - 0x9e2f4b1dUL, 0xb230f3dcUL, 0x8652ec0dUL, 0xc1e3d077UL, - 0xb3166c2bUL, 0x70b999a9UL, 0x9448fa11UL, 0xe9642247UL, - 0xfc8cc4a8UL, 0xf03f1aa0UL, 0x7d2cd856UL, 0x3390ef22UL, - 0x494ec787UL, 0x38d1c1d9UL, 0xcaa2fe8cUL, 0xd40b3698UL, - 0xf581cfa6UL, 0x7ade28a5UL, 0xb78e26daUL, 0xadbfa43fUL, - 0x3a9de42cUL, 0x78920d50UL, 0x5fcc9b6aUL, 0x7e466254UL, - 0x8d13c2f6UL, 0xd8b8e890UL, 0x39f75e2eUL, 0xc3aff582UL, - 0x5d80be9fUL, 0xd0937c69UL, 0xd52da96fUL, 0x2512b3cfUL, - 0xac993bc8UL, 0x187da710UL, 0x9c636ee8UL, 0x3bbb7bdbUL, - 0x267809cdUL, 0x5918f46eUL, 0x9ab701ecUL, 0x4f9aa883UL, - 0x956e65e6UL, 0xffe67eaaUL, 0xbccf0821UL, 0x15e8e6efUL, - 0xe79bd9baUL, 0x6f36ce4aUL, 0x9f09d4eaUL, 0xb07cd629UL, - 0xa4b2af31UL, 0x3f23312aUL, 0xa59430c6UL, 0xa266c035UL, - 0x4ebc3774UL, 0x82caa6fcUL, 0x90d0b0e0UL, 0xa7d81533UL, - 0x04984af1UL, 0xecdaf741UL, 0xcd500e7fUL, 0x91f62f17UL, - 0x4dd68d76UL, 0xefb04d43UL, 0xaa4d54ccUL, 0x9604dfe4UL, - 0xd1b5e39eUL, 0x6a881b4cUL, 0x2c1fb8c1UL, 0x65517f46UL, - 0x5eea049dUL, 0x8c355d01UL, 0x877473faUL, 0x0b412efbUL, - 0x671d5ab3UL, 0xdbd25292UL, 0x105633e9UL, 0xd647136dUL, - 0xd7618c9aUL, 0xa10c7a37UL, 0xf8148e59UL, 0x133c89ebUL, - 0xa927eeceUL, 0x61c935b7UL, 0x1ce5ede1UL, 0x47b13c7aUL, - 0xd2df599cUL, 0xf2733f55UL, 0x14ce7918UL, 0xc737bf73UL, - 0xf7cdea53UL, 0xfdaa5b5fUL, 0x3d6f14dfUL, 0x44db8678UL, - 0xaff381caUL, 0x68c43eb9UL, 0x24342c38UL, 0xa3405fc2UL, - 0x1dc37216UL, 0xe2250cbcUL, 0x3c498b28UL, 0x0d9541ffUL, - 0xa8017139UL, 0x0cb3de08UL, 0xb4e49cd8UL, 0x56c19064UL, - 0xcb84617bUL, 0x32b670d5UL, 0x6c5c7448UL, 0xb85742d0UL, -}; -static const unsigned int Td4[256] = { - 0x52525252UL, 0x09090909UL, 0x6a6a6a6aUL, 0xd5d5d5d5UL, - 0x30303030UL, 0x36363636UL, 0xa5a5a5a5UL, 0x38383838UL, - 0xbfbfbfbfUL, 0x40404040UL, 0xa3a3a3a3UL, 0x9e9e9e9eUL, - 0x81818181UL, 0xf3f3f3f3UL, 0xd7d7d7d7UL, 0xfbfbfbfbUL, - 0x7c7c7c7cUL, 0xe3e3e3e3UL, 0x39393939UL, 0x82828282UL, - 0x9b9b9b9bUL, 0x2f2f2f2fUL, 0xffffffffUL, 0x87878787UL, - 0x34343434UL, 0x8e8e8e8eUL, 0x43434343UL, 0x44444444UL, - 0xc4c4c4c4UL, 0xdedededeUL, 0xe9e9e9e9UL, 0xcbcbcbcbUL, - 0x54545454UL, 0x7b7b7b7bUL, 0x94949494UL, 0x32323232UL, - 0xa6a6a6a6UL, 0xc2c2c2c2UL, 0x23232323UL, 0x3d3d3d3dUL, - 0xeeeeeeeeUL, 0x4c4c4c4cUL, 0x95959595UL, 0x0b0b0b0bUL, - 0x42424242UL, 0xfafafafaUL, 0xc3c3c3c3UL, 0x4e4e4e4eUL, - 0x08080808UL, 0x2e2e2e2eUL, 0xa1a1a1a1UL, 0x66666666UL, - 0x28282828UL, 0xd9d9d9d9UL, 0x24242424UL, 0xb2b2b2b2UL, - 0x76767676UL, 0x5b5b5b5bUL, 0xa2a2a2a2UL, 0x49494949UL, - 0x6d6d6d6dUL, 0x8b8b8b8bUL, 0xd1d1d1d1UL, 0x25252525UL, - 0x72727272UL, 0xf8f8f8f8UL, 0xf6f6f6f6UL, 0x64646464UL, - 0x86868686UL, 0x68686868UL, 0x98989898UL, 0x16161616UL, - 0xd4d4d4d4UL, 0xa4a4a4a4UL, 0x5c5c5c5cUL, 0xccccccccUL, - 0x5d5d5d5dUL, 0x65656565UL, 0xb6b6b6b6UL, 0x92929292UL, - 0x6c6c6c6cUL, 0x70707070UL, 0x48484848UL, 0x50505050UL, - 0xfdfdfdfdUL, 0xededededUL, 0xb9b9b9b9UL, 0xdadadadaUL, - 0x5e5e5e5eUL, 0x15151515UL, 0x46464646UL, 0x57575757UL, - 0xa7a7a7a7UL, 0x8d8d8d8dUL, 0x9d9d9d9dUL, 0x84848484UL, - 0x90909090UL, 0xd8d8d8d8UL, 0xababababUL, 0x00000000UL, - 0x8c8c8c8cUL, 0xbcbcbcbcUL, 0xd3d3d3d3UL, 0x0a0a0a0aUL, - 0xf7f7f7f7UL, 0xe4e4e4e4UL, 0x58585858UL, 0x05050505UL, - 0xb8b8b8b8UL, 0xb3b3b3b3UL, 0x45454545UL, 0x06060606UL, - 0xd0d0d0d0UL, 0x2c2c2c2cUL, 0x1e1e1e1eUL, 0x8f8f8f8fUL, - 0xcacacacaUL, 0x3f3f3f3fUL, 0x0f0f0f0fUL, 0x02020202UL, - 0xc1c1c1c1UL, 0xafafafafUL, 0xbdbdbdbdUL, 0x03030303UL, - 0x01010101UL, 0x13131313UL, 0x8a8a8a8aUL, 0x6b6b6b6bUL, - 0x3a3a3a3aUL, 0x91919191UL, 0x11111111UL, 0x41414141UL, - 0x4f4f4f4fUL, 0x67676767UL, 0xdcdcdcdcUL, 0xeaeaeaeaUL, - 0x97979797UL, 0xf2f2f2f2UL, 0xcfcfcfcfUL, 0xcecececeUL, - 0xf0f0f0f0UL, 0xb4b4b4b4UL, 0xe6e6e6e6UL, 0x73737373UL, - 0x96969696UL, 0xacacacacUL, 0x74747474UL, 0x22222222UL, - 0xe7e7e7e7UL, 0xadadadadUL, 0x35353535UL, 0x85858585UL, - 0xe2e2e2e2UL, 0xf9f9f9f9UL, 0x37373737UL, 0xe8e8e8e8UL, - 0x1c1c1c1cUL, 0x75757575UL, 0xdfdfdfdfUL, 0x6e6e6e6eUL, - 0x47474747UL, 0xf1f1f1f1UL, 0x1a1a1a1aUL, 0x71717171UL, - 0x1d1d1d1dUL, 0x29292929UL, 0xc5c5c5c5UL, 0x89898989UL, - 0x6f6f6f6fUL, 0xb7b7b7b7UL, 0x62626262UL, 0x0e0e0e0eUL, - 0xaaaaaaaaUL, 0x18181818UL, 0xbebebebeUL, 0x1b1b1b1bUL, - 0xfcfcfcfcUL, 0x56565656UL, 0x3e3e3e3eUL, 0x4b4b4b4bUL, - 0xc6c6c6c6UL, 0xd2d2d2d2UL, 0x79797979UL, 0x20202020UL, - 0x9a9a9a9aUL, 0xdbdbdbdbUL, 0xc0c0c0c0UL, 0xfefefefeUL, - 0x78787878UL, 0xcdcdcdcdUL, 0x5a5a5a5aUL, 0xf4f4f4f4UL, - 0x1f1f1f1fUL, 0xddddddddUL, 0xa8a8a8a8UL, 0x33333333UL, - 0x88888888UL, 0x07070707UL, 0xc7c7c7c7UL, 0x31313131UL, - 0xb1b1b1b1UL, 0x12121212UL, 0x10101010UL, 0x59595959UL, - 0x27272727UL, 0x80808080UL, 0xececececUL, 0x5f5f5f5fUL, - 0x60606060UL, 0x51515151UL, 0x7f7f7f7fUL, 0xa9a9a9a9UL, - 0x19191919UL, 0xb5b5b5b5UL, 0x4a4a4a4aUL, 0x0d0d0d0dUL, - 0x2d2d2d2dUL, 0xe5e5e5e5UL, 0x7a7a7a7aUL, 0x9f9f9f9fUL, - 0x93939393UL, 0xc9c9c9c9UL, 0x9c9c9c9cUL, 0xefefefefUL, - 0xa0a0a0a0UL, 0xe0e0e0e0UL, 0x3b3b3b3bUL, 0x4d4d4d4dUL, - 0xaeaeaeaeUL, 0x2a2a2a2aUL, 0xf5f5f5f5UL, 0xb0b0b0b0UL, - 0xc8c8c8c8UL, 0xebebebebUL, 0xbbbbbbbbUL, 0x3c3c3c3cUL, - 0x83838383UL, 0x53535353UL, 0x99999999UL, 0x61616161UL, - 0x17171717UL, 0x2b2b2b2bUL, 0x04040404UL, 0x7e7e7e7eUL, - 0xbabababaUL, 0x77777777UL, 0xd6d6d6d6UL, 0x26262626UL, - 0xe1e1e1e1UL, 0x69696969UL, 0x14141414UL, 0x63636363UL, - 0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL, -}; -static const unsigned int rcon[] = { - 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, - 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL, - 0x1B000000UL, 0x36000000UL, -}; - -#define GETU32(pt) (((unsigned int)(pt)[0] << 24) ^ \ - ((unsigned int)(pt)[1] << 16) ^ \ - ((unsigned int)(pt)[2] << 8) ^ \ - ((unsigned int)(pt)[3])) - -#define PUTU32(ct, st) { (ct)[0] = (unsigned char)((st) >> 24); \ - (ct)[1] = (unsigned char)((st) >> 16); \ - (ct)[2] = (unsigned char)((st) >> 8); \ - (ct)[3] = (unsigned char)(st); } - -/* -* Expand the cipher key into the encryption key schedule and return the -* number of rounds for the given cipher key size. -*/ -int aes_setkey_enc(unsigned int rk[], const unsigned char cipherKey[], int keyBytes) -{ - int i = 0; - unsigned int temp; - - rk[0] = GETU32(cipherKey ); - rk[1] = GETU32(cipherKey + 4); - rk[2] = GETU32(cipherKey + 8); - rk[3] = GETU32(cipherKey + 12); - if (keyBytes == 16) { // 128 bits - for (;;) { - temp = rk[3]; - rk[4] = rk[0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[5] = rk[1] ^ rk[4]; - rk[6] = rk[2] ^ rk[5]; - rk[7] = rk[3] ^ rk[6]; - if (++i == 10) { - return 10; - } - rk += 4; - } - } - rk[4] = GETU32(cipherKey + 16); - rk[5] = GETU32(cipherKey + 20); - if (keyBytes == 24) { // 192 bits - for (;;) { - temp = rk[ 5]; - rk[ 6] = rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 7] = rk[ 1] ^ rk[ 6]; - rk[ 8] = rk[ 2] ^ rk[ 7]; - rk[ 9] = rk[ 3] ^ rk[ 8]; - if (++i == 8) { - return 12; - } - rk[10] = rk[ 4] ^ rk[ 9]; - rk[11] = rk[ 5] ^ rk[10]; - rk += 6; - } - } - rk[6] = GETU32(cipherKey + 24); - rk[7] = GETU32(cipherKey + 28); - if (keyBytes == 32) { // 256 bits - for (;;) { - temp = rk[ 7]; - rk[ 8] = rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 9] = rk[ 1] ^ rk[ 8]; - rk[10] = rk[ 2] ^ rk[ 9]; - rk[11] = rk[ 3] ^ rk[10]; - if (++i == 7) { - return 14; - } - temp = rk[11]; - rk[12] = rk[ 4] ^ - (Te4[(temp >> 24) ] & 0xff000000) ^ - (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(temp ) & 0xff] & 0x000000ff); - rk[13] = rk[ 5] ^ rk[12]; - rk[14] = rk[ 6] ^ rk[13]; - rk[15] = rk[ 7] ^ rk[14]; - - rk += 8; - } - } - return 0; -} - -/* -* Expand the cipher key into encryption and decryption key schedule and -* return the number of rounds for the given cipher key size. -*/ -int AesGenKeySched(unsigned int rk[], unsigned int rrk[], const unsigned char cipherKey[], int keyBytes) -{ - int Nr, i; - - // expand the cipher key - Nr = aes_setkey_enc(rk, cipherKey, keyBytes); - // invert the order of the first round keys - rrk += Nr * 4; - rrk[0] = rk[0]; - rrk[1] = rk[1]; - rrk[2] = rk[2]; - rrk[3] = rk[3]; - - /* - * apply the inverse MixColumn transform to all round keys but the first - * and the last - */ - for (i = 1; i < Nr; i++) { - rrk -= 4; - rk += 4; - rrk[0] = - Td0[Te4[(rk[0] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[0] ) & 0xff] & 0xff]; - rrk[1] = - Td0[Te4[(rk[1] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[1] ) & 0xff] & 0xff]; - rrk[2] = - Td0[Te4[(rk[2] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[2] ) & 0xff] & 0xff]; - rrk[3] = - Td0[Te4[(rk[3] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[3] ) & 0xff] & 0xff]; - } - // invert the order of the last round keys - rrk -= 4; - rk += 4; - rrk[0] = rk[0]; - rrk[1] = rk[1]; - rrk[2] = rk[2]; - rrk[3] = rk[3]; - - return Nr; -} - -/* -* Encrypt the plain text into cipher -*/ -void AesEncBlk(AesCtx *pCtx, const unsigned char pt[], unsigned char ct[]) -{ - unsigned int s0, s1, s2, s3, t0, t1, t2, t3, *iv; - const unsigned int *rk; - int r; - - rk = pCtx->Ek; - iv = pCtx->Iv; - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(pt ) ^ rk[0]; - s1 = GETU32(pt + 4) ^ rk[1]; - s2 = GETU32(pt + 8) ^ rk[2]; - s3 = GETU32(pt + 12) ^ rk[3]; - if (pCtx->Mode) { - s0 = s0 ^ iv[0]; - s1 = s1 ^ iv[1]; - s2 = s2 ^ iv[2]; - s3 = s3 ^ iv[3]; - } - /* - * Nr - 1 full rounds: - */ - r = pCtx->Nr >> 1; - for (;;) { - t0 = - Te0[(s0 >> 24) ] ^ - Te1[(s1 >> 16) & 0xff] ^ - Te2[(s2 >> 8) & 0xff] ^ - Te3[(s3 ) & 0xff] ^ - rk[4]; - t1 = - Te0[(s1 >> 24) ] ^ - Te1[(s2 >> 16) & 0xff] ^ - Te2[(s3 >> 8) & 0xff] ^ - Te3[(s0 ) & 0xff] ^ - rk[5]; - t2 = - Te0[(s2 >> 24) ] ^ - Te1[(s3 >> 16) & 0xff] ^ - Te2[(s0 >> 8) & 0xff] ^ - Te3[(s1 ) & 0xff] ^ - rk[6]; - t3 = - Te0[(s3 >> 24) ] ^ - Te1[(s0 >> 16) & 0xff] ^ - Te2[(s1 >> 8) & 0xff] ^ - Te3[(s2 ) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) { - break; - } - - s0 = - Te0[(t0 >> 24) ] ^ - Te1[(t1 >> 16) & 0xff] ^ - Te2[(t2 >> 8) & 0xff] ^ - Te3[(t3 ) & 0xff] ^ - rk[0]; - s1 = - Te0[(t1 >> 24) ] ^ - Te1[(t2 >> 16) & 0xff] ^ - Te2[(t3 >> 8) & 0xff] ^ - Te3[(t0 ) & 0xff] ^ - rk[1]; - s2 = - Te0[(t2 >> 24) ] ^ - Te1[(t3 >> 16) & 0xff] ^ - Te2[(t0 >> 8) & 0xff] ^ - Te3[(t1 ) & 0xff] ^ - rk[2]; - s3 = - Te0[(t3 >> 24) ] ^ - Te1[(t0 >> 16) & 0xff] ^ - Te2[(t1 >> 8) & 0xff] ^ - Te3[(t2 ) & 0xff] ^ - rk[3]; - } - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - (Te4[(t0 >> 24) ] & 0xff000000) ^ - (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTU32(ct , s0); - s1 = - (Te4[(t1 >> 24) ] & 0xff000000) ^ - (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[1]; - PUTU32(ct + 4, s1); - s2 = - (Te4[(t2 >> 24) ] & 0xff000000) ^ - (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[2]; - PUTU32(ct + 8, s2); - s3 = - (Te4[(t3 >> 24) ] & 0xff000000) ^ - (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[3]; - PUTU32(ct + 12, s3); - - if (pCtx->Mode) { - iv[0] = s0; - iv[1] = s1; - iv[2] = s2; - iv[3] = s3; - } -} - -/* -* Decrypt the cipher into plain text -*/ -void AesDecBlk(AesCtx *pCtx, const unsigned char ct[], unsigned char pt[]) -{ - unsigned int s0, s1, s2, s3, t0, t1, t2, t3, v0, v1, v2, v3, *iv; - const unsigned int *rk; - int r; - - rk = pCtx->Dk; - iv = pCtx->Iv; - /* - * map byte array block to cipher state - * and add initial round key: - */ - v0 = GETU32(ct ); s0 = v0 ^ rk[0]; - v1 = GETU32(ct + 4); s1 = v1 ^ rk[1]; - v2 = GETU32(ct + 8); s2 = v2 ^ rk[2]; - v3 = GETU32(ct + 12); s3 = v3 ^ rk[3]; - /* - * Nr - 1 full rounds: - */ - r = pCtx->Nr >> 1; - for (;;) { - t0 = - Td0[(s0 >> 24) ] ^ - Td1[(s3 >> 16) & 0xff] ^ - Td2[(s2 >> 8) & 0xff] ^ - Td3[(s1 ) & 0xff] ^ - rk[4]; - t1 = - Td0[(s1 >> 24) ] ^ - Td1[(s0 >> 16) & 0xff] ^ - Td2[(s3 >> 8) & 0xff] ^ - Td3[(s2 ) & 0xff] ^ - rk[5]; - t2 = - Td0[(s2 >> 24) ] ^ - Td1[(s1 >> 16) & 0xff] ^ - Td2[(s0 >> 8) & 0xff] ^ - Td3[(s3 ) & 0xff] ^ - rk[6]; - t3 = - Td0[(s3 >> 24) ] ^ - Td1[(s2 >> 16) & 0xff] ^ - Td2[(s1 >> 8) & 0xff] ^ - Td3[(s0 ) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) { - break; - } - - s0 = - Td0[(t0 >> 24) ] ^ - Td1[(t3 >> 16) & 0xff] ^ - Td2[(t2 >> 8) & 0xff] ^ - Td3[(t1 ) & 0xff] ^ - rk[0]; - s1 = - Td0[(t1 >> 24) ] ^ - Td1[(t0 >> 16) & 0xff] ^ - Td2[(t3 >> 8) & 0xff] ^ - Td3[(t2 ) & 0xff] ^ - rk[1]; - s2 = - Td0[(t2 >> 24) ] ^ - Td1[(t1 >> 16) & 0xff] ^ - Td2[(t0 >> 8) & 0xff] ^ - Td3[(t3 ) & 0xff] ^ - rk[2]; - s3 = - Td0[(t3 >> 24) ] ^ - Td1[(t2 >> 16) & 0xff] ^ - Td2[(t1 >> 8) & 0xff] ^ - Td3[(t0 ) & 0xff] ^ - rk[3]; - } - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - (Td4[(t0 >> 24) ] & 0xff000000) ^ - (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[0]; - s1 = - (Td4[(t1 >> 24) ] & 0xff000000) ^ - (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[1]; - s2 = - (Td4[(t2 >> 24) ] & 0xff000000) ^ - (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[2]; - s3 = - (Td4[(t3 >> 24) ] & 0xff000000) ^ - (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[3]; - - if (pCtx->Mode) { - s0 = s0 ^ iv[0]; iv[0] = v0; - s1 = s1 ^ iv[1]; iv[1] = v1; - s2 = s2 ^ iv[2]; iv[2] = v2; - s3 = s3 ^ iv[3]; iv[3] = v3; - } - - PUTU32(pt , s0); - PUTU32(pt + 4, s1); - PUTU32(pt + 8, s2); - PUTU32(pt + 12, s3); -} - -////////////////////////////////////////////////////////////////////////////// -// API functions // -////////////////////////////////////////////////////////////////////////////// - -/* -* initialize AES context -*/ -int AesCtxIni(AesCtx *pCtx, unsigned char *pIV, unsigned char *pKey, unsigned int KeyLen, unsigned char Mode) -{ - if (pKey == 0 || pCtx == 0 || (KeyLen != KEY128 && KeyLen != KEY192 && KeyLen != KEY256)) - return -1; - - // generate key schedule - pCtx->Nr = AesGenKeySched(pCtx->Ek, pCtx->Dk, pKey, KeyLen); - - // initialize IV - if (pIV != 0) { - pCtx->Iv[0] = GETU32(pIV ); - pCtx->Iv[1] = GETU32(pIV + 4 ); - pCtx->Iv[2] = GETU32(pIV + 8 ); - pCtx->Iv[3] = GETU32(pIV + 12); - } - - // mode - pCtx->Mode = Mode; - - return 0; -} - -/* -* Encrypt plain text -*/ -int AesEncrypt(AesCtx *pCtx, unsigned char *pData, unsigned char *pCipher, unsigned int DataLen) -{ - int i; - - if (pData == 0 || pCipher == 0 || pCtx == 0 || (DataLen & 0xf) != 0) - return -1; - - for (i = 0; i < DataLen; i += BLOCKSZ) { - // encrypt block by block - AesEncBlk(pCtx, pData, pCipher); - pCipher += BLOCKSZ; - pData += BLOCKSZ; - } - return DataLen; -} - -/* -* Decrypt cipher -*/ -int AesDecrypt(AesCtx *pCtx, unsigned char *pCipher, unsigned char *pData, unsigned int CipherLen) -{ - int i; - - if (pData == 0 || pCipher == 0 || pCtx == 0 || (CipherLen & 0xf) != 0) - return -1; - - for (i = 0; i < CipherLen; i += BLOCKSZ) { - // decrypt block by block - AesDecBlk(pCtx, pCipher, pData); - pCipher += BLOCKSZ; - pData += BLOCKSZ; - } - return CipherLen; -} - -////////////////////////////////////////////////////////////////////////////// -// Sample main program // -////////////////////////////////////////////////////////////////////////////// - -#ifndef EMBEDDED -int main() -{ - AesCtx ctx; - unsigned char iv[] = "INI VECTINI VECT"; - unsigned char key[] = "This is a sample AESKey"; - unsigned char databuf[] = "Data : AES Test"; // must be in multiple of 16 - - // initialize context and encrypt data at one end - - if( AesCtxIni(&ctx, iv, key, KEY128, CBC) < 0) - printf("init error\n"); - - if (AesEncrypt(&ctx, databuf, databuf, sizeof databuf) < 0) - printf("error in encryption\n"); - - // initialize context and decrypt cipher at other end - - if( AesCtxIni(&ctx, iv, key, KEY128, CBC) < 0) - printf("init error\n"); - - if (AesDecrypt(&ctx, databuf, databuf, sizeof databuf) < 0) - printf("error in decryption\n"); - - printf("%s\n", databuf); - - return 0; -} -#endif \ No newline at end of file diff --git a/armsrc/aes.h b/armsrc/aes.h deleted file mode 100644 index 85944873..00000000 --- a/armsrc/aes.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -* AES Cryptographic Algorithm Header File. Include this header file in -* your source which uses these given APIs. (This source is kept under -* public domain) -*/ - -// AES context structure -typedef struct { - unsigned int Ek[60]; - unsigned int Dk[60]; - unsigned int Iv[4]; - unsigned char Nr; - unsigned char Mode; -} AesCtx; - -// key length in bytes -#define KEY128 16 -#define KEY192 24 -#define KEY256 32 -// block size in bytes -#define BLOCKSZ 16 -// mode -#define EBC 0 -#define CBC 1 - -// AES API function prototype - -int AesCtxIni(AesCtx *pCtx, unsigned char *pIV, unsigned char *pKey, unsigned int KeyLen, unsigned char Mode); -int AesEncrypt(AesCtx *pCtx, unsigned char *pData, unsigned char *pCipher, unsigned int DataLen); -int AesDecrypt(AesCtx *pCtx, unsigned char *pCipher, unsigned char *pData, unsigned int CipherLen); \ No newline at end of file diff --git a/armsrc/appmain.c b/armsrc/appmain.c index dbbbe6bd..3c92a7fd 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -10,20 +10,19 @@ // executes. //----------------------------------------------------------------------------- -#include "../common/usb_cdc.h" -#include "../common/cmd.h" +#include "usb_cdc.h" +#include "cmd.h" -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" #include "util.h" #include "printf.h" #include "string.h" + #include - #include "legicrf.h" -#include "../include/hitag2.h" - +#include #ifdef WITH_LCD #include "LCD.h" @@ -37,7 +36,7 @@ // is the order in which they go out on the wire. //============================================================================= -#define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits +#define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits uint8_t ToSend[TOSEND_BUFFER_SIZE]; int ToSendMax; static int ToSendBit; @@ -69,7 +68,7 @@ void ToSendStuffBit(int b) ToSendBit++; - if(ToSendMax >= sizeof(ToSend)) { + if(ToSendMax >= sizeof(ToSend)) { ToSendBit = 0; DbpString("ToSendStuffBit overflowed!"); } @@ -173,7 +172,7 @@ void MeasureAntennaTuning(void) int i, adcval = 0, peak = 0, peakv = 0, peakf = 0; //ptr = 0 int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV - LED_B_ON(); + LED_B_ON(); /* * Sweeps the useful LF range of the proxmark from @@ -207,7 +206,7 @@ void MeasureAntennaTuning(void) for (i=18; i >= 0; i--) LF_Results[i] = 0; - LED_A_ON(); + LED_A_ON(); // Let the FPGA drive the high-frequency antenna around 13.56 MHz. FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); @@ -218,9 +217,9 @@ void MeasureAntennaTuning(void) cmd_send(CMD_MEASURED_ANTENNA_TUNING,vLf125|(vLf134<<16),vHf,peakf|(peakv<<16),LF_Results,256); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_A_OFF(); - LED_B_OFF(); - return; + LED_A_OFF(); + LED_B_OFF(); + return; } void MeasureAntennaTuningHf(void) @@ -362,7 +361,7 @@ void SamyRun() for (;;) { usb_poll(); - WDT_HIT(); + WDT_HIT(); // Was our button held down or pressed? int button_pressed = BUTTON_HELD(1000); @@ -626,7 +625,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { UsbCommand *c = (UsbCommand *)packet; - //Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d",len,c->cmd,c->arg[0],c->arg[1],c->arg[2]); +// Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d",len,c->cmd,c->arg[0],c->arg[1],c->arg[2]); switch(c->cmd) { #ifdef WITH_LF @@ -669,8 +668,9 @@ void UsbPacketReceived(uint8_t *packet, int len) WriteTItag(c->arg[0],c->arg[1],c->arg[2]); break; case CMD_SIMULATE_TAG_125K: - SimulateTagLowFrequency(c->arg[0], c->arg[1], 0); - //SimulateTagLowFrequencyA(c->arg[0], c->arg[1]); + LED_A_ON(); + SimulateTagLowFrequency(c->arg[0], c->arg[1], 1); + LED_A_OFF(); break; case CMD_LF_SIMULATE_BIDIR: SimulateTagLowFrequencyBidir(c->arg[0], c->arg[1]); @@ -792,10 +792,6 @@ void UsbPacketReceived(uint8_t *packet, int len) EPA_PACE_Collect_Nonce(c); break; - // case CMD_EPA_: - // EpaFoo(c); - // break; - case CMD_READER_MIFARE: ReaderMifare(c->arg[0]); break; @@ -805,17 +801,8 @@ void UsbPacketReceived(uint8_t *packet, int len) case CMD_MIFAREU_READBL: MifareUReadBlock(c->arg[0],c->d.asBytes); break; - case CMD_MIFAREUC_AUTH1: - MifareUC_Auth1(c->arg[0],c->d.asBytes); - break; - case CMD_MIFAREUC_AUTH2: - MifareUC_Auth2(c->arg[0],c->d.asBytes); - break; case CMD_MIFAREU_READCARD: - MifareUReadCard(c->arg[0],c->arg[1],c->d.asBytes); - break; - case CMD_MIFAREUC_READCARD: - MifareUReadCard(c->arg[0],c->arg[1],c->d.asBytes); + MifareUReadCard(c->arg[0],c->d.asBytes); break; case CMD_MIFARE_READSC: MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); @@ -871,28 +858,6 @@ void UsbPacketReceived(uint8_t *packet, int len) case CMD_MIFARE_SNIFFER: SniffMifare(c->arg[0]); break; - - // mifare desfire - case CMD_MIFARE_DESFIRE_READBL: - break; - case CMD_MIFARE_DESFIRE_WRITEBL: - break; - case CMD_MIFARE_DESFIRE_AUTH1: - MifareDES_Auth1(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_MIFARE_DESFIRE_AUTH2: - //MifareDES_Auth2(c->arg[0],c->d.asBytes); - break; - // case CMD_MIFARE_DES_READER: - // ReaderMifareDES(c->arg[0], c->arg[1], c->d.asBytes); - //break; - case CMD_MIFARE_DESFIRE_INFO: - MifareDesfireGetInformation(); - break; - case CMD_MIFARE_DESFIRE: - MifareSendCommand(c->arg[0], c->arg[1], c->d.asBytes); - break; - #endif #ifdef WITH_ICLASS @@ -907,7 +872,7 @@ void UsbPacketReceived(uint8_t *packet, int len) ReaderIClass(c->arg[0]); break; case CMD_READER_ICLASS_REPLAY: - ReaderIClass_Replay(c->arg[0], c->d.asBytes); + ReaderIClass_Replay(c->arg[0], c->d.asBytes); break; #endif @@ -1036,7 +1001,7 @@ void __attribute__((noreturn)) AppMain(void) LED_A_OFF(); // Init USB device - usb_enable(); + usb_enable(); // The FPGA gets its clock from us from PCK0 output, so set that up. AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0; @@ -1066,12 +1031,12 @@ void __attribute__((noreturn)) AppMain(void) size_t rx_len; for(;;) { - if (usb_poll()) { - rx_len = usb_read(rx,sizeof(UsbCommand)); - if (rx_len) { - UsbPacketReceived(rx,rx_len); - } - } + if (usb_poll()) { + rx_len = usb_read(rx,sizeof(UsbCommand)); + if (rx_len) { + UsbPacketReceived(rx,rx_len); + } + } WDT_HIT(); #ifdef WITH_LF diff --git a/armsrc/apps.h b/armsrc/apps.h index 81124a1a..eafee559 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -14,40 +14,28 @@ #include #include -#include -#include -#include -#include - -#include "../include/common.h" -#include "../include/hitag2.h" -#include "../include/mifare.h" - -//#include -//#include -//#include "des.h" -//#include "aes.h" -#include "../common/desfire.h" -#include "../common/crc32.h" +#include "common.h" +#include "hitag2.h" +#include "mifare.h" // The large multi-purpose buffer, typically used to hold A/D samples, // maybe processed in some way. -#define BIGBUF_SIZE 40000 +#define BIGBUF_SIZE 40000 uint32_t BigBuf[BIGBUF_SIZE / sizeof(uint32_t)]; -#define TRACE_OFFSET 0 -#define TRACE_SIZE 3000 -#define RECV_CMD_OFFSET (TRACE_OFFSET + TRACE_SIZE) -#define MAX_FRAME_SIZE 256 -#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 1)/ 8) -#define RECV_CMD_PAR_OFFSET (RECV_CMD_OFFSET + MAX_FRAME_SIZE) -#define RECV_RESP_OFFSET (RECV_CMD_PAR_OFFSET + MAX_PARITY_SIZE) -#define RECV_RESP_PAR_OFFSET (RECV_RESP_OFFSET + MAX_FRAME_SIZE) -#define CARD_MEMORY_OFFSET (RECV_RESP_PAR_OFFSET + MAX_PARITY_SIZE) -#define CARD_MEMORY_SIZE 4096 -#define DMA_BUFFER_OFFSET CARD_MEMORY_OFFSET -#define DMA_BUFFER_SIZE CARD_MEMORY_SIZE -#define FREE_BUFFER_OFFSET (CARD_MEMORY_OFFSET + CARD_MEMORY_SIZE) -#define FREE_BUFFER_SIZE (BIGBUF_SIZE - FREE_BUFFER_OFFSET - 1) +#define TRACE_OFFSET 0 +#define TRACE_SIZE 3000 +#define RECV_CMD_OFFSET (TRACE_OFFSET + TRACE_SIZE) +#define MAX_FRAME_SIZE 256 +#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 1)/ 8) +#define RECV_CMD_PAR_OFFSET (RECV_CMD_OFFSET + MAX_FRAME_SIZE) +#define RECV_RESP_OFFSET (RECV_CMD_PAR_OFFSET + MAX_PARITY_SIZE) +#define RECV_RESP_PAR_OFFSET (RECV_RESP_OFFSET + MAX_FRAME_SIZE) +#define CARD_MEMORY_OFFSET (RECV_RESP_PAR_OFFSET + MAX_PARITY_SIZE) +#define CARD_MEMORY_SIZE 4096 +#define DMA_BUFFER_OFFSET CARD_MEMORY_OFFSET +#define DMA_BUFFER_SIZE CARD_MEMORY_SIZE +#define FREE_BUFFER_OFFSET (CARD_MEMORY_OFFSET + CARD_MEMORY_SIZE) +#define FREE_BUFFER_SIZE (BIGBUF_SIZE - FREE_BUFFER_OFFSET - 1) extern const uint8_t OddByteParity[256]; extern uint8_t *trace; // = (uint8_t *) BigBuf; @@ -76,10 +64,7 @@ void ToSendReset(void); void ListenReaderField(int limit); void AcquireRawAdcSamples125k(int at134khz); void SnoopLFRawAdcSamples(int divisor, int trigger_threshold); -void DoAcquisition125k_internal(int trigger_threshold, bool silent); -void DoAcquisition125k_threshold(int trigger_threshold); -void DoAcquisition125k(); - +void DoAcquisition125k(int trigger_threshold); extern int ToSendMax; extern uint8_t ToSend[]; extern uint32_t BigBuf[]; @@ -144,10 +129,8 @@ void ReadTItag(void); void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc); void AcquireTiType(void); void AcquireRawBitsTI(void); -void SimulateTagLowFrequency( uint16_t period, uint32_t gap, uint8_t ledcontrol); -void SimulateTagLowFrequencyA(int period, int gap); - -void CmdHIDsimTAG(int hi, int lo, uint8_t ledcontrol); +void SimulateTagLowFrequency(int period, int gap, int ledcontrol); +void CmdHIDsimTAG(int hi, int lo, int ledcontrol); void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol); void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol); void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol); @@ -160,7 +143,6 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode); void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode ); void T55xxReadTrace(void); -void TurnReadLFOn(); int DemodPCF7931(uint8_t **outBlocks); int IsBlock0PCF7931(uint8_t *Block); int IsBlock1PCF7931(uint8_t *Block); @@ -181,7 +163,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data); void ReaderIso14443a(UsbCommand * c); // Also used in iclass.c bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t len, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag); -void GetParity(const uint8_t * pbtCmd, uint16_t len, uint8_t *parity); +void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *parity); void iso14a_set_trigger(bool enable); void iso14a_clear_trace(); void iso14a_set_tracing(bool enable); @@ -195,9 +177,7 @@ void ReaderMifare(bool first_try); int32_t dist_nt(uint32_t nt1, uint32_t nt2); void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data); void MifareUReadBlock(uint8_t arg0,uint8_t *datain); -void MifareUC_Auth1(uint8_t arg0, uint8_t *datain); -void MifareUC_Auth2(uint32_t arg0, uint8_t *datain); -void MifareUReadCard(uint8_t arg0, int Pages, uint8_t *datain); +void MifareUReadCard(uint8_t arg0,uint8_t *datain); void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); void MifareUWriteBlock(uint8_t arg0,uint8_t *datain); @@ -214,36 +194,6 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); void MifareCIdent(); // is "magic chinese" card? -//desfire -void Mifare_DES_Auth1(uint8_t arg0,uint8_t *datain); -void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain); - -// mifaredesfire.h -bool InitDesfireCard(); -void MifareSendCommand(uint8_t arg0,uint8_t arg1, uint8_t *datain); -void MifareDesfireGetInformation(); -void MifareDES_Auth1(uint8_t arg0,uint8_t arg1,uint8_t arg2, uint8_t *datain); -void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t * datain); -int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout); -size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout); -void OnSuccess(); -void OnError(); - - - -// desfire_crypto.h -void *mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes, off_t offset, int communication_settings); -void *mifare_cryto_postprocess_data (desfiretag_t tag, void *data, ssize_t *nbytes, int communication_settings); -void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size); -void mifare_cypher_blocks_chained (desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation); -size_t key_block_size (const desfirekey_t key); -size_t padded_data_length (const size_t nbytes, const size_t block_size); -size_t maced_data_length (const desfirekey_t key, const size_t nbytes); -size_t enciphered_data_length (const desfiretag_t tag, const size_t nbytes, int communication_settings); -void cmac_generate_subkeys (desfirekey_t key); -void cmac (const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac); - - /// iso15693.h void RecordRawAdcSamplesIso15693(void); void AcquireRawAdcSamplesIso15693(void); diff --git a/armsrc/crapto1.c b/armsrc/crapto1.c index c0a7fc32..9d491d12 100644 --- a/armsrc/crapto1.c +++ b/armsrc/crapto1.c @@ -44,12 +44,12 @@ static void quicksort(uint32_t* const start, uint32_t* const stop) else if(*rit > *start) --rit; else - *it ^= ( (*it ^= *rit ), *rit ^= *it); + *it ^= (*it ^= *rit, *rit ^= *it); if(*rit >= *start) --rit; if(rit != start) - *rit ^= ( (*rit ^= *start), *start ^= *rit); + *rit ^= (*rit ^= *start, *start ^= *rit); quicksort(start, rit - 1); quicksort(rit + 1, stop); @@ -454,7 +454,7 @@ lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8]) odd = lfsr_prefix_ks(ks, 1); even = lfsr_prefix_ks(ks, 0); - + s = statelist = malloc((sizeof *statelist) << 20); if(!s || !odd || !even) { free(statelist); diff --git a/armsrc/des.c b/armsrc/des.c deleted file mode 100644 index 0a27503e..00000000 --- a/armsrc/des.c +++ /dev/null @@ -1,383 +0,0 @@ -/* des.c */ -/* - This file is part of the ARM-Crypto-Lib. - Copyright (C) 2006-2010 Daniel Otte (daniel.otte@rub.de) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -/** - * \file des.c - * \author Daniel Otte - * \email daniel.otte@rub.de - * \date 2007-06-16 - * \brief DES and EDE-DES implementation - * \license GPLv3 or later - * - */ -#include -#include - -const uint8_t sbox[256] = { - /* S-box 1 */ - 0xE4, 0xD1, 0x2F, 0xB8, 0x3A, 0x6C, 0x59, 0x07, - 0x0F, 0x74, 0xE2, 0xD1, 0xA6, 0xCB, 0x95, 0x38, - 0x41, 0xE8, 0xD6, 0x2B, 0xFC, 0x97, 0x3A, 0x50, - 0xFC, 0x82, 0x49, 0x17, 0x5B, 0x3E, 0xA0, 0x6D, - /* S-box 2 */ - 0xF1, 0x8E, 0x6B, 0x34, 0x97, 0x2D, 0xC0, 0x5A, - 0x3D, 0x47, 0xF2, 0x8E, 0xC0, 0x1A, 0x69, 0xB5, - 0x0E, 0x7B, 0xA4, 0xD1, 0x58, 0xC6, 0x93, 0x2F, - 0xD8, 0xA1, 0x3F, 0x42, 0xB6, 0x7C, 0x05, 0xE9, - /* S-box 3 */ - 0xA0, 0x9E, 0x63, 0xF5, 0x1D, 0xC7, 0xB4, 0x28, - 0xD7, 0x09, 0x34, 0x6A, 0x28, 0x5E, 0xCB, 0xF1, - 0xD6, 0x49, 0x8F, 0x30, 0xB1, 0x2C, 0x5A, 0xE7, - 0x1A, 0xD0, 0x69, 0x87, 0x4F, 0xE3, 0xB5, 0x2C, - /* S-box 4 */ - 0x7D, 0xE3, 0x06, 0x9A, 0x12, 0x85, 0xBC, 0x4F, - 0xD8, 0xB5, 0x6F, 0x03, 0x47, 0x2C, 0x1A, 0xE9, - 0xA6, 0x90, 0xCB, 0x7D, 0xF1, 0x3E, 0x52, 0x84, - 0x3F, 0x06, 0xA1, 0xD8, 0x94, 0x5B, 0xC7, 0x2E, - /* S-box 5 */ - 0x2C, 0x41, 0x7A, 0xB6, 0x85, 0x3F, 0xD0, 0xE9, - 0xEB, 0x2C, 0x47, 0xD1, 0x50, 0xFA, 0x39, 0x86, - 0x42, 0x1B, 0xAD, 0x78, 0xF9, 0xC5, 0x63, 0x0E, - 0xB8, 0xC7, 0x1E, 0x2D, 0x6F, 0x09, 0xA4, 0x53, - /* S-box 6 */ - 0xC1, 0xAF, 0x92, 0x68, 0x0D, 0x34, 0xE7, 0x5B, - 0xAF, 0x42, 0x7C, 0x95, 0x61, 0xDE, 0x0B, 0x38, - 0x9E, 0xF5, 0x28, 0xC3, 0x70, 0x4A, 0x1D, 0xB6, - 0x43, 0x2C, 0x95, 0xFA, 0xBE, 0x17, 0x60, 0x8D, - /* S-box 7 */ - 0x4B, 0x2E, 0xF0, 0x8D, 0x3C, 0x97, 0x5A, 0x61, - 0xD0, 0xB7, 0x49, 0x1A, 0xE3, 0x5C, 0x2F, 0x86, - 0x14, 0xBD, 0xC3, 0x7E, 0xAF, 0x68, 0x05, 0x92, - 0x6B, 0xD8, 0x14, 0xA7, 0x95, 0x0F, 0xE2, 0x3C, - /* S-box 8 */ - 0xD2, 0x84, 0x6F, 0xB1, 0xA9, 0x3E, 0x50, 0xC7, - 0x1F, 0xD8, 0xA3, 0x74, 0xC5, 0x6B, 0x0E, 0x92, - 0x7B, 0x41, 0x9C, 0xE2, 0x06, 0xAD, 0xF3, 0x58, - 0x21, 0xE7, 0x4A, 0x8D, 0xFC, 0x90, 0x35, 0x6B -}; - -const uint8_t e_permtab[] ={ - 4, 6, /* 4 bytes in 6 bytes out*/ - 32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, - 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, - 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1 -}; - -const uint8_t p_permtab[] ={ - 4, 4, /* 32 bit -> 32 bit */ - 16, 7, 20, 21, - 29, 12, 28, 17, - 1, 15, 23, 26, - 5, 18, 31, 10, - 2, 8, 24, 14, - 32, 27, 3, 9, - 19, 13, 30, 6, - 22, 11, 4, 25 -}; - -const uint8_t ip_permtab[] ={ - 8, 8, /* 64 bit -> 64 bit */ - 58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7 -}; - -const uint8_t inv_ip_permtab[] ={ - 8, 8, /* 64 bit -> 64 bit */ - 40, 8, 48, 16, 56, 24, 64, 32, - 39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, - 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, - 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, - 33, 1, 41, 9, 49, 17, 57, 25 -}; - -const uint8_t pc1_permtab[] ={ - 8, 7, /* 64 bit -> 56 bit*/ - 57, 49, 41, 33, 25, 17, 9, - 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, - 19, 11, 3, 60, 52, 44, 36, - 63, 55, 47, 39, 31, 23, 15, - 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, - 21, 13, 5, 28, 20, 12, 4 -}; - -const uint8_t pc2_permtab[] ={ - 7, 6, /* 56 bit -> 48 bit */ - 14, 17, 11, 24, 1, 5, - 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, - 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, - 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, - 46, 42, 50, 36, 29, 32 -}; - -const uint8_t splitin6bitword_permtab[] = { - 8, 8, /* 64 bit -> 64 bit */ - 64, 64, 1, 6, 2, 3, 4, 5, - 64, 64, 7, 12, 8, 9, 10, 11, - 64, 64, 13, 18, 14, 15, 16, 17, - 64, 64, 19, 24, 20, 21, 22, 23, - 64, 64, 25, 30, 26, 27, 28, 29, - 64, 64, 31, 36, 32, 33, 34, 35, - 64, 64, 37, 42, 38, 39, 40, 41, - 64, 64, 43, 48, 44, 45, 46, 47 -}; - -const uint8_t shiftkey_permtab[] = { - 7, 7, /* 56 bit -> 56 bit */ - 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 1, - 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 29 -}; - -const uint8_t shiftkeyinv_permtab[] = { - 7, 7, - 28, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, - 56, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55 -}; - -/* -1 0 -1 0 -2 1 -2 1 -2 1 -2 1 -2 1 -2 1 ----- -1 0 -2 1 -2 1 -2 1 -2 1 -2 1 -2 1 -1 0 -*/ -#define ROTTABLE 0x7EFC -#define ROTTABLE_INV 0x3F7E -/******************************************************************************/ - -void permute(const uint8_t *ptable, const uint8_t *in, uint8_t *out){ - uint8_t ob; /* in-bytes and out-bytes */ - uint8_t byte, bit; /* counter for bit and byte */ - ob = ptable[1]; - ptable = &(ptable[2]); - for(byte=0; byte>(x%8)) ){ - t|=0x01; - } - } - out[byte]=t; - } -} - -/******************************************************************************/ - -void changeendian32(uint32_t * a){ - *a = (*a & 0x000000FF) << 24 | - (*a & 0x0000FF00) << 8 | - (*a & 0x00FF0000) >> 8 | - (*a & 0xFF000000) >> 24; -} - -/******************************************************************************/ -static inline -void shiftkey(uint8_t *key){ - uint8_t k[7]; - memcpy(k, key, 7); - permute((uint8_t*)shiftkey_permtab, k, key); -} - -/******************************************************************************/ -static inline -void shiftkey_inv(uint8_t *key){ - uint8_t k[7]; - memcpy(k, key, 7); - permute((uint8_t*)shiftkeyinv_permtab, k, key); - -} - -/******************************************************************************/ -static inline -uint64_t splitin6bitwords(uint64_t a){ - uint64_t ret=0; - a &= 0x0000ffffffffffffLL; - permute((uint8_t*)splitin6bitword_permtab, (uint8_t*)&a, (uint8_t*)&ret); - return ret; -} - -/******************************************************************************/ - -static inline -uint8_t substitute(uint8_t a, uint8_t * sbp){ - uint8_t x; - x = sbp[a>>1]; - x = (a&1)?x&0x0F:x>>4; - return x; - -} - -/******************************************************************************/ - -uint32_t des_f(uint32_t r, uint8_t* kr){ - uint8_t i; - uint32_t t=0,ret; - uint64_t data; - uint8_t *sbp; /* sboxpointer */ - permute((uint8_t*)e_permtab, (uint8_t*)&r, (uint8_t*)&data); - for(i=0; i<7; ++i) - ((uint8_t*)&data)[i] ^= kr[i]; - - /* Sbox substitution */ - data = splitin6bitwords(data); - sbp=(uint8_t*)sbox; - for(i=0; i<8; ++i){ - uint8_t x; - x = substitute(((uint8_t*)&data)[i], sbp); - t<<=4; - t |= x; - sbp += 32; - } - changeendian32(&t); - - permute((uint8_t*)p_permtab,(uint8_t*)&t, (uint8_t*)&ret); - - return ret; -} - -/******************************************************************************/ - -void des_enc(void* out, const void* in, const void* key){ -#define R *((uint32_t*)&(data[4])) -#define L *((uint32_t*)&(data[0])) - - uint8_t data[8],kr[6],k[7]; - uint8_t i; - - permute((uint8_t*)ip_permtab, (uint8_t*)in, data); - permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k); - for(i=0; i<8; ++i){ - shiftkey(k); - if(ROTTABLE&((1<<((i<<1)+0))) ) - shiftkey(k); - permute((uint8_t*)pc2_permtab, k, kr); - L ^= des_f(R, kr); - - shiftkey(k); - if(ROTTABLE&((1<<((i<<1)+1))) ) - shiftkey(k); - permute((uint8_t*)pc2_permtab, k, kr); - R ^= des_f(L, kr); - - } - /* L <-> R*/ - R ^= L; - L ^= R; - R ^= L; - - permute((uint8_t*)inv_ip_permtab, data, (uint8_t*)out); -} - -/******************************************************************************/ - -void des_dec(void* out, const void* in, const uint8_t* key){ -#define R *((uint32_t*)&(data[4])) -#define L *((uint32_t*)&(data[0])) - - uint8_t data[8],kr[6],k[7]; - int8_t i; - permute((uint8_t*)ip_permtab, (uint8_t*)in, data); - permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k); - for(i=7; i>=0; --i){ - - permute((uint8_t*)pc2_permtab, k, kr); - L ^= des_f(R, kr); - shiftkey_inv(k); - if(ROTTABLE&((1<<((i<<1)+1))) ){ - shiftkey_inv(k); - } - - permute((uint8_t*)pc2_permtab, k, kr); - R ^= des_f(L, kr); - shiftkey_inv(k); - if(ROTTABLE&((1<<((i<<1)+0))) ){ - shiftkey_inv(k); - } - - } - /* L <-> R*/ - R ^= L; - L ^= R; - R ^= L; - - permute((uint8_t*)inv_ip_permtab, data, (uint8_t*)out); -} - -/******************************************************************************/ - -void tdes_enc(void* out, void* in, const void* key){ - des_enc(out, in, (uint8_t*)key + 0); - des_dec(out, out, (uint8_t*)key + 8); - des_enc(out, out, (uint8_t*)key +16); -} - -/******************************************************************************/ - -void tdes_dec(void* out, void* in, const uint8_t* key){ - des_dec(out, in, (uint8_t*)key +16); - des_enc(out, out, (uint8_t*)key + 8); - des_dec(out, out, (uint8_t*)key + 0); -} - -/******************************************************************************/ - - diff --git a/armsrc/des.h b/armsrc/des.h deleted file mode 100644 index 652886fd..00000000 --- a/armsrc/des.h +++ /dev/null @@ -1,107 +0,0 @@ -/* des.h */ -/* - This file is part of the ARM-Crypto-Lib. - Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -/** - * \file des.h - * \author Daniel Otte - * \date 2007-06-16 - * \brief des and tdes declarations - * \license GPLv3 or later - * - */ -#ifndef DES_H_ -#define DES_H_ - -/* the FIPS 46-3 (1999-10-25) name for triple DES is triple data encryption algorithm so TDEA. - * Also we only implement the three key mode */ - -/** \def tdea_enc - * \brief defining an alias for void tdes_enc(void* out, const void* in, const void* key) - */ - -/** \def tdea_dec - * \brief defining an alias for void tdes_dec(void* out, const void* in, const void* key) - */ - -#define tdea_enc tdes_enc -#define tdea_dec tdes_dec - -/** \fn void des_enc(void* out, const void* in, const void* key) - * \brief encrypt a block with DES - * - * This function encrypts a block of 64 bits (8 bytes) with the DES algorithm. - * Key expansion is done automatically. The key is 64 bits long, but note that - * only 56 bits are used (the LSB of each byte is dropped). The input and output - * blocks may overlap. - * - * \param out pointer to the block (64 bit = 8 byte) where the ciphertext is written to - * \param in pointer to the block (64 bit = 8 byte) where the plaintext is read from - * \param key pointer to the key (64 bit = 8 byte) - */ -void des_enc(void* out, const void* in, const void* key); - -/** \fn void des_dec(void* out, const void* in, const void* key) - * \brief decrypt a block with DES - * - * This function decrypts a block of 64 bits (8 bytes) with the DES algorithm. - * Key expansion is done automatically. The key is 64 bits long, but note that - * only 56 bits are used (the LSB of each byte is dropped). The input and output - * blocks may overlap. - * - * \param out pointer to the block (64 bit = 8 byte) where the plaintext is written to - * \param in pointer to the block (64 bit = 8 byte) where the ciphertext is read from - * \param key pointer to the key (64 bit = 8 byte) - */ -void des_dec(void* out, const void* in, const void* key); - -/** \fn void tdes_enc(void* out, const void* in, const void* key) - * \brief encrypt a block with Tripple-DES - * - * This function encrypts a block of 64 bits (8 bytes) with the Tripple-DES (EDE) - * algorithm. Key expansion is done automatically. The key is 192 bits long, but - * note that only 178 bits are used (the LSB of each byte is dropped). The input - * and output blocks may overlap. - * - * \param out pointer to the block (64 bit = 8 byte) where the ciphertext is written to - * \param in pointer to the block (64 bit = 8 byte) where the plaintext is read from - * \param key pointer to the key (192 bit = 24 byte) - */ -void tdes_enc(void* out, const void* in, const void* key); - -/** \fn void tdes_dec(void* out, const void* in, const void* key) - * \brief decrypt a block with Tripple-DES - * - * This function decrypts a block of 64 bits (8 bytes) with the Tripple-DES (EDE) - * algorithm. Key expansion is done automatically. The key is 192 bits long, but - * note that only 178 bits are used (the LSB of each byte is dropped). The input - * and output blocks may overlap. - * - * \param out pointer to the block (64 bit = 8 byte) where the plaintext is written to - * \param in pointer to the block (64 bit = 8 byte) where the ciphertext is read from - * \param key pointer to the key (192 bit = 24 byte) - */ - void tdes_dec(void* out, const void* in, const void* key); - -#endif /*DES_H_*/ - -// Copied from des.h in desfire imp. -typedef unsigned long DES_KS[16][2]; /* Single-key DES key schedule */ -typedef unsigned long DES3_KS[48][2]; /* Triple-DES key schedule */ - - -extern int Asmversion; /* 1 if we're linked with an asm version, 0 if C */ diff --git a/armsrc/desfire_crypto.c b/armsrc/desfire_crypto.c deleted file mode 100644 index 9ea07371..00000000 --- a/armsrc/desfire_crypto.c +++ /dev/null @@ -1,642 +0,0 @@ -/*- - * Copyright (C) 2010, Romain Tartiere. - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - * $Id$ - */ - -/* - * This implementation was written based on information provided by the - * following documents: - * - * NIST Special Publication 800-38B - * Recommendation for Block Cipher Modes of Operation: The CMAC Mode for Authentication - * May 2005 - */ -#include "desfire_crypto.h" - -static void xor (const uint8_t *ivect, uint8_t *data, const size_t len); - -static size_t key_macing_length (desfirekey_t key); - -static void xor (const uint8_t *ivect, uint8_t *data, const size_t len) { - for (size_t i = 0; i < len; i++) { - data[i] ^= ivect[i]; - } -} - -void cmac_generate_subkeys ( desfirekey_t key) { - int kbs = key_block_size (key); - const uint8_t R = (kbs == 8) ? 0x1B : 0x87; - - uint8_t l[kbs]; - memset (l, 0, kbs); - - uint8_t ivect[kbs]; - memset (ivect, 0, kbs); - - mifare_cypher_blocks_chained (NULL, key, ivect, l, kbs, MCD_RECEIVE, MCO_ENCYPHER); - - bool xor = false; - - // Used to compute CMAC on complete blocks - memcpy (key->cmac_sk1, l, kbs); - xor = l[0] & 0x80; - lsl (key->cmac_sk1, kbs); - if (xor) - key->cmac_sk1[kbs-1] ^= R; - - // Used to compute CMAC on the last block if non-complete - memcpy (key->cmac_sk2, key->cmac_sk1, kbs); - xor = key->cmac_sk1[0] & 0x80; - lsl (key->cmac_sk2, kbs); - if (xor) - key->cmac_sk2[kbs-1] ^= R; -} - -void cmac (const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac) { - int kbs = key_block_size (key); - uint8_t *buffer = malloc (padded_data_length (len, kbs)); - - memcpy (buffer, data, len); - - if ((!len) || (len % kbs)) { - buffer[len++] = 0x80; - while (len % kbs) { - buffer[len++] = 0x00; - } - xor (key->cmac_sk2, buffer + len - kbs, kbs); - } else { - xor (key->cmac_sk1, buffer + len - kbs, kbs); - } - - mifare_cypher_blocks_chained (NULL, key, ivect, buffer, len, MCD_SEND, MCO_ENCYPHER); - - memcpy (cmac, ivect, kbs); -} - -size_t key_block_size (const desfirekey_t key) { - size_t block_size = 8; - - switch (key->type) { - case T_DES: - case T_3DES: - case T_3K3DES: - block_size = 8; - break; - case T_AES: - block_size = 16; - break; - } - - return block_size; -} - -/* - * Size of MACing produced with the key. - */ -static size_t key_macing_length (const desfirekey_t key) { - size_t mac_length = MAC_LENGTH; - - switch (key->type) { - case T_DES: - case T_3DES: - mac_length = MAC_LENGTH; - break; - case T_3K3DES: - case T_AES: - mac_length = CMAC_LENGTH; - break; - } - - return mac_length; -} - -/* - * Size required to store nbytes of data in a buffer of size n*block_size. - */ -size_t padded_data_length (const size_t nbytes, const size_t block_size) { - if ((!nbytes) || (nbytes % block_size)) - return ((nbytes / block_size) + 1) * block_size; - else - return nbytes; -} - -/* - * Buffer size required to MAC nbytes of data - */ -size_t maced_data_length (const desfirekey_t key, const size_t nbytes) { - return nbytes + key_macing_length (key); -} -/* - * Buffer size required to encipher nbytes of data and a two bytes CRC. - */ -size_t enciphered_data_length (const desfiretag_t tag, const size_t nbytes, int communication_settings) { - size_t crc_length = 0; - if (!(communication_settings & NO_CRC)) { - switch (DESFIRE(tag)->authentication_scheme) { - case AS_LEGACY: - crc_length = 2; - break; - case AS_NEW: - crc_length = 4; - break; - } - } - - size_t block_size = DESFIRE(tag)->session_key ? key_block_size (DESFIRE(tag)->session_key) : 1; - - return padded_data_length (nbytes + crc_length, block_size); -} - -void* mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes, off_t offset, int communication_settings) { - uint8_t *res = data; - uint8_t mac[4]; - size_t edl; - bool append_mac = true; - desfirekey_t key = DESFIRE(tag)->session_key; - - if (!key) - return data; - - switch (communication_settings & MDCM_MASK) { - case MDCM_PLAIN: - if (AS_LEGACY == DESFIRE(tag)->authentication_scheme) - break; - - /* - * When using new authentication methods, PLAIN data transmission from - * the PICC to the PCD are CMACed, so we have to maintain the - * cryptographic initialisation vector up-to-date to check data - * integrity later. - * - * The only difference with CMACed data transmission is that the CMAC - * is not apended to the data send by the PCD to the PICC. - */ - - append_mac = false; - - /* pass through */ - case MDCM_MACED: - switch (DESFIRE(tag)->authentication_scheme) { - case AS_LEGACY: - if (!(communication_settings & MAC_COMMAND)) - break; - - /* pass through */ - edl = padded_data_length (*nbytes - offset, key_block_size (DESFIRE(tag)->session_key)) + offset; - - // Fill in the crypto buffer with data ... - memcpy (res, data, *nbytes); - // ... and 0 padding - memset (res + *nbytes, 0, edl - *nbytes); - - mifare_cypher_blocks_chained (tag, NULL, NULL, res + offset, edl - offset, MCD_SEND, MCO_ENCYPHER); - - memcpy (mac, res + edl - 8, 4); - - // Copy again provided data (was overwritten by mifare_cypher_blocks_chained) - memcpy (res, data, *nbytes); - - if (!(communication_settings & MAC_COMMAND)) - break; - // Append MAC - size_t bla = maced_data_length (DESFIRE(tag)->session_key, *nbytes - offset) + offset; - bla++; - - memcpy (res + *nbytes, mac, 4); - - *nbytes += 4; - break; - case AS_NEW: - if (!(communication_settings & CMAC_COMMAND)) - break; - cmac (key, DESFIRE (tag)->ivect, res, *nbytes, DESFIRE (tag)->cmac); - - if (append_mac) { - maced_data_length (key, *nbytes); - - memcpy (res, data, *nbytes); - memcpy (res + *nbytes, DESFIRE (tag)->cmac, CMAC_LENGTH); - *nbytes += CMAC_LENGTH; - } - break; - } - - break; - case MDCM_ENCIPHERED: - /* |<-------------- data -------------->| - * |<--- offset -->| | - * +---------------+--------------------+-----+---------+ - * | CMD + HEADERS | DATA TO BE SECURED | CRC | PADDING | - * +---------------+--------------------+-----+---------+ ---------------- - * | |<~~~~v~~~~~~~~~~~~~>| ^ | | (DES / 3DES) - * | | `---- crc16() ----' | | - * | | | ^ | | ----- *or* ----- - * |<~~~~~~~~~~~~~~~~~~~~v~~~~~~~~~~~~~>| ^ | | (3K3DES / AES) - * | `---- crc32() ----' | | - * | | ---- *then* ---- - * |<---------------------------------->| - * encypher()/decypher() - */ - - if (!(communication_settings & ENC_COMMAND)) - break; - edl = enciphered_data_length (tag, *nbytes - offset, communication_settings) + offset; - - // Fill in the crypto buffer with data ... - memcpy (res, data, *nbytes); - if (!(communication_settings & NO_CRC)) { - // ... CRC ... - switch (DESFIRE (tag)->authentication_scheme) { - case AS_LEGACY: - AppendCrc14443a(res + offset, *nbytes - offset); - *nbytes += 2; - break; - case AS_NEW: - crc32_append (res, *nbytes); - *nbytes += 4; - break; - } - } - // ... and padding - memset (res + *nbytes, 0, edl - *nbytes); - - *nbytes = edl; - - mifare_cypher_blocks_chained (tag, NULL, NULL, res + offset, *nbytes - offset, MCD_SEND, (AS_NEW == DESFIRE(tag)->authentication_scheme) ? MCO_ENCYPHER : MCO_DECYPHER); - break; - default: - - *nbytes = -1; - res = NULL; - break; - } - - return res; - -} - -void* mifare_cryto_postprocess_data (desfiretag_t tag, void *data, ssize_t *nbytes, int communication_settings) -{ - void *res = data; - size_t edl; - void *edata = NULL; - uint8_t first_cmac_byte = 0x00; - - desfirekey_t key = DESFIRE(tag)->session_key; - - if (!key) - return data; - - // Return directly if we just have a status code. - if (1 == *nbytes) - return res; - - switch (communication_settings & MDCM_MASK) { - case MDCM_PLAIN: - - if (AS_LEGACY == DESFIRE(tag)->authentication_scheme) - break; - - /* pass through */ - case MDCM_MACED: - switch (DESFIRE (tag)->authentication_scheme) { - case AS_LEGACY: - if (communication_settings & MAC_VERIFY) { - *nbytes -= key_macing_length (key); - if (*nbytes <= 0) { - *nbytes = -1; - res = NULL; -#ifdef WITH_DEBUG - Dbprintf ("No room for MAC!"); -#endif - break; - } - - edl = enciphered_data_length (tag, *nbytes - 1, communication_settings); - edata = malloc (edl); - - memcpy (edata, data, *nbytes - 1); - memset ((uint8_t *)edata + *nbytes - 1, 0, edl - *nbytes + 1); - - mifare_cypher_blocks_chained (tag, NULL, NULL, edata, edl, MCD_SEND, MCO_ENCYPHER); - - if (0 != memcmp ((uint8_t *)data + *nbytes - 1, (uint8_t *)edata + edl - 8, 4)) { -#ifdef WITH_DEBUG - Dbprintf ("MACing not verified"); - hexdump ((uint8_t *)data + *nbytes - 1, key_macing_length (key), "Expect ", 0); - hexdump ((uint8_t *)edata + edl - 8, key_macing_length (key), "Actual ", 0); -#endif - DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR; - *nbytes = -1; - res = NULL; - } - } - break; - case AS_NEW: - if (!(communication_settings & CMAC_COMMAND)) - break; - if (communication_settings & CMAC_VERIFY) { - if (*nbytes < 9) { - *nbytes = -1; - res = NULL; - break; - } - first_cmac_byte = ((uint8_t *)data)[*nbytes - 9]; - ((uint8_t *)data)[*nbytes - 9] = ((uint8_t *)data)[*nbytes-1]; - } - - int n = (communication_settings & CMAC_VERIFY) ? 8 : 0; - cmac (key, DESFIRE (tag)->ivect, ((uint8_t *)data), *nbytes - n, DESFIRE (tag)->cmac); - - if (communication_settings & CMAC_VERIFY) { - ((uint8_t *)data)[*nbytes - 9] = first_cmac_byte; - if (0 != memcmp (DESFIRE (tag)->cmac, (uint8_t *)data + *nbytes - 9, 8)) { -#ifdef WITH_DEBUG - Dbprintf ("CMAC NOT verified :-("); - hexdump ((uint8_t *)data + *nbytes - 9, 8, "Expect ", 0); - hexdump (DESFIRE (tag)->cmac, 8, "Actual ", 0); -#endif - DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR; - *nbytes = -1; - res = NULL; - } else { - *nbytes -= 8; - } - } - break; - } - - free (edata); - - break; - case MDCM_ENCIPHERED: - (*nbytes)--; - bool verified = false; - int crc_pos = 0x00; - int end_crc_pos = 0x00; - uint8_t x; - - /* - * AS_LEGACY: - * ,-----------------+-------------------------------+--------+ - * \ BLOCK n-1 | BLOCK n | STATUS | - * / PAYLOAD | CRC0 | CRC1 | 0x80? | 0x000000000000 | 0x9100 | - * `-----------------+-------------------------------+--------+ - * - * <------------ DATA ------------> - * FRAME = PAYLOAD + CRC(PAYLOAD) + PADDING - * - * AS_NEW: - * ,-------------------------------+-----------------------------------------------+--------+ - * \ BLOCK n-1 | BLOCK n | STATUS | - * / PAYLOAD | CRC0 | CRC1 | CRC2 | CRC3 | 0x80? | 0x0000000000000000000000000000 | 0x9100 | - * `-------------------------------+-----------------------------------------------+--------+ - * <----------------------------------- DATA ------------------------------------->| - * - * <----------------- DATA ----------------> - * FRAME = PAYLOAD + CRC(PAYLOAD + STATUS) + PADDING + STATUS - * `------------------' - */ - - mifare_cypher_blocks_chained (tag, NULL, NULL, res, *nbytes, MCD_RECEIVE, MCO_DECYPHER); - - /* - * Look for the CRC and ensure it is followed by NULL padding. We - * can't start by the end because the CRC is supposed to be 0 when - * verified, and accumulating 0's in it should not change it. - */ - switch (DESFIRE (tag)->authentication_scheme) { - case AS_LEGACY: - crc_pos = *nbytes - 8 - 1; // The CRC can be over two blocks - if (crc_pos < 0) { - /* Single block */ - crc_pos = 0; - } - break; - case AS_NEW: - /* Move status between payload and CRC */ - res = DESFIRE (tag)->crypto_buffer; - memcpy (res, data, *nbytes); - - crc_pos = (*nbytes) - 16 - 3; - if (crc_pos < 0) { - /* Single block */ - crc_pos = 0; - } - memcpy ((uint8_t *)res + crc_pos + 1, (uint8_t *)res + crc_pos, *nbytes - crc_pos); - ((uint8_t *)res)[crc_pos] = 0x00; - crc_pos++; - *nbytes += 1; - break; - } - - do { - uint16_t crc16 =0x00; - uint32_t crc; - switch (DESFIRE (tag)->authentication_scheme) { - case AS_LEGACY: - end_crc_pos = crc_pos + 2; - AppendCrc14443a (res, end_crc_pos); - - // - - - crc = crc16; - break; - case AS_NEW: - end_crc_pos = crc_pos + 4; - crc32 (res, end_crc_pos, (uint8_t *)&crc); - break; - } - if (!crc) { - verified = true; - for (int n = end_crc_pos; n < *nbytes - 1; n++) { - uint8_t byte = ((uint8_t *)res)[n]; - if (!( (0x00 == byte) || ((0x80 == byte) && (n == end_crc_pos)) )) - verified = false; - } - } - if (verified) { - *nbytes = crc_pos; - switch (DESFIRE (tag)->authentication_scheme) { - case AS_LEGACY: - ((uint8_t *)data)[(*nbytes)++] = 0x00; - break; - case AS_NEW: - /* The status byte was already before the CRC */ - break; - } - } else { - switch (DESFIRE (tag)->authentication_scheme) { - case AS_LEGACY: - break; - case AS_NEW: - x = ((uint8_t *)res)[crc_pos - 1]; - ((uint8_t *)res)[crc_pos - 1] = ((uint8_t *)res)[crc_pos]; - ((uint8_t *)res)[crc_pos] = x; - break; - } - crc_pos++; - } - } while (!verified && (end_crc_pos < *nbytes)); - - if (!verified) { -#ifdef WITH_DEBUG - /* FIXME In some configurations, the file is transmitted PLAIN */ - Dbprintf("CRC not verified in decyphered stream"); -#endif - DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR; - *nbytes = -1; - res = NULL; - } - - break; - default: - Dbprintf("Unknown communication settings"); - *nbytes = -1; - res = NULL; - break; - - } - return res; -} - - -void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size) -{ - uint8_t ovect[MAX_CRYPTO_BLOCK_SIZE]; - - if (direction == MCD_SEND) { - xor (ivect, data, block_size); - } else { - memcpy (ovect, data, block_size); - } - - uint8_t edata[MAX_CRYPTO_BLOCK_SIZE]; - - switch (key->type) { - case T_DES: - switch (operation) { - case MCO_ENCYPHER: - //DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); - des_enc(edata, data, key->data); - break; - case MCO_DECYPHER: - //DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); - des_dec(edata, data, key->data); - break; - } - break; - case T_3DES: - switch (operation) { - case MCO_ENCYPHER: - // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); - // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT); - // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); - tdes_enc(edata,data, key->data); - break; - case MCO_DECYPHER: - // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); - // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT); - // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); - tdes_dec(data, edata, key->data); - break; - } - break; - case T_3K3DES: - switch (operation) { - case MCO_ENCYPHER: - tdes_enc(edata,data, key->data); - // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); - // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT); - // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_ENCRYPT); - break; - case MCO_DECYPHER: - tdes_dec(data, edata, key->data); - // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_DECRYPT); - // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT); - // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); - break; - } - break; - case T_AES: - switch (operation) - { - case MCO_ENCYPHER: - { - AesCtx ctx; - AesCtxIni(&ctx, ivect, key->data, KEY128,CBC); - AesEncrypt(&ctx, data, edata, sizeof(data) ); - break; - } - case MCO_DECYPHER: - { - AesCtx ctx; - AesCtxIni(&ctx, ivect, key->data, KEY128,CBC); - AesDecrypt(&ctx, edata, data, sizeof(edata)); - break; - } - } - break; - } - - memcpy (data, edata, block_size); - - if (direction == MCD_SEND) { - memcpy (ivect, data, block_size); - } else { - xor (ivect, data, block_size); - memcpy (ivect, ovect, block_size); - } -} - -/* - * This function performs all CBC cyphering / deciphering. - * - * The tag argument may be NULL, in which case both key and ivect shall be set. - * When using the tag session_key and ivect for processing data, these - * arguments should be set to NULL. - * - * Because the tag may contain additional data, one may need to call this - * function with tag, key and ivect defined. - */ -void mifare_cypher_blocks_chained (desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation) { - size_t block_size; - - if (tag) { - if (!key) - key = DESFIRE (tag)->session_key; - if (!ivect) - ivect = DESFIRE (tag)->ivect; - - switch (DESFIRE (tag)->authentication_scheme) { - case AS_LEGACY: - memset (ivect, 0, MAX_CRYPTO_BLOCK_SIZE); - break; - case AS_NEW: - break; - } - } - - block_size = key_block_size (key); - - size_t offset = 0; - while (offset < data_size) { - mifare_cypher_single_block (key, data + offset, ivect, direction, operation, block_size); - offset += block_size; - } -} \ No newline at end of file diff --git a/armsrc/desfire_crypto.h b/armsrc/desfire_crypto.h deleted file mode 100644 index 698f11e3..00000000 --- a/armsrc/desfire_crypto.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __DESFIRE_CRYPTO_H -#define __DESFIRE_CRYPTO_H - -#include -#include -#include -#include "printf.h" - -#include "iso14443a.h" -#include "../common/desfire.h" -#include "des.h" -//#include "aes.h" - -#endif diff --git a/armsrc/desfire_key.c b/armsrc/desfire_key.c deleted file mode 100644 index b3aa14e9..00000000 --- a/armsrc/desfire_key.c +++ /dev/null @@ -1,155 +0,0 @@ -/*- - * Copyright (C) 2010, Romain Tartiere. - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - * $Id$ - */ -#include -#include "desfire_key.h" - -static inline void update_key_schedules (desfirekey_t key); - -static inline void update_key_schedules (desfirekey_t key) { - // DES_set_key ((DES_cblock *)key->data, &(key->ks1)); - // DES_set_key ((DES_cblock *)(key->data + 8), &(key->ks2)); - // if (T_3K3DES == key->type) { - // DES_set_key ((DES_cblock *)(key->data + 16), &(key->ks3)); - // } -} - -void Desfire_des_key_new (const uint8_t value[8], desfirekey_t key) { - uint8_t data[8]; - memcpy (data, value, 8); - for (int n=0; n < 8; n++) - data[n] &= 0xfe; - Desfire_des_key_new_with_version (data, key); -} - -void Desfire_des_key_new_with_version (const uint8_t value[8], desfirekey_t key) { - if ( key != NULL) { - key->type = T_DES; - memcpy (key->data, value, 8); - memcpy (key->data+8, value, 8); - update_key_schedules (key); - } -} - -void Desfire_3des_key_new (const uint8_t value[16], desfirekey_t key) { - uint8_t data[16]; - memcpy (data, value, 16); - for (int n=0; n < 8; n++) - data[n] &= 0xfe; - for (int n=8; n < 16; n++) - data[n] |= 0x01; - Desfire_3des_key_new_with_version (data, key); -} - -void Desfire_3des_key_new_with_version (const uint8_t value[16], desfirekey_t key) { - if ( key != NULL ){ - key->type = T_3DES; - memcpy (key->data, value, 16); - update_key_schedules (key); - } -} - -void Desfire_3k3des_key_new (const uint8_t value[24], desfirekey_t key) { - uint8_t data[24]; - memcpy (data, value, 24); - for (int n=0; n < 8; n++) - data[n] &= 0xfe; - Desfire_3k3des_key_new_with_version (data, key); -} - -void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t key) { - if ( key != NULL){ - key->type = T_3K3DES; - memcpy (key->data, value, 24); - update_key_schedules (key); - } -} - - void Desfire_aes_key_new (const uint8_t value[16], desfirekey_t key) { - Desfire_aes_key_new_with_version (value, 0, key); -} - - void Desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version, desfirekey_t key) { - - if (key != NULL) { - memcpy (key->data, value, 16); - key->type = T_AES; - key->aes_version = version; - } -} - -uint8_t Desfire_key_get_version (desfirekey_t key) { - uint8_t version = 0; - - for (int n = 0; n < 8; n++) { - version |= ((key->data[n] & 1) << (7 - n)); - } - return version; -} - -void Desfire_key_set_version (desfirekey_t key, uint8_t version) -{ - for (int n = 0; n < 8; n++) { - uint8_t version_bit = ((version & (1 << (7-n))) >> (7-n)); - key->data[n] &= 0xfe; - key->data[n] |= version_bit; - if (key->type == T_DES) { - key->data[n+8] = key->data[n]; - } else { - // Write ~version to avoid turning a 3DES key into a DES key - key->data[n+8] &= 0xfe; - key->data[n+8] |= ~version_bit; - } - } -} - -void Desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key) { - - uint8_t buffer[24]; - - switch (authkey->type) { - case T_DES: - memcpy (buffer, rnda, 4); - memcpy (buffer+4, rndb, 4); - Desfire_des_key_new_with_version (buffer, key); - break; - case T_3DES: - memcpy (buffer, rnda, 4); - memcpy (buffer+4, rndb, 4); - memcpy (buffer+8, rnda+4, 4); - memcpy (buffer+12, rndb+4, 4); - Desfire_3des_key_new_with_version (buffer, key); - break; - case T_3K3DES: - memcpy (buffer, rnda, 4); - memcpy (buffer+4, rndb, 4); - memcpy (buffer+8, rnda+6, 4); - memcpy (buffer+12, rndb+6, 4); - memcpy (buffer+16, rnda+12, 4); - memcpy (buffer+20, rndb+12, 4); - Desfire_3k3des_key_new (buffer, key); - break; - case T_AES: - memcpy (buffer, rnda, 4); - memcpy (buffer+4, rndb, 4); - memcpy (buffer+8, rnda+12, 4); - memcpy (buffer+12, rndb+12, 4); - Desfire_aes_key_new (buffer, key); - break; - } -} \ No newline at end of file diff --git a/armsrc/desfire_key.h b/armsrc/desfire_key.h deleted file mode 100644 index 0d99903e..00000000 --- a/armsrc/desfire_key.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __DESFIRE_KEY_INCLUDED -#define __DESFIRE_KEY_INCLUDED -#include "iso14443a.h" -// desfire_key.h -void Desfire_des_key_new (const uint8_t value[8], desfirekey_t key); -void Desfire_3des_key_new (const uint8_t value[16], desfirekey_t key); -void Desfire_des_key_new_with_version (const uint8_t value[8], desfirekey_t key); -void Desfire_3des_key_new_with_version (const uint8_t value[16], desfirekey_t key); -void Desfire_3k3des_key_new (const uint8_t value[24], desfirekey_t key); -void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t key); -void Desfire_aes_key_new (const uint8_t value[16], desfirekey_t key); -void Desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version,desfirekey_t key); -uint8_t Desfire_key_get_version (desfirekey_t key); -void Desfire_key_set_version (desfirekey_t key, uint8_t version); -void Desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key); - -#endif \ No newline at end of file diff --git a/armsrc/epa.c b/armsrc/epa.c index 0bbd2dd7..bec79e61 100644 --- a/armsrc/epa.c +++ b/armsrc/epa.c @@ -13,7 +13,7 @@ #include "iso14443a.h" #include "epa.h" -#include "../common/cmd.h" +#include "cmd.h" // Protocol and Parameter Selection Request // use regular (1x) speed in both directions @@ -224,7 +224,7 @@ static void EPA_PACE_Collect_Nonce_Abort(uint8_t step, int func_return) EPA_Finish(); // send the USB packet - cmd_send(CMD_ACK,step,func_return,0,0,0); + cmd_send(CMD_ACK,step,func_return,0,0,0); } //----------------------------------------------------------------------------- @@ -252,15 +252,13 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c) // set up communication func_return = EPA_Setup(); - if (func_return != 0) { + if (func_return != 0) { EPA_PACE_Collect_Nonce_Abort(1, func_return); - Dbprintf("epa: setup fucked up! %d", func_return); return; } // increase the timeout (at least some cards really do need this!) iso14a_set_timeout(0x0002FFFF); - Dbprintf("epa: Epic!"); // read the CardAccess file // this array will hold the CardAccess file @@ -268,13 +266,10 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c) int card_access_length = EPA_Read_CardAccess(card_access, 256); // the response has to be at least this big to hold the OID if (card_access_length < 18) { - Dbprintf("epa: Too small!"); EPA_PACE_Collect_Nonce_Abort(2, card_access_length); return; } - Dbprintf("epa: foo!"); - // this will hold the PACE info of the card pace_version_info_t pace_version_info; // search for the PACE OID @@ -286,8 +281,6 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c) return; } - Dbprintf("epa: bar!"); - // initiate the PACE protocol // use the CAN for the password since that doesn't change func_return = EPA_PACE_MSE_Set_AT(pace_version_info, 2); @@ -309,7 +302,7 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c) // save received information // ack->arg[1] = func_return; // memcpy(ack->d.asBytes, nonce, func_return); - cmd_send(CMD_ACK,0,func_return,0,nonce,func_return); + cmd_send(CMD_ACK,0,func_return,0,nonce,func_return); } //----------------------------------------------------------------------------- @@ -432,7 +425,7 @@ int EPA_Setup() // power up the field iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); - + iso14a_set_timeout(10500); // select the card diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 32e0500e..077b378a 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -9,8 +9,7 @@ // Routines to load the FPGA image, and then to configure the FPGA's major // mode once it is configured. //----------------------------------------------------------------------------- - -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" #include "util.h" #include "string.h" diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index dc4c4232..27a5d508 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -16,10 +16,10 @@ // (c) 2012 Roel Verdult //----------------------------------------------------------------------------- -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" #include "util.h" -#include "../include/hitag2.h" +#include "hitag2.h" #include "string.h" static bool bQuiet; @@ -744,7 +744,7 @@ void SnoopHitag(uint32_t type) { // Set up eavesdropping mode, frequency divisor which will drive the FPGA // and analog mux selection. FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); RELAY_OFF(); @@ -968,7 +968,7 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) { // Set up simulator mode, frequency divisor which will drive the FPGA // and analog mux selection. FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz SetAdcMuxFor(GPIO_MUXSEL_LOPKD); RELAY_OFF(); @@ -987,7 +987,7 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) { AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; - // Disable timer during configuration + // Disable timer during configuration AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, @@ -1140,7 +1140,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { case RHT2F_PASSWORD: { Dbprintf("List identifier in password mode"); memcpy(password,htd->pwd.password,4); - blocknr = 0; + blocknr = 0; bQuitTraceFull = false; bQuiet = false; bPwd = false; @@ -1158,7 +1158,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { case RHT2F_CRYPTO: { DbpString("Authenticating using key:"); - memcpy(key,htd->crypto.key,6); // 4 or 6 ?? + memcpy(key,htd->crypto.key,4); //HACK; 4 or 6?? I read both in the code. Dbhexdump(6,key,false); blocknr = 0; bQuiet = false; diff --git a/armsrc/iclass.c b/armsrc/iclass.c index cf1931fd..625cf39b 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -36,7 +36,7 @@ // //----------------------------------------------------------------------------- -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" #include "util.h" #include "string.h" @@ -45,11 +45,9 @@ // Needed for CRC in emulation mode; // same construction as in ISO 14443; // different initial value (CRC_ICLASS) -#include "../common/iso14443crc.h" -#include "../common/iso15693tools.h" +#include "iso14443crc.h" #include "iso15693tools.h" - static int timeout = 4096; @@ -353,7 +351,7 @@ static struct { SUB_SECOND_HALF, SUB_BOTH } sub; - uint8_t *output; + uint8_t *output; } Demod; static RAMFUNC int ManchesterDecoding(int v) @@ -435,7 +433,7 @@ static RAMFUNC int ManchesterDecoding(int v) else { modulation = bit & Demod.syncBit; modulation |= ((bit << 1) ^ ((Demod.buffer & 0x08) >> 3)) & Demod.syncBit; - + Demod.samples += 4; if(Demod.posCount==0) { @@ -645,7 +643,7 @@ void RAMFUNC SnoopIClass(void) uint8_t *readerToTagCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET); // The response (tag -> reader) that we're receiving. uint8_t *tagToReaderResponse = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET); - + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); // reset traceLen to 0 @@ -744,7 +742,7 @@ void RAMFUNC SnoopIClass(void) //if(!LogTrace(Uart.output,Uart.byteCnt, rsamples, Uart.parityBits,TRUE)) break; //if(!LogTrace(NULL, 0, Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, 0, TRUE)) break; - if(tracing) { + if(tracing) { uint8_t parity[MAX_PARITY_SIZE]; GetParity(Uart.output, Uart.byteCnt, parity); LogTrace(Uart.output,Uart.byteCnt, (GetCountSspClk()-time_0) << 4, (GetCountSspClk()-time_0) << 4, parity, TRUE); @@ -768,7 +766,7 @@ void RAMFUNC SnoopIClass(void) rsamples = samples - Demod.samples; LED_B_ON(); - if(tracing) { + if(tracing) { uint8_t parity[MAX_PARITY_SIZE]; GetParity(Demod.output, Demod.len, parity); LogTrace(Demod.output, Demod.len, (GetCountSspClk()-time_0) << 4, (GetCountSspClk()-time_0) << 4, parity, FALSE); @@ -1267,18 +1265,18 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int if (wait) { if(*wait < 10) *wait = 10; - - for(c = 0; c < *wait;) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing! - c++; - } - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR; - (void)r; - } - WDT_HIT(); - } + + for(c = 0; c < *wait;) { + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing! + c++; + } + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR; + (void)r; + } + WDT_HIT(); + } } @@ -1361,19 +1359,19 @@ void CodeIClassCommand(const uint8_t * cmd, int len) void ReaderTransmitIClass(uint8_t* frame, int len) { - int wait = 0; - int samples = 0; + int wait = 0; + int samples = 0; - // This is tied to other size changes - CodeIClassCommand(frame,len); + // This is tied to other size changes + CodeIClassCommand(frame,len); - // Select the card - TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait); - if(trigger) - LED_A_ON(); + // Select the card + TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait); + if(trigger) + LED_A_ON(); - // Store reader command in buffer - if (tracing) { + // Store reader command in buffer + if (tracing) { uint8_t par[MAX_PARITY_SIZE]; GetParity(frame, len, par); LogTrace(frame, len, rsamples, rsamples, par, TRUE); @@ -1408,7 +1406,7 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, for(;;) { WDT_HIT(); - if(BUTTON_PRESS()) return FALSE; + if(BUTTON_PRESS()) return FALSE; if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = 0x00; // To make use of exact timing of next command from reader!! @@ -1433,10 +1431,10 @@ int ReaderReceiveIClass(uint8_t* receivedAnswer) int samples = 0; if (!GetIClassAnswer(receivedAnswer,160,&samples,0)) return FALSE; rsamples += samples; - if (tracing){ - uint8_t parity[MAX_PARITY_SIZE]; - GetParity(receivedAnswer, Demod.len, parity); - LogTrace(receivedAnswer,Demod.len,rsamples,rsamples,parity,FALSE); + if (tracing) { + uint8_t parity[MAX_PARITY_SIZE]; + GetParity(receivedAnswer, Demod.len, parity); + LogTrace(receivedAnswer,Demod.len,rsamples,rsamples,parity,FALSE); } if(samples == 0) return FALSE; return Demod.len; @@ -1539,7 +1537,7 @@ void ReaderIClass(uint8_t arg0) { uint8_t card_data[24]={0}; uint8_t last_csn[8]={0}; - + int read_status= 0; bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE; bool get_cc = arg0 & FLAG_ICLASS_READER_GET_CC; @@ -1554,7 +1552,7 @@ void ReaderIClass(uint8_t arg0) { DbpString("Trace full"); break; } - WDT_HIT(); + WDT_HIT(); read_status = handshakeIclassTag(card_data); @@ -1562,24 +1560,24 @@ void ReaderIClass(uint8_t arg0) { if(read_status == 1) datasize = 8; if(read_status == 2) datasize = 16; - LED_B_ON(); - //Send back to client, but don't bother if we already sent this - if(memcmp(last_csn, card_data, 8) != 0) + LED_B_ON(); + //Send back to client, but don't bother if we already sent this + if(memcmp(last_csn, card_data, 8) != 0) { if(!get_cc || (get_cc && read_status == 2)) { - cmd_send(CMD_ACK,read_status,0,0,card_data,datasize); + cmd_send(CMD_ACK,read_status,0,0,card_data,datasize); if(abort_after_read) { LED_A_OFF(); return; } - //Save that we already sent this.... - memcpy(last_csn, card_data, 8); + //Save that we already sent this.... + memcpy(last_csn, card_data, 8); } //If 'get_cc' was specified and we didn't get a CC, we'll just keep trying... } - LED_B_OFF(); + LED_B_OFF(); } cmd_send(CMD_ACK,0,0,0,card_data, 0); LED_A_OFF(); @@ -1614,14 +1612,14 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { } memory; uint8_t* resp = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET); - + setupIclassReader(); while(!BUTTON_PRESS()) { WDT_HIT(); - + if(traceLen > TRACE_SIZE) { DbpString("Trace full"); break; @@ -1630,20 +1628,20 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { uint8_t read_status = handshakeIclassTag(card_data); if(read_status < 2) continue; - //for now replay captured auth (as cc not updated) - memcpy(check+5,MAC,4); + //for now replay captured auth (as cc not updated) + memcpy(check+5,MAC,4); if(sendCmdGetResponseWithRetries(check, sizeof(check),resp, 4, 5)) { - Dbprintf("Error: Authentication Fail!"); + Dbprintf("Error: Authentication Fail!"); continue; - } + } //first get configuration block (block 1) crc = block_crc_LUT[1]; - read[1]=1; - read[2] = crc >> 8; - read[3] = crc & 0xff; + read[1]=1; + read[2] = crc >> 8; + read[3] = crc & 0xff; if(sendCmdGetResponseWithRetries(read, sizeof(read),resp, 10, 10)) { @@ -1651,30 +1649,30 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { continue; } - mem=resp[5]; - memory.k16= (mem & 0x80); - memory.book= (mem & 0x20); - memory.k2= (mem & 0x8); - memory.lockauth= (mem & 0x2); - memory.keyaccess= (mem & 0x1); + mem=resp[5]; + memory.k16= (mem & 0x80); + memory.book= (mem & 0x20); + memory.k2= (mem & 0x8); + memory.lockauth= (mem & 0x2); + memory.keyaccess= (mem & 0x1); cardsize = memory.k16 ? 255 : 32; WDT_HIT(); - //then loop around remaining blocks + //then loop around remaining blocks for(int block=0; block < cardsize; block++){ read[1]= block; crc = block_crc_LUT[block]; - read[2] = crc >> 8; - read[3] = crc & 0xff; + read[2] = crc >> 8; + read[3] = crc & 0xff; if(!sendCmdGetResponseWithRetries(read, sizeof(read), resp, 10, 10)) { - Dbprintf(" %02x: %02x %02x %02x %02x %02x %02x %02x %02x", + Dbprintf(" %02x: %02x %02x %02x %02x %02x %02x %02x %02x", block, resp[0], resp[1], resp[2], - resp[3], resp[4], resp[5], - resp[6], resp[7]); + resp[3], resp[4], resp[5], + resp[6], resp[7]); }else{ Dbprintf("Failed to dump block %d", block); @@ -1702,10 +1700,10 @@ void IClass_iso14443A_write(uint8_t arg0, uint8_t blockNo, uint8_t *data, uint8_ uint16_t crc = 0; - uint8_t* resp = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET); + uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // Reset trace buffer - memset(trace, 0x44, RECV_CMD_OFFSET); + memset(trace, 0x44, RECV_CMD_OFFSET); traceLen = 0; // Setup SSC diff --git a/armsrc/iso14443.c b/armsrc/iso14443.c index 775c583a..e9483189 100644 --- a/armsrc/iso14443.c +++ b/armsrc/iso14443.c @@ -10,12 +10,12 @@ // supported. //----------------------------------------------------------------------------- -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" #include "util.h" #include "string.h" -#include "../common/iso14443crc.h" +#include "iso14443crc.h" //static void GetSamplesFor14443(int weTx, int n); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 8399c6f8..c2f809fe 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -10,12 +10,13 @@ // Routines to support ISO 14443 type A. //----------------------------------------------------------------------------- -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" #include "util.h" #include "string.h" -#include "../common/cmd.h" -#include "../common/iso14443crc.h" +#include "cmd.h" + +#include "iso14443crc.h" #include "iso14443a.h" #include "crapto1.h" #include "mifareutil.h" @@ -169,7 +170,7 @@ byte_t oddparity (const byte_t bt) return OddByteParity[bt]; } -void GetParity(const uint8_t * pbtCmd, uint16_t iLen, uint8_t *par) +void GetParity(const uint8_t *pbtCmd, uint16_t iLen, uint8_t *par) { uint16_t paritybit_cnt = 0; uint16_t paritybyte_cnt = 0; @@ -179,15 +180,15 @@ void GetParity(const uint8_t * pbtCmd, uint16_t iLen, uint8_t *par) // Generate the parity bits parityBits |= ((OddByteParity[pbtCmd[i]]) << (7-paritybit_cnt)); if (paritybit_cnt == 7) { - par[paritybyte_cnt] = parityBits; // save 8 Bits parity - parityBits = 0; // and advance to next Parity Byte + par[paritybyte_cnt] = parityBits; // save 8 Bits parity + parityBits = 0; // and advance to next Parity Byte paritybyte_cnt++; paritybit_cnt = 0; } else { - paritybit_cnt++; + paritybit_cnt++; } } - + // save remaining parity bits par[paritybyte_cnt] = parityBits; @@ -203,7 +204,7 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_ { if (!tracing) return FALSE; - uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity + uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity uint16_t duration = timestamp_end - timestamp_start; // Return when trace is full @@ -218,7 +219,7 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_ // 16 bits data length (little endian, Highest Bit used as readerToTag flag) // y Bytes data // x Bytes parity (one byte per 8 bytes data) - + // timestamp (start) trace[traceLen++] = ((timestamp_start >> 0) & 0xff); trace[traceLen++] = ((timestamp_start >> 8) & 0xff); @@ -228,28 +229,28 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_ // duration trace[traceLen++] = ((duration >> 0) & 0xff); trace[traceLen++] = ((duration >> 8) & 0xff); - + // data length trace[traceLen++] = ((iLen >> 0) & 0xff); trace[traceLen++] = ((iLen >> 8) & 0xff); - + // readerToTag flag if (!readerToTag) { trace[traceLen - 1] |= 0x80; - } + } // data bytes if (btBytes != NULL && iLen != 0) { memcpy(trace + traceLen, btBytes, iLen); } - traceLen += iLen; - + traceLen += iLen; + // parity bytes if (parity != NULL && iLen != 0) { memcpy(trace + traceLen, parity, num_paritybytes); } traceLen += num_paritybytes; - + return TRUE; } @@ -307,7 +308,7 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) Uart.twoBits = (Uart.twoBits << 8) | bit; - if (Uart.state == STATE_UNSYNCD) { // not yet synced + if (Uart.state == STATE_UNSYNCD) { // not yet synced if (Uart.highCnt < 7) { // wait for a stable unmodulated signal if (Uart.twoBits == 0xffff) { @@ -315,7 +316,7 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) } else { Uart.highCnt = 0; } - } else { + } else { Uart.syncBit = 0xFFFF; // not set // look for 00xx1111 (the start bit) if ((Uart.twoBits & 0x6780) == 0x0780) Uart.syncBit = 7; @@ -355,9 +356,9 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit Uart.bitCount = 0; Uart.shiftReg = 0; - if((Uart.len & 0x0007) == 0) { // every 8 data bytes - Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits - Uart.parityBits = 0; + if((Uart.len&0x0007) == 0) { // every 8 data bytes + Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits + Uart.parityBits = 0; } } } @@ -374,32 +375,32 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit Uart.bitCount = 0; Uart.shiftReg = 0; - if ((Uart.len & 0x0007) == 0) { // every 8 data bytes - Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits + if ((Uart.len&0x0007) == 0) { // every 8 data bytes + Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits Uart.parityBits = 0; } } } else { // no modulation in both halves - Sequence Y if (Uart.state == STATE_MILLER_Z || Uart.state == STATE_MILLER_Y) { // Y after logic "0" - End of Communication Uart.state = STATE_UNSYNCD; - Uart.bitCount--; // last "0" was part of EOC sequence - Uart.shiftReg <<= 1; // drop it - if(Uart.bitCount > 0) { // if we decoded some bits - Uart.shiftReg >>= (9 - Uart.bitCount); // right align them - Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); // add last byte to the output - Uart.parityBits <<= 1; // add a (void) parity bit - Uart.parityBits <<= (8 - (Uart.len & 0x0007)); // left align parity bits - Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store it - return TRUE; - } else if (Uart.len & 0x0007) { // there are some parity bits to store - Uart.parityBits <<= (8 - (Uart.len & 0x0007)); // left align remaining parity bits - Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store them + Uart.bitCount--; // last "0" was part of EOC sequence + Uart.shiftReg <<= 1; // drop it + if(Uart.bitCount > 0) { // if we decoded some bits + Uart.shiftReg >>= (9 - Uart.bitCount); // right align them + Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); // add last byte to the output + Uart.parityBits <<= 1; // add a (void) parity bit + Uart.parityBits <<= (8 - (Uart.len&0x0007)); // left align parity bits + Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store it + return TRUE; + } else if (Uart.len & 0x0007) { // there are some parity bits to store + Uart.parityBits <<= (8 - (Uart.len&0x0007)); // left align remaining parity bits + Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store them } - if ( Uart.len) { - return TRUE; // we are finished with decoding the raw data sequence + if (Uart.len) { + return TRUE; // we are finished with decoding the raw data sequence } else { UartReset(); // Nothing receiver - start over - } + } } if (Uart.state == STATE_START_OF_COMMUNICATION) { // error - must not follow directly after SOC UartReset(); @@ -414,8 +415,8 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit Uart.bitCount = 0; Uart.shiftReg = 0; - if ((Uart.len & 0x0007) == 0) { // every 8 data bytes - Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits + if ((Uart.len&0x0007) == 0) { // every 8 data bytes + Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits Uart.parityBits = 0; } } @@ -423,7 +424,7 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) } } - } + } return FALSE; // not finished yet, need more data } @@ -527,8 +528,8 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non Demod.parityBits |= ((Demod.shiftReg >> 8) & 0x01); // store parity bit Demod.bitCount = 0; Demod.shiftReg = 0; - if((Demod.len & 0x0007) == 0) { // every 8 data bytes - Demod.parity[Demod.parityLen++] = Demod.parityBits; // store 8 parity bits + if((Demod.len&0x0007) == 0) { // every 8 data bytes + Demod.parity[Demod.parityLen++] = Demod.parityBits; // store 8 parity bits Demod.parityBits = 0; } } @@ -543,26 +544,26 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non Demod.parityBits |= ((Demod.shiftReg >> 8) & 0x01); // store parity bit Demod.bitCount = 0; Demod.shiftReg = 0; - if ((Demod.len & 0x0007) == 0) { // every 8 data bytes - Demod.parity[Demod.parityLen++] = Demod.parityBits; // store 8 parity bits1 + if ((Demod.len&0x0007) == 0) { // every 8 data bytes + Demod.parity[Demod.parityLen++] = Demod.parityBits; // store 8 parity bits1 Demod.parityBits = 0; } } Demod.endTime = Demod.startTime + 8*(9*Demod.len + Demod.bitCount + 1); } else { // no modulation in both halves - End of communication - if(Demod.bitCount > 0) { // there are some remaining data bits - Demod.shiftReg >>= (9 - Demod.bitCount); // right align the decoded bits - Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output - Demod.parityBits <<= 1; // add a (void) parity bit - Demod.parityBits <<= (8 - (Demod.len & 0x0007)); // left align remaining parity bits - Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them - return TRUE; - } else if (Demod.len & 0x0007) { // there are some parity bits to store - Demod.parityBits <<= (8 - (Demod.len & 0x0007)); // left align remaining parity bits - Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them - } - if (Demod.len) { - return TRUE; // we are finished with decoding the raw data sequence + if(Demod.bitCount > 0) { // there are some remaining data bits + Demod.shiftReg >>= (9 - Demod.bitCount); // right align the decoded bits + Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output + Demod.parityBits <<= 1; // add a (void) parity bit + Demod.parityBits <<= (8 - (Demod.len&0x0007)); // left align remaining parity bits + Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them + return TRUE; + } else if (Demod.len & 0x0007) { // there are some parity bits to store + Demod.parityBits <<= (8 - (Demod.len&0x0007)); // left align remaining parity bits + Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them + } + if (Demod.len) { + return TRUE; // we are finished with decoding the raw data sequence } else { // nothing received. Start over DemodReset(); } @@ -627,10 +628,10 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { // Set up the demodulator for tag -> reader responses. DemodInit(receivedResponse, receivedResponsePar); - + // Set up the demodulator for the reader -> tag commands UartInit(receivedCmd, receivedCmdPar); - + // Setup and start DMA. FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); @@ -687,12 +688,12 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { if ((!triggered) && (param & 0x02) && (Uart.len == 1) && (Uart.bitCount == 7)) triggered = TRUE; if(triggered) { - if (!LogTrace(receivedCmd, - Uart.len, - Uart.startTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, - Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, - Uart.parity, - TRUE)) break; + if (!LogTrace(receivedCmd, + Uart.len, + Uart.startTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, + Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, + Uart.parity, + TRUE)) break; } /* And ready to receive another command. */ UartReset(); @@ -709,12 +710,12 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { if(ManchesterDecoding(tagdata, 0, (rsamples-1)*4)) { LED_B_ON(); - if (!LogTrace(receivedResponse, - Demod.len, - Demod.startTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, - Demod.endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, - Demod.parity, - FALSE)) break; + if (!LogTrace(receivedResponse, + Demod.len, + Demod.startTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, + Demod.endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, + Demod.parity, + FALSE)) break; if ((!triggered) && (param & 0x01)) triggered = TRUE; @@ -745,7 +746,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { //----------------------------------------------------------------------------- // Prepare tag messages //----------------------------------------------------------------------------- -static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity) +static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity) { ToSendReset(); @@ -763,7 +764,7 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *pa ToSend[++ToSendMax] = SEC_D; LastProxToAirDuration = 8 * ToSendMax - 4; - for( uint16_t i = 0; i < len; i++) { + for(uint16_t i = 0; i < len; i++) { uint8_t b = cmd[i]; // Data bits @@ -1034,8 +1035,8 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); uint8_t response5[] = { 0x00, 0x00, 0x00, 0x00 }; // Very random tag nonce - uint8_t response6[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 }; // dummy ATS (pseudo-ATR), answer to RATS: - // Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present, + uint8_t response6[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 }; // dummy ATS (pseudo-ATR), answer to RATS: + // Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present, // TA(1) = 0x80: different divisors not supported, DR = 1, DS = 1 // TB(1) = not present. Defaults: FWI = 4 (FWT = 256 * 16 * 2^4 * 1/fc = 4833us), SFGI = 0 (SFG = 256 * 16 * 2^0 * 1/fc = 302us) // TC(1) = 0x02: CID supported, NAD not supported @@ -1091,7 +1092,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) // buffers used on software Uart: uint8_t *receivedCmd = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET; uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET; - + cmdsRecvd = 0; tag_response_info_t* p_response; @@ -1101,7 +1102,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) if(!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) { DbpString("Button press"); - break; + break; } p_response = NULL; @@ -1323,14 +1324,14 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing } } - NextTransferTime = MAX(NextTransferTime, LastTimeProxToAirStart + REQUEST_GUARD_TIME); + NextTransferTime = MAX(NextTransferTime, LastTimeProxToAirStart + REQUEST_GUARD_TIME); } //----------------------------------------------------------------------------- // Prepare reader command (in bits, support short frames) to send to FPGA //----------------------------------------------------------------------------- -void CodeIso14443aBitsAsReaderPar(const uint8_t * cmd, uint16_t bits, const uint8_t *parity) +void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8_t *parity) { int i, j; int last; @@ -1411,7 +1412,7 @@ void CodeIso14443aBitsAsReaderPar(const uint8_t * cmd, uint16_t bits, const uint //----------------------------------------------------------------------------- // Prepare reader command to send to FPGA //----------------------------------------------------------------------------- -void CodeIso14443aAsReaderPar(const uint8_t * cmd, uint16_t len, const uint8_t *parity) +void CodeIso14443aAsReaderPar(const uint8_t *cmd, uint16_t len, const uint8_t *parity) { CodeIso14443aBitsAsReaderPar(cmd, len*8, parity); } @@ -1595,7 +1596,7 @@ int EmSendCmdEx(uint8_t *resp, uint16_t respLen, bool correctionNeeded){ GetParity(resp, respLen, par); return EmSendCmdExPar(resp, respLen, correctionNeeded, par); } - + int EmSendCmd(uint8_t *resp, uint16_t respLen){ uint8_t par[MAX_PARITY_SIZE]; GetParity(resp, respLen, par); @@ -1610,16 +1611,16 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity) { if (tracing) { - // we cannot exactly measure the end and start of a received command from reader. However we know that the delay from - // end of the received command to start of the tag's (simulated by us) answer is n*128+20 or n*128+84 resp. - // with n >= 9. The start of the tags answer can be measured and therefore the end of the received command be calculated: - uint16_t reader_modlen = reader_EndTime - reader_StartTime; - uint16_t approx_fdt = tag_StartTime - reader_EndTime; - uint16_t exact_fdt = (approx_fdt - 20 + 32)/64 * 64 + 20; - reader_EndTime = tag_StartTime - exact_fdt; - reader_StartTime = reader_EndTime - reader_modlen; - if (!LogTrace(reader_data, reader_len, reader_StartTime, reader_EndTime, reader_Parity, TRUE)) { - return FALSE; + // we cannot exactly measure the end and start of a received command from reader. However we know that the delay from + // end of the received command to start of the tag's (simulated by us) answer is n*128+20 or n*128+84 resp. + // with n >= 9. The start of the tags answer can be measured and therefore the end of the received command be calculated: + uint16_t reader_modlen = reader_EndTime - reader_StartTime; + uint16_t approx_fdt = tag_StartTime - reader_EndTime; + uint16_t exact_fdt = (approx_fdt - 20 + 32)/64 * 64 + 20; + reader_EndTime = tag_StartTime - exact_fdt; + reader_StartTime = reader_EndTime - reader_modlen; + if (!LogTrace(reader_data, reader_len, reader_StartTime, reader_EndTime, reader_Parity, TRUE)) { + return FALSE; } else return(!LogTrace(tag_data, tag_len, tag_StartTime, tag_EndTime, tag_Parity, FALSE)); } else { return TRUE; @@ -1643,7 +1644,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive // Now get the answer from the card DemodInit(receivedResponse, receivedResponsePar); - + // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; @@ -1685,23 +1686,23 @@ void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *tim void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing) { - // Generate parity and redirect - uint8_t par[MAX_PARITY_SIZE]; - GetParity(frame, len/8, par); - ReaderTransmitBitsPar(frame, len, par, timing); + // Generate parity and redirect + uint8_t par[MAX_PARITY_SIZE]; + GetParity(frame, len/8, par); + ReaderTransmitBitsPar(frame, len, par, timing); } void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing) { - // Generate parity and redirect - uint8_t par[MAX_PARITY_SIZE]; - GetParity(frame, len, par); - ReaderTransmitBitsPar(frame, len*8, par, timing); + // Generate parity and redirect + uint8_t par[MAX_PARITY_SIZE]; + GetParity(frame, len, par); + ReaderTransmitBitsPar(frame, len*8, par, timing); } int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity) { - if (!GetIso14443aAnswerFromTag(receivedAnswer,parity,offset)) return FALSE; + if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset)) return FALSE; if (tracing) { LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, FALSE); } @@ -1720,34 +1721,26 @@ int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity) /* performs iso14443a anticollision procedure * fills the uid pointer unless NULL * fills resp_data unless NULL */ -int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, uint32_t* cuid_ptr) { - - //uint8_t deselect[] = {0xc2}; //DESELECT - //uint8_t halt[] = { 0x50, 0x00, 0x57, 0xCD }; // HALT - uint8_t wupa[] = { 0x52 }; // WAKE-UP - //uint8_t reqa[] = { 0x26 }; // REQUEST A +int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr) { + uint8_t wupa[] = { 0x52 }; // 0x26 - REQA 0x52 - WAKE-UP uint8_t sel_all[] = { 0x93,0x20 }; uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0 uint8_t *resp = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET; uint8_t *resp_par = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET; - byte_t uid_resp[4]; size_t uid_resp_len; + uint8_t sak = 0x04; // cascade uid int cascade_level = 0; - int len =0; - - // test for the SKYLANDERS TOY. - // ReaderTransmit(deselect,sizeof(deselect), NULL); - // len = ReaderReceive(resp, resp_par); - + int len; + // Broadcast for a card, WUPA (0x52) will force response from all cards in the field - ReaderTransmitBitsPar(wupa,7,0, NULL); + ReaderTransmitBitsPar(wupa,7,0, NULL); // Receive the ATQA if(!ReaderReceive(resp, resp_par)) return 0; - + if(p_hi14a_card) { memcpy(p_hi14a_card->atqa, resp, 2); p_hi14a_card->uidlen = 0; @@ -1759,103 +1752,99 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u memset(uid_ptr,0,10); } - // OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in - // which case we need to make a cascade 2 request and select - this is a long UID - // While the UID is not complete, the 3nd bit (from the right) is set in the SAK. - for(; sak & 0x04; cascade_level++) { - // SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97) - sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2; + // OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in + // which case we need to make a cascade 2 request and select - this is a long UID + // While the UID is not complete, the 3nd bit (from the right) is set in the SAK. + for(; sak & 0x04; cascade_level++) { + // SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97) + sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2; - // SELECT_ALL - ReaderTransmit(sel_all,sizeof(sel_all), NULL); - if (!ReaderReceive(resp, resp_par)) return 0; + // SELECT_ALL + ReaderTransmit(sel_all, sizeof(sel_all), NULL); + if (!ReaderReceive(resp, resp_par)) return 0; - if (Demod.collisionPos) { // we had a collision and need to construct the UID bit by bit - memset(uid_resp, 0, 4); - uint16_t uid_resp_bits = 0; - uint16_t collision_answer_offset = 0; - // anti-collision-loop: - while (Demod.collisionPos) { - Dbprintf("Multiple tags detected. Collision after Bit %d", Demod.collisionPos); - for (uint16_t i = collision_answer_offset; i < Demod.collisionPos; i++, uid_resp_bits++) { // add valid UID bits before collision point - uint16_t UIDbit = (resp[i/8] >> (i % 8)) & 0x01; - uid_resp[uid_resp_bits & 0xf8] |= UIDbit << (uid_resp_bits % 8); + if (Demod.collisionPos) { // we had a collision and need to construct the UID bit by bit + memset(uid_resp, 0, 4); + uint16_t uid_resp_bits = 0; + uint16_t collision_answer_offset = 0; + // anti-collision-loop: + while (Demod.collisionPos) { + Dbprintf("Multiple tags detected. Collision after Bit %d", Demod.collisionPos); + for (uint16_t i = collision_answer_offset; i < Demod.collisionPos; i++, uid_resp_bits++) { // add valid UID bits before collision point + uint16_t UIDbit = (resp[i/8] >> (i % 8)) & 0x01; + uid_resp[uid_resp_bits & 0xf8] |= UIDbit << (uid_resp_bits % 8); + } + uid_resp[uid_resp_bits/8] |= 1 << (uid_resp_bits % 8); // next time select the card(s) with a 1 in the collision position + uid_resp_bits++; + // construct anticollosion command: + sel_uid[1] = ((2 + uid_resp_bits/8) << 4) | (uid_resp_bits & 0x07); // length of data in bytes and bits + for (uint16_t i = 0; i <= uid_resp_bits/8; i++) { + sel_uid[2+i] = uid_resp[i]; + } + collision_answer_offset = uid_resp_bits%8; + ReaderTransmitBits(sel_uid, 16 + uid_resp_bits, NULL); + if (!ReaderReceiveOffset(resp, collision_answer_offset, resp_par)) return 0; } - uid_resp[uid_resp_bits/8] |= 1 << (uid_resp_bits % 8); // next time select the card(s) with a 1 in the collision position - uid_resp_bits++; - // construct anticollosion command: - sel_uid[1] = ((2 + uid_resp_bits/8) << 4) | (uid_resp_bits & 0x07); // length of data in bytes and bits - for (uint16_t i = 0; i <= uid_resp_bits/8; i++) { - sel_uid[2+i] = uid_resp[i]; + // finally, add the last bits and BCC of the UID + for (uint16_t i = collision_answer_offset; i < (Demod.len-1)*8; i++, uid_resp_bits++) { + uint16_t UIDbit = (resp[i/8] >> (i%8)) & 0x01; + uid_resp[uid_resp_bits/8] |= UIDbit << (uid_resp_bits % 8); } - collision_answer_offset = uid_resp_bits%8; - ReaderTransmitBits(sel_uid, 16 + uid_resp_bits, NULL); - if (!ReaderReceiveOffset(resp, collision_answer_offset,resp_par)) return 0; + + } else { // no collision, use the response to SELECT_ALL as current uid + memcpy(uid_resp, resp, 4); } - // finally, add the last bits and BCC of the UID - for (uint16_t i = collision_answer_offset; i < (Demod.len-1)*8; i++, uid_resp_bits++) { - uint16_t UIDbit = (resp[i/8] >> (i%8)) & 0x01; - uid_resp[uid_resp_bits/8] |= UIDbit << (uid_resp_bits % 8); + uid_resp_len = 4; + + // calculate crypto UID. Always use last 4 Bytes. + if(cuid_ptr) { + *cuid_ptr = bytes_to_num(uid_resp, 4); } - } else { // no collision, use the response to SELECT_ALL as current uid - memcpy(uid_resp,resp,4); + // Construct SELECT UID command + sel_uid[1] = 0x70; // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC) + memcpy(sel_uid+2, uid_resp, 4); // the UID + sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate and add BCC + AppendCrc14443a(sel_uid, 7); // calculate and add CRC + ReaderTransmit(sel_uid, sizeof(sel_uid), NULL); + + // Receive the SAK + if (!ReaderReceive(resp, resp_par)) return 0; + sak = resp[0]; + + // Test if more parts of the uid are comming + if ((sak & 0x04) /* && uid_resp[0] == 0x88 */) { + // Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of: + // http://www.nxp.com/documents/application_note/AN10927.pdf + uid_resp[0] = uid_resp[1]; + uid_resp[1] = uid_resp[2]; + uid_resp[2] = uid_resp[3]; + + uid_resp_len = 3; + } + + if(uid_ptr) { + memcpy(uid_ptr + (cascade_level*3), uid_resp, uid_resp_len); + } + + if(p_hi14a_card) { + memcpy(p_hi14a_card->uid + (cascade_level*3), uid_resp, uid_resp_len); + p_hi14a_card->uidlen += uid_resp_len; + } } - uid_resp_len = 4; - // calculate crypto UID. Always use last 4 Bytes. - if(cuid_ptr) { - *cuid_ptr = bytes_to_num(uid_resp, 4); - } - - // Construct SELECT UID command - sel_uid[1] = 0x70; // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC) - memcpy(sel_uid+2,uid_resp,4); // the UID - sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate and add BCC - AppendCrc14443a(sel_uid,7); // calculate and add CRC - ReaderTransmit(sel_uid,sizeof(sel_uid), NULL); - - // Receive the SAK - if (!ReaderReceive(resp, resp_par)){ - return 0; + if(p_hi14a_card) { + p_hi14a_card->sak = sak; + p_hi14a_card->ats_len = 0; } - - - sak = resp[0]; - - // Test if more parts of the uid are coming - if ((sak & 0x04) /* && uid_resp[0] == 0x88 */) { - // Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of: - // http://www.nxp.com/documents/application_note/AN10927.pdf - uid_resp[0] = uid_resp[1]; - uid_resp[1] = uid_resp[2]; - uid_resp[2] = uid_resp[3]; - - uid_resp_len = 3; - } - - if(uid_ptr) { - memcpy(uid_ptr + (cascade_level*3), uid_resp, uid_resp_len); - } - - if(p_hi14a_card) { - memcpy(p_hi14a_card->uid + (cascade_level*3), uid_resp, uid_resp_len); - p_hi14a_card->uidlen += uid_resp_len; - } - } - - if(p_hi14a_card) { - p_hi14a_card->sak = sak; - p_hi14a_card->ats_len = 0; - } // non iso14443a compliant tag if( (sak & 0x20) == 0) return 2; - + // Request for answer to select AppendCrc14443a(rats, 2); ReaderTransmit(rats, sizeof(rats), NULL); - + if (!(len = ReaderReceive(resp, resp_par))) return 0; @@ -1866,7 +1855,7 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u // reset the PCB block number iso14_pcb_blocknum = 0; - return 1; + return 1; } void iso14443a_setup(uint8_t fpga_minor_mode) { @@ -1877,7 +1866,8 @@ void iso14443a_setup(uint8_t fpga_minor_mode) { SetAdcMuxFor(GPIO_MUXSEL_HIPKD); // Signal field is on with the appropriate LED - if (fpga_minor_mode == FPGA_HF_ISO14443A_READER_MOD || fpga_minor_mode == FPGA_HF_ISO14443A_READER_LISTEN) { + if (fpga_minor_mode == FPGA_HF_ISO14443A_READER_MOD + || fpga_minor_mode == FPGA_HF_ISO14443A_READER_LISTEN) { LED_D_ON(); } else { LED_D_OFF(); @@ -1890,7 +1880,7 @@ void iso14443a_setup(uint8_t fpga_minor_mode) { DemodReset(); UartReset(); NextTransferTime = 2*DELAY_ARM2AIR_AS_READER; - iso14a_set_timeout(1050); // 10ms default 10*105 = + iso14a_set_timeout(1050); // 10ms default } int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) { @@ -1905,7 +1895,7 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) { ReaderTransmit(real_cmd, cmd_len+4, NULL); size_t len = ReaderReceive(data, parity); - uint8_t * data_bytes = (uint8_t *) data; + uint8_t *data_bytes = (uint8_t *) data; if (!len) return 0; //DATA LINK ERROR // if we received an I- or R(ACK)-Block with a block number equal to the @@ -1969,8 +1959,8 @@ void ReaderIso14443a(UsbCommand *c) len += 2; if (lenbits) lenbits += 16; } - if(lenbits>0) { - GetParity(cmd, lenbits/8, par); + if(lenbits>0) { + GetParity(cmd, lenbits/8, par); ReaderTransmitBitsPar(cmd, lenbits, par, NULL); } else { ReaderTransmit(cmd,len, NULL); @@ -2168,7 +2158,7 @@ void ReaderMifare(bool first_try) led_on = !led_on; if(led_on) LED_B_ON(); else LED_B_OFF(); - par_list[nt_diff] = SwapBits(par[0], 8); + par_list[nt_diff] = SwapBits(par[0], 8); ks_list[nt_diff] = receivedAnswer[0] ^ 0x05; // Test if the information is complete @@ -2736,7 +2726,7 @@ void RAMFUNC SniffMifare(uint8_t param) { // The response (tag -> reader) that we're receiving. uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET); uint8_t *receivedResponsePar = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET; - + // As we receive stuff, we copy it from receivedCmd or receivedResponse // into trace, along with its length and other annotations. //uint8_t *trace = (uint8_t *)BigBuf; diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 15e2a2f0..c595d5e1 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -12,7 +12,7 @@ #ifndef __ISO14443A_H #define __ISO14443A_H -#include "../include/common.h" +#include "common.h" #include "mifaresniff.h" typedef struct { @@ -28,8 +28,8 @@ typedef struct { uint16_t bitCount; uint16_t collisionPos; uint16_t syncBit; - uint8_t parityBits; - uint8_t parityLen; + uint8_t parityBits; + uint8_t parityLen; uint16_t shiftReg; uint16_t samples; uint16_t len; @@ -61,8 +61,8 @@ typedef struct { uint16_t byteCntMax; uint16_t posCnt; uint16_t syncBit; - uint8_t parityBits; - uint8_t parityLen; + uint8_t parityBits; + uint8_t parityLen; uint16_t highCnt; uint16_t twoBits; uint32_t startTime, endTime; diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index c4f5f612..ec8120b9 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -58,14 +58,12 @@ // *) document all the functions -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "util.h" #include "apps.h" #include "string.h" -#include "../common/iso15693tools.h" -#include "../common/cmd.h" -#include "crapto1.h" -#include "mifareutil.h" +#include "iso15693tools.h" +#include "cmd.h" #define arraylen(x) (sizeof(x)/sizeof((x)[0])) @@ -453,7 +451,7 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int int8_t prev = 0; - // NOW READ RESPONSE +// NOW READ RESPONSE FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); //spindelay(60); // greg - experiment to get rid of some of the 0 byte/failed reads c = 0; @@ -469,9 +467,21 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int // tone that the tag AM-modulates, so every other sample is I, // every other is Q. We just want power, so abs(I) + abs(Q) is // close to what we want. - if (getNext) { + if(getNext) { + int8_t r; - dest[c++] = abs(b) + abs(prev); + if(b < 0) { + r = -b; + } else { + r = b; + } + if(prev < 0) { + r -= prev; + } else { + r += prev; + } + + dest[c++] = (uint8_t)r; if(c >= 20000) { break; @@ -679,8 +689,8 @@ void RecordRawAdcSamplesIso15693(void) FpgaSetupSsc(); // Start from off (no field generated) - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(200); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(200); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); @@ -982,7 +992,7 @@ void SetDebugIso15693(uint32_t debug) { // Simulate an ISO15693 reader, perform anti-collision and then attempt to read a sector // all demodulation performed in arm rather than host. - greg //----------------------------------------------------------------------------- -void ReaderIso15693(uint32_t parameter ) +void ReaderIso15693(uint32_t parameter) { LED_A_ON(); LED_B_ON(); @@ -1003,7 +1013,7 @@ void ReaderIso15693(uint32_t parameter ) int elapsed = 0; uint8_t TagUID[8] = {0x00}; - + // Blank arrays memset(BigBuf + 3660, 0x00, 300); @@ -1014,9 +1024,9 @@ void ReaderIso15693(uint32_t parameter ) FpgaSetupSsc(); // Start from off (no field generated) - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(200); - + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(200); + // Give the tags time to energize FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); SpinDelay(200); @@ -1055,7 +1065,7 @@ void ReaderIso15693(uint32_t parameter ) Dbhexdump(answerLen1,answer1,true); // UID is reverse - if (answerLen1 >= 12) + if (answerLen1>=12) Dbprintf("UID = %02hX%02hX%02hX%02hX%02hX%02hX%02hX%02hX", TagUID[7],TagUID[6],TagUID[5],TagUID[4], TagUID[3],TagUID[2],TagUID[1],TagUID[0]); @@ -1069,14 +1079,14 @@ void ReaderIso15693(uint32_t parameter ) DbdecodeIso15693Answer(answerLen3,answer3); Dbhexdump(answerLen3,answer3,true); - // read all pages - if (answerLen1 >= 12 && DEBUG) { + // read all pages + if (answerLen1>=12 && DEBUG) { i=0; - while (i < 32) { // sanity check, assume max 32 pages + while (i<32) { // sanity check, assume max 32 pages BuildReadBlockRequest(TagUID,i); - TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait); - answerLen2 = GetIso15693AnswerFromTag(answer2, 100, &samples, &elapsed); - if (answerLen2 > 0) { + TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait); + answerLen2 = GetIso15693AnswerFromTag(answer2, 100, &samples, &elapsed); + if (answerLen2>0) { Dbprintf("READ SINGLE BLOCK %d returned %d octets:",i,answerLen2); DbdecodeIso15693Answer(answerLen2,answer2); Dbhexdump(answerLen2,answer2,true); @@ -1108,9 +1118,9 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid) int tsamples = 0; int wait = 0; int elapsed = 0; - + memset(buf, 0x00, 100); - + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); @@ -1118,8 +1128,8 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid) FpgaSetupSsc(); // Start from off (no field generated) - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(200); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(200); LED_A_OFF(); LED_B_OFF(); @@ -1136,7 +1146,7 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid) BuildInventoryResponse(uid); - TransmitTo15693Reader(ToSend, ToSendMax, &tsamples, &wait); + TransmitTo15693Reader(ToSend,ToSendMax, &tsamples, &wait); } Dbprintf("%d octets read from reader command: %x %x %x %x %x %x %x %x %x", answerLen1, diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 0e63ef5e..3fbdf5cb 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -8,14 +8,14 @@ // LEGIC RF simulation code //----------------------------------------------------------------------------- -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" #include "util.h" #include "string.h" #include "legicrf.h" -#include "../include/legic_prng.h" -#include "../common/crc.h" +#include "legic_prng.h" +#include "crc.h" static struct legic_frame { int bits; diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 08bae44d..edddb1c6 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -8,136 +8,154 @@ // Also routines for raw mode reading/simulating of LF waveform //----------------------------------------------------------------------------- -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" #include "util.h" -#include "../common/crc16.h" -#include "../common/lfdemod.h" +#include "hitag2.h" +#include "crc16.h" #include "string.h" -#include "crapto1.h" -#include "mifareutil.h" -#include "../include/hitag2.h" +#include "lfdemod.h" -// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK) -// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz -// Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier) -// T0 = TIMER_CLOCK1 / 125000 = 192 -#define T0 192 -#define SHORT_COIL() LOW(GPIO_SSC_DOUT) -#define OPEN_COIL() HIGH(GPIO_SSC_DOUT) +/** +* Does the sample acquisition. If threshold is specified, the actual sampling +* is not commenced until the threshold has been reached. +* @param trigger_threshold - the threshold +* @param silent - is true, now outputs are made. If false, dbprints the status +*/ +void DoAcquisition125k_internal(int trigger_threshold,bool silent) +{ + uint8_t *dest = (uint8_t *)BigBuf; + int n = sizeof(BigBuf); + int i; + memset(dest, 0, n); + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + LED_D_ON(); + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + LED_D_OFF(); + if (trigger_threshold != -1 && dest[i] < trigger_threshold) + continue; + else + trigger_threshold = -1; + if (++i >= n) break; + } + } + if(!silent) + { + Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", + dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); + + } +} +/** +* Perform sample aquisition. +*/ +void DoAcquisition125k(int trigger_threshold) +{ + DoAcquisition125k_internal(trigger_threshold, false); +} + +/** +* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream +* if not already loaded, sets divisor and starts up the antenna. +* @param divisor : 1, 88> 255 or negative ==> 134.8 KHz +* 0 or 95 ==> 125 KHz +* +**/ void LFSetupFPGAForADC(int divisor, bool lf_field) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - else if (divisor == 0) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - else - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + else if (divisor == 0) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + else + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(150); - - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(50); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); } - +/** +* Initializes the FPGA, and acquires the samples. +**/ void AcquireRawAdcSamples125k(int divisor) { - LFSetupFPGAForADC(divisor, true); - DoAcquisition125k(); + LFSetupFPGAForADC(divisor, true); + // Now call the acquisition routine + DoAcquisition125k_internal(-1,false); } +/** +* Initializes the FPGA for snoop-mode, and acquires the samples. +**/ void SnoopLFRawAdcSamples(int divisor, int trigger_threshold) { - LFSetupFPGAForADC(divisor, false); - DoAcquisition125k_threshold(trigger_threshold); + LFSetupFPGAForADC(divisor, false); + DoAcquisition125k(trigger_threshold); } -// split into two routines so we can avoid timing issues after sending commands // -void DoAcquisition125k_internal(int trigger_threshold, bool silent) -{ - uint8_t *dest = (uint8_t *)BigBuf; - uint16_t i = 0; - memset(dest, 0x00, BIGBUF_SIZE); - - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - LED_D_OFF(); - if (trigger_threshold != -1 && dest[i] < trigger_threshold) - continue; - else - trigger_threshold = -1; - if (++i >= BIGBUF_SIZE) break; - } - } - if (!silent){ - Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", - dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); - } -} -void DoAcquisition125k_threshold(int trigger_threshold) { - DoAcquisition125k_internal(trigger_threshold, true); -} -void DoAcquisition125k() { - DoAcquisition125k_internal(-1, true); -} - void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - - /* Make sure the tag is reset */ - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(2500); - int divisor = 95; // 125 KHz - // see if 'h' was specified - if (command[strlen((char *) command) - 1] == 'h') - divisor = 88; // 134.8 KHz + /* Make sure the tag is reset */ + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(2500); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(2000); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + int divisor_used = 95; // 125 KHz + // see if 'h' was specified - // now modulate the reader field - while(*command != '\0' && *command != ' ') { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); + if (command[strlen((char *) command) - 1] == 'h') + divisor_used = 88; // 134.8 KHz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - LED_D_ON(); - if(*(command++) == '0') - SpinDelayUs(period_0); - else - SpinDelayUs(period_1); - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // now do the read - DoAcquisition125k(-1); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(50); + + // And a little more time for the tag to fully power up + SpinDelay(2000); + + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + // now modulate the reader field + while(*command != '\0' && *command != ' ') { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + SpinDelayUs(delay_off); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + LED_D_ON(); + if(*(command++) == '0') + SpinDelayUs(period_0); + else + SpinDelayUs(period_1); + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + SpinDelayUs(delay_off); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // now do the read + DoAcquisition125k(-1); } /* blank r/w tag data stream @@ -151,228 +169,228 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, */ void ReadTItag(void) { - // some hardcoded initial params - // when we read a TI tag we sample the zerocross line at 2Mhz - // TI tags modulate a 1 as 16 cycles of 123.2Khz - // TI tags modulate a 0 as 16 cycles of 134.2Khz - #define FSAMPLE 2000000 - #define FREQLO 123200 - #define FREQHI 134200 + // some hardcoded initial params + // when we read a TI tag we sample the zerocross line at 2Mhz + // TI tags modulate a 1 as 16 cycles of 123.2Khz + // TI tags modulate a 0 as 16 cycles of 134.2Khz +#define FSAMPLE 2000000 +#define FREQLO 123200 +#define FREQHI 134200 - signed char *dest = (signed char *)BigBuf; - int n = sizeof(BigBuf); + signed char *dest = (signed char *)BigBuf; + int n = sizeof(BigBuf); - // 128 bit shift register [shift3:shift2:shift1:shift0] - uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; + // 128 bit shift register [shift3:shift2:shift1:shift0] + uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; - int i, cycles=0, samples=0; - // how many sample points fit in 16 cycles of each frequency - uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; - // when to tell if we're close enough to one freq or another - uint32_t threshold = (sampleslo - sampleshi + 1)>>1; + int i, cycles=0, samples=0; + // how many sample points fit in 16 cycles of each frequency + uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; + // when to tell if we're close enough to one freq or another + uint32_t threshold = (sampleslo - sampleshi + 1)>>1; - // TI tags charge at 134.2Khz - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + // TI tags charge at 134.2Khz + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - // Place FPGA in passthrough mode, in this mode the CROSS_LO line - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - // get TI tag data into the buffer - AcquireTiType(); + // get TI tag data into the buffer + AcquireTiType(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - for (i=0; i0) ) { - cycles++; - // after 16 cycles, measure the frequency - if (cycles>15) { - cycles=0; - samples=i-samples; // number of samples in these 16 cycles + for (i=0; i0) ) { + cycles++; + // after 16 cycles, measure the frequency + if (cycles>15) { + cycles=0; + samples=i-samples; // number of samples in these 16 cycles - // TI bits are coming to us lsb first so shift them - // right through our 128 bit right shift register - shift0 = (shift0>>1) | (shift1 << 31); - shift1 = (shift1>>1) | (shift2 << 31); - shift2 = (shift2>>1) | (shift3 << 31); - shift3 >>= 1; + // TI bits are coming to us lsb first so shift them + // right through our 128 bit right shift register + shift0 = (shift0>>1) | (shift1 << 31); + shift1 = (shift1>>1) | (shift2 << 31); + shift2 = (shift2>>1) | (shift3 << 31); + shift3 >>= 1; - // check if the cycles fall close to the number - // expected for either the low or high frequency - if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { - // low frequency represents a 1 - shift3 |= (1<<31); - } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { - // high frequency represents a 0 - } else { - // probably detected a gay waveform or noise - // use this as gaydar or discard shift register and start again - shift3 = shift2 = shift1 = shift0 = 0; - } - samples = i; + // check if the cycles fall close to the number + // expected for either the low or high frequency + if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { + // low frequency represents a 1 + shift3 |= (1<<31); + } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { + // high frequency represents a 0 + } else { + // probably detected a gay waveform or noise + // use this as gaydar or discard shift register and start again + shift3 = shift2 = shift1 = shift0 = 0; + } + samples = i; - // for each bit we receive, test if we've detected a valid tag + // for each bit we receive, test if we've detected a valid tag - // if we see 17 zeroes followed by 6 ones, we might have a tag - // remember the bits are backwards - if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { - // if start and end bytes match, we have a tag so break out of the loop - if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { - cycles = 0xF0B; //use this as a flag (ugly but whatever) - break; - } - } - } - } - } + // if we see 17 zeroes followed by 6 ones, we might have a tag + // remember the bits are backwards + if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { + // if start and end bytes match, we have a tag so break out of the loop + if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { + cycles = 0xF0B; //use this as a flag (ugly but whatever) + break; + } + } + } + } + } - // if flag is set we have a tag - if (cycles!=0xF0B) { - DbpString("Info: No valid tag detected."); - } else { - // put 64 bit data into shift1 and shift0 - shift0 = (shift0>>24) | (shift1 << 8); - shift1 = (shift1>>24) | (shift2 << 8); + // if flag is set we have a tag + if (cycles!=0xF0B) { + DbpString("Info: No valid tag detected."); + } else { + // put 64 bit data into shift1 and shift0 + shift0 = (shift0>>24) | (shift1 << 8); + shift1 = (shift1>>24) | (shift2 << 8); - // align 16 bit crc into lower half of shift2 - shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; + // align 16 bit crc into lower half of shift2 + shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; - // if r/w tag, check ident match - if ( shift3&(1<<15) ) { - DbpString("Info: TI tag is rewriteable"); - // only 15 bits compare, last bit of ident is not valid - if ( ((shift3>>16)^shift0)&0x7fff ) { - DbpString("Error: Ident mismatch!"); - } else { - DbpString("Info: TI tag ident is valid"); - } - } else { - DbpString("Info: TI tag is readonly"); - } + // if r/w tag, check ident match + if ( shift3&(1<<15) ) { + DbpString("Info: TI tag is rewriteable"); + // only 15 bits compare, last bit of ident is not valid + if ( ((shift3>>16)^shift0)&0x7fff ) { + DbpString("Error: Ident mismatch!"); + } else { + DbpString("Info: TI tag ident is valid"); + } + } else { + DbpString("Info: TI tag is readonly"); + } - // WARNING the order of the bytes in which we calc crc below needs checking - // i'm 99% sure the crc algorithm is correct, but it may need to eat the - // bytes in reverse or something - // calculate CRC - uint32_t crc=0; + // WARNING the order of the bytes in which we calc crc below needs checking + // i'm 99% sure the crc algorithm is correct, but it may need to eat the + // bytes in reverse or something + // calculate CRC + uint32_t crc=0; - crc = update_crc16(crc, (shift0)&0xff); - crc = update_crc16(crc, (shift0>>8)&0xff); - crc = update_crc16(crc, (shift0>>16)&0xff); - crc = update_crc16(crc, (shift0>>24)&0xff); - crc = update_crc16(crc, (shift1)&0xff); - crc = update_crc16(crc, (shift1>>8)&0xff); - crc = update_crc16(crc, (shift1>>16)&0xff); - crc = update_crc16(crc, (shift1>>24)&0xff); + crc = update_crc16(crc, (shift0)&0xff); + crc = update_crc16(crc, (shift0>>8)&0xff); + crc = update_crc16(crc, (shift0>>16)&0xff); + crc = update_crc16(crc, (shift0>>24)&0xff); + crc = update_crc16(crc, (shift1)&0xff); + crc = update_crc16(crc, (shift1>>8)&0xff); + crc = update_crc16(crc, (shift1>>16)&0xff); + crc = update_crc16(crc, (shift1>>24)&0xff); - Dbprintf("Info: Tag data: %x%08x, crc=%x", - (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); - if (crc != (shift2&0xffff)) { - Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); - } else { - DbpString("Info: CRC is good"); - } - } + Dbprintf("Info: Tag data: %x%08x, crc=%x", + (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); + if (crc != (shift2&0xffff)) { + Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); + } else { + DbpString("Info: CRC is good"); + } + } } void WriteTIbyte(uint8_t b) { - int i = 0; + int i = 0; - // modulate 8 bits out to the antenna - for (i=0; i<8; i++) - { - if (b&(1<PIO_PDR = GPIO_SSC_DIN; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; + // Set up the synchronous serial port + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; - // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long - // 48/2 = 24 MHz clock must be divided by 12 - AT91C_BASE_SSC->SSC_CMR = 12; + // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long + // 48/2 = 24 MHz clock must be divided by 12 + AT91C_BASE_SSC->SSC_CMR = 12; - AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; - AT91C_BASE_SSC->SSC_TCMR = 0; - AT91C_BASE_SSC->SSC_TFMR = 0; + AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; + AT91C_BASE_SSC->SSC_TCMR = 0; + AT91C_BASE_SSC->SSC_TFMR = 0; - LED_D_ON(); + LED_D_ON(); - // modulate antenna - HIGH(GPIO_SSC_DOUT); + // modulate antenna + HIGH(GPIO_SSC_DOUT); - // Charge TI tag for 50ms. - SpinDelay(50); + // Charge TI tag for 50ms. + SpinDelay(50); - // stop modulating antenna and listen - LOW(GPIO_SSC_DOUT); + // stop modulating antenna and listen + LOW(GPIO_SSC_DOUT); - LED_D_OFF(); + LED_D_OFF(); - i = 0; - for(;;) { - if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer - i++; if(i >= TIBUFLEN) break; - } - WDT_HIT(); - } + i = 0; + for(;;) { + if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer + i++; if(i >= TIBUFLEN) break; + } + WDT_HIT(); + } - // return stolen pin to SSP - AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; + // return stolen pin to SSP + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; - char *dest = (char *)BigBuf; - n = TIBUFLEN*32; - // unpack buffer - for (i=TIBUFLEN-1; i>=0; i--) { - for (j=0; j<32; j++) { - if(BigBuf[i] & (1 << j)) { - dest[--n] = 1; - } else { - dest[--n] = -1; - } - } - } + char *dest = (char *)BigBuf; + n = TIBUFLEN*32; + // unpack buffer + for (i=TIBUFLEN-1; i>=0; i--) { + for (j=0; j<32; j++) { + if(BigBuf[i] & (1 << j)) { + dest[--n] = 1; + } else { + dest[--n] = -1; + } + } + } } // arguments: 64bit data split into 32bit idhi:idlo and optional 16bit crc @@ -380,233 +398,127 @@ void AcquireTiType(void) // if not provided a valid crc will be computed from the data and written. void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - if(crc == 0) { - crc = update_crc16(crc, (idlo)&0xff); - crc = update_crc16(crc, (idlo>>8)&0xff); - crc = update_crc16(crc, (idlo>>16)&0xff); - crc = update_crc16(crc, (idlo>>24)&0xff); - crc = update_crc16(crc, (idhi)&0xff); - crc = update_crc16(crc, (idhi>>8)&0xff); - crc = update_crc16(crc, (idhi>>16)&0xff); - crc = update_crc16(crc, (idhi>>24)&0xff); - } - Dbprintf("Writing to tag: %x%08x, crc=%x", - (unsigned int) idhi, (unsigned int) idlo, crc); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if(crc == 0) { + crc = update_crc16(crc, (idlo)&0xff); + crc = update_crc16(crc, (idlo>>8)&0xff); + crc = update_crc16(crc, (idlo>>16)&0xff); + crc = update_crc16(crc, (idlo>>24)&0xff); + crc = update_crc16(crc, (idhi)&0xff); + crc = update_crc16(crc, (idhi>>8)&0xff); + crc = update_crc16(crc, (idhi>>16)&0xff); + crc = update_crc16(crc, (idhi>>24)&0xff); + } + Dbprintf("Writing to tag: %x%08x, crc=%x", + (unsigned int) idhi, (unsigned int) idlo, crc); - // TI tags charge at 134.2Khz - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - // Place FPGA in passthrough mode, in this mode the CROSS_LO line - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - LED_A_ON(); + // TI tags charge at 134.2Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + LED_A_ON(); - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - // writing algorithm: - // a high bit consists of a field off for 1ms and field on for 1ms - // a low bit consists of a field off for 0.3ms and field on for 1.7ms - // initiate a charge time of 50ms (field on) then immediately start writing bits - // start by writing 0xBB (keyword) and 0xEB (password) - // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) - // finally end with 0x0300 (write frame) - // all data is sent lsb firts - // finish with 15ms programming time + // writing algorithm: + // a high bit consists of a field off for 1ms and field on for 1ms + // a low bit consists of a field off for 0.3ms and field on for 1.7ms + // initiate a charge time of 50ms (field on) then immediately start writing bits + // start by writing 0xBB (keyword) and 0xEB (password) + // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) + // finally end with 0x0300 (write frame) + // all data is sent lsb firts + // finish with 15ms programming time - // modulate antenna - HIGH(GPIO_SSC_DOUT); - SpinDelay(50); // charge time + // modulate antenna + HIGH(GPIO_SSC_DOUT); + SpinDelay(50); // charge time - WriteTIbyte(0xbb); // keyword - WriteTIbyte(0xeb); // password - WriteTIbyte( (idlo )&0xff ); - WriteTIbyte( (idlo>>8 )&0xff ); - WriteTIbyte( (idlo>>16)&0xff ); - WriteTIbyte( (idlo>>24)&0xff ); - WriteTIbyte( (idhi )&0xff ); - WriteTIbyte( (idhi>>8 )&0xff ); - WriteTIbyte( (idhi>>16)&0xff ); - WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo - WriteTIbyte( (crc )&0xff ); // crc lo - WriteTIbyte( (crc>>8 )&0xff ); // crc hi - WriteTIbyte(0x00); // write frame lo - WriteTIbyte(0x03); // write frame hi - HIGH(GPIO_SSC_DOUT); - SpinDelay(50); // programming time + WriteTIbyte(0xbb); // keyword + WriteTIbyte(0xeb); // password + WriteTIbyte( (idlo )&0xff ); + WriteTIbyte( (idlo>>8 )&0xff ); + WriteTIbyte( (idlo>>16)&0xff ); + WriteTIbyte( (idlo>>24)&0xff ); + WriteTIbyte( (idhi )&0xff ); + WriteTIbyte( (idhi>>8 )&0xff ); + WriteTIbyte( (idhi>>16)&0xff ); + WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo + WriteTIbyte( (crc )&0xff ); // crc lo + WriteTIbyte( (crc>>8 )&0xff ); // crc hi + WriteTIbyte(0x00); // write frame lo + WriteTIbyte(0x03); // write frame hi + HIGH(GPIO_SSC_DOUT); + SpinDelay(50); // programming time - LED_A_OFF(); + LED_A_OFF(); - // get TI tag data into the buffer - AcquireTiType(); + // get TI tag data into the buffer + AcquireTiType(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Now use tiread to check"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + DbpString("Now use tiread to check"); } - +void SimulateTagLowFrequency(int period, int gap, int ledcontrol) +{ + int i; + uint8_t *tab = (uint8_t *)BigBuf; + + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); + + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; + + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; + +#define SHORT_COIL() LOW(GPIO_SSC_DOUT) +#define OPEN_COIL() HIGH(GPIO_SSC_DOUT) + + i = 0; + for(;;) { + while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { + if(BUTTON_PRESS()) { + DbpString("Stopped"); + return; + } + WDT_HIT(); + } -// PIO_CODR = Clear Output Data Register -// PIO_SODR = Set Output Data Register -//#define LOW(x) AT91C_BASE_PIOA->PIO_CODR = (x) -//#define HIGH(x) AT91C_BASE_PIOA->PIO_SODR = (x) -void SimulateTagLowFrequency( uint16_t period, uint32_t gap, uint8_t ledcontrol) -{ - LED_D_ON(); - - uint16_t i = 0; - uint8_t send = 0; - - //int overflow = 0; - uint8_t *buf = (uint8_t *)BigBuf; - - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - RELAY_OFF(); - - // Configure output pin that is connected to the FPGA (for modulating) - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - - SHORT_COIL(); - - // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); - - // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the reader frames - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); - AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; - - // Disable timer during configuration - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - - // Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, - // external trigger rising edge, load RA on rising edge of TIOA. - AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING; - - // Enable and reset counter - //AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - - while(!BUTTON_PRESS()) { - WDT_HIT(); - - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * 55) { - - // Check if rising edge in modulation is detected - if(AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - //int ra = (AT91C_BASE_TC1->TC_RA/T0) + overflow; - //Dbprintf("Timing value - %d %d", ra, overflow); - //overflow = 0; - - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - send = 1; - - LED_B_ON(); - } - } - - if ( send ) { - // Disable timer 1 with external trigger to avoid triggers during our own modulation - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - - // Wait for HITAG_T_WAIT_1 carrier periods after the last reader bit, - // not that since the clock counts since the rising edge, but T_Wait1 is - // with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low) - // periods. The gap time T_Low varies (4..10). All timer values are in - // terms of T0 units - while(AT91C_BASE_TC0->TC_CV < T0 * 16 ); - - // datat kommer in som 1 bit för varje position i arrayn - for(i = 0; i < period; ++i) { - - // Reset clock for the next bit - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - - if ( buf[i] > 0 ) - HIGH(GPIO_SSC_DOUT); - else - LOW(GPIO_SSC_DOUT); - - while(AT91C_BASE_TC0->TC_CV < T0 * 1 ); - } - // Drop modulation - LOW(GPIO_SSC_DOUT); - - // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - LED_B_OFF(); - } - - send = 0; - - // Save the timer overflow, will be 0 when frame was received - //overflow += (AT91C_BASE_TC1->TC_CV/T0); - - // Reset the timer to restart while-loop that receives frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; - } - - LED_B_OFF(); - LED_D_OFF(); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - - DbpString("Sim Stopped"); -} - - -void SimulateTagLowFrequencyA(int len, int gap) -{ - uint8_t *buf = (uint8_t *)BigBuf; - - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE); // new izsh toggle mode! - - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - SpinDelay(5); - - AT91C_BASE_SSC->SSC_THR = 0x00; - - int i = 0; - while(!BUTTON_PRESS()) { - WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - - if ( buf[i] > 0 ) - AT91C_BASE_SSC->SSC_THR = 0x43; - else - AT91C_BASE_SSC->SSC_THR = 0x00; - - ++i; - LED_A_ON(); - if (i >= len){ - i = 0; - } - } - - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR; - (void)r; - LED_A_OFF(); - } - } - DbpString("lf simulate stopped"); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + if (ledcontrol) + LED_D_ON(); + + if(tab[i]) + OPEN_COIL(); + else + SHORT_COIL(); + + if (ledcontrol) + LED_D_OFF(); + + while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { + if(BUTTON_PRESS()) { + DbpString("Stopped"); + return; + } + WDT_HIT(); + } + + i++; + if(i == period) { + i = 0; + if (gap) { + SHORT_COIL(); + SpinDelayUs(gap); + } + } + } } #define DEBUG_FRAME_CONTENTS 1 @@ -615,319 +527,315 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0) } // compose fc/8 fc/10 waveform -static void fc(int c, uint16_t *n) { - uint8_t *dest = (uint8_t *)BigBuf; - int idx; +static void fc(int c, int *n) { + uint8_t *dest = (uint8_t *)BigBuf; + int idx; - // for when we want an fc8 pattern every 4 logical bits - if(c == 0) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples - if(c == 8) { - for (idx=0; idx<6; idx++) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - } + // for when we want an fc8 pattern every 4 logical bits + if(c==0) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples + if(c==8) { + for (idx=0; idx<6; idx++) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + } - // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples - if(c == 10) { - for (idx = 0; idx < 5; idx++) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - } + // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples + if(c==10) { + for (idx=0; idx<5; idx++) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + } } // prepare a waveform pattern in the buffer based on the ID given then // simulate a HID tag until the button is pressed -void CmdHIDsimTAG(int hi, int lo, uint8_t ledcontrol) +void CmdHIDsimTAG(int hi, int lo, int ledcontrol) { - uint16_t n = 0, i = 0; - /* - HID tag bitstream format - The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits - A 1 bit is represented as 6 fc8 and 5 fc10 patterns - A 0 bit is represented as 5 fc10 and 6 fc8 patterns - A fc8 is inserted before every 4 bits - A special start of frame pattern is used consisting a0b0 where a and b are neither 0 - nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) - */ + int n=0, i=0; + /* + HID tag bitstream format + The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits + A 1 bit is represented as 6 fc8 and 5 fc10 patterns + A 0 bit is represented as 5 fc10 and 6 fc8 patterns + A fc8 is inserted before every 4 bits + A special start of frame pattern is used consisting a0b0 where a and b are neither 0 + nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) + */ - if (hi > 0xFFF) { - DbpString("Tags can only have 44 bits."); - return; - } - fc(0, &n); - // special start of frame marker containing invalid bit sequences - fc(8, &n); fc(8, &n); // invalid - fc(8, &n); fc(10, &n); // logical 0 - fc(10, &n); fc(10, &n); // invalid - fc(8, &n); fc(10, &n); // logical 0 + if (hi>0xFFF) { + DbpString("Tags can only have 44 bits."); + return; + } + fc(0,&n); + // special start of frame marker containing invalid bit sequences + fc(8, &n); fc(8, &n); // invalid + fc(8, &n); fc(10, &n); // logical 0 + fc(10, &n); fc(10, &n); // invalid + fc(8, &n); fc(10, &n); // logical 0 - WDT_HIT(); - // manchester encode bits 43 to 32 - for (i = 11; i >= 0; i--) { - if ((i % 4) == 3) fc(0, &n); - if ((hi >> i) & 1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } + WDT_HIT(); + // manchester encode bits 43 to 32 + for (i=11; i>=0; i--) { + if ((i%4)==3) fc(0,&n); + if ((hi>>i)&1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } - WDT_HIT(); - // manchester encode bits 31 to 0 - for (i = 31; i >= 0; i--) { - if ((i % 4 ) == 3) fc(0, &n); - if ((lo >> i ) & 1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } + WDT_HIT(); + // manchester encode bits 31 to 0 + for (i=31; i>=0; i--) { + if ((i%4)==3) fc(0,&n); + if ((lo>>i)&1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } - if (ledcontrol) - LED_A_ON(); + if (ledcontrol) + LED_A_ON(); - SimulateTagLowFrequency(n, 0, ledcontrol); + SimulateTagLowFrequency(n, 0, ledcontrol); - if (ledcontrol) - LED_A_OFF(); + if (ledcontrol) + LED_A_OFF(); } // loop to get raw HID waveform then FSK demodulate the TAG ID from it void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; - uint32_t hi2 = 0, hi = 0, lo = 0; + uint8_t *dest = (uint8_t *)BigBuf; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(0, true); + size_t size=0; //, found=0; + uint32_t hi2=0, hi=0, lo=0; - while(!BUTTON_PRESS()) { + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + while(!BUTTON_PRESS()) { - DoAcquisition125k_internal(-1,true); + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - // FSK demodulator - int bitLen = HIDdemodFSK(dest,BIGBUF_SIZE,&hi2,&hi,&lo); + DoAcquisition125k_internal(-1,true); + size = sizeof(BigBuf); + if (size < 2000) continue; + // FSK demodulator - WDT_HIT(); + int bitLen = HIDdemodFSK(dest,size,&hi2,&hi,&lo); - if (bitLen > 0 && lo > 0){ + WDT_HIT(); - // final loop, go over previously decoded manchester data and decode into usable tag ID - // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 - - if (hi2 != 0){ - //extra large HID tags - Dbprintf("TAG ID: %x%08x%08x (%d)", - (unsigned int) hi2, - (unsigned int) hi, - (unsigned int) lo, - (unsigned int) (lo >> 1) & 0xFFFF); - - } else { - //standard HID tags <38 bits - uint8_t bitlen = 0; - uint32_t fc = 0; - uint32_t cardnum = 0; - - if ((( hi >> 5 ) & 1) ==1){//if bit 38 is set then < 37 bit format is used - uint32_t lo2 = 0; - lo2 = (((hi & 31) << 12) | (lo >> 20)); //get bits 21-37 to check for format len bit - uint8_t idx3 = 1; - while(lo2 > 1){ //find last bit set to 1 (format len bit) - lo2 = lo2 >> 1; - idx3++; - } - bitlen =idx3 + 19; - fc = 0; - cardnum = 0; - if(bitlen == 26){ - cardnum = (lo >> 1) & 0xFFFF; - fc = (lo >> 17) & 0xFF; - } - if(bitlen == 37){ - cardnum = (lo >> 1) & 0x7FFFF; - fc = ((hi & 0xF) << 12)|( lo >> 20); - } - if(bitlen == 34){ - cardnum = (lo >> 1) & 0xFFFF; - fc = ((hi & 1) << 15) | (lo >> 17); - } - if(bitlen == 35){ - cardnum = (lo >> 1 ) & 0xFFFFF; - fc = ((hi & 1) << 11 ) | ( lo >> 21); - } - } - else { //if bit 38 is not set then 37 bit format is used - bitlen = 37; - fc = 0; - cardnum = 0; - if(bitlen == 37){ - cardnum = ( lo >> 1) & 0x7FFFF; - fc = ((hi & 0xF) << 12 ) |(lo >> 20); - } - } - Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", - (unsigned int) hi, - (unsigned int) lo, - (unsigned int) (lo >> 1) & 0xFFFF, - (unsigned int) bitlen, - (unsigned int) fc, - (unsigned int) cardnum); - } - if (findone){ - if (ledcontrol) LED_A_OFF(); - return; - } - // reset - hi2 = hi = lo = 0; - } - WDT_HIT(); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + if (bitLen>0 && lo>0){ + // final loop, go over previously decoded manchester data and decode into usable tag ID + // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 + if (hi2 != 0){ //extra large HID tags + Dbprintf("TAG ID: %x%08x%08x (%d)", + (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + }else { //standard HID tags <38 bits + //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd + uint8_t bitlen = 0; + uint32_t fc = 0; + uint32_t cardnum = 0; + if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used + uint32_t lo2=0; + lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit + uint8_t idx3 = 1; + while(lo2>1){ //find last bit set to 1 (format len bit) + lo2=lo2>>1; + idx3++; + } + bitlen =idx3+19; + fc =0; + cardnum=0; + if(bitlen==26){ + cardnum = (lo>>1)&0xFFFF; + fc = (lo>>17)&0xFF; + } + if(bitlen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + if(bitlen==34){ + cardnum = (lo>>1)&0xFFFF; + fc= ((hi&1)<<15)|(lo>>17); + } + if(bitlen==35){ + cardnum = (lo>>1)&0xFFFFF; + fc = ((hi&1)<<11)|(lo>>21); + } + } + else { //if bit 38 is not set then 37 bit format is used + bitlen= 37; + fc =0; + cardnum=0; + if(bitlen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + } + //Dbprintf("TAG ID: %x%08x (%d)", + // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, + (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + return; + } + // reset + hi2 = hi = lo = 0; + } + WDT_HIT(); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; - uint32_t bitLen = 0; - int clk = 0, invert = 0, errCnt = 0; - uint64_t lo = 0; - - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(0, true); + uint8_t *dest = (uint8_t *)BigBuf; - while(!BUTTON_PRESS()) { + size_t size=0; //, found=0; + uint32_t bitLen=0; + int clk=0, invert=0, errCnt=0; + uint64_t lo=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + while(!BUTTON_PRESS()) { - DoAcquisition125k_internal(-1,true); - - // FSK demodulator - bitLen = BIGBUF_SIZE; - errCnt = askmandemod(dest,&bitLen,&clk,&invert); - if ( errCnt < 0 ) continue; + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - WDT_HIT(); - - lo = Em410xDecode(dest,bitLen); - - if ( lo <= 0) continue; - - Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)", - (uint32_t)(lo >> 32), - (uint32_t)lo, - (uint32_t)(lo & 0xFFFF), - (uint32_t)((lo >> 16LL) & 0xFF), - (uint32_t)(lo & 0xFFFFFF) - ); + DoAcquisition125k_internal(-1,true); + size = sizeof(BigBuf); + if (size < 2000) continue; + // FSK demodulator + //int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); + bitLen=size; + //Dbprintf("DEBUG: Buffer got"); + errCnt = askmandemod(dest,&bitLen,&clk,&invert); //HIDdemodFSK(dest,size,&hi2,&hi,&lo); + //Dbprintf("DEBUG: ASK Got"); + WDT_HIT(); - if (findone){ - if (ledcontrol) LED_A_OFF(); - return; - } - - WDT_HIT(); - lo = clk = invert = errCnt = 0; - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + if (errCnt>=0){ + lo = Em410xDecode(dest,bitLen); + //Dbprintf("DEBUG: EM GOT"); + //printEM410x(lo); + if (lo>0){ + Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",(uint32_t)(lo>>32),(uint32_t)lo,(uint32_t)(lo&0xFFFF),(uint32_t)((lo>>16LL) & 0xFF),(uint32_t)(lo & 0xFFFFFF)); + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + return; + } + } else{ + //Dbprintf("DEBUG: No Tag"); + } + WDT_HIT(); + lo = 0; + clk=0; + invert=0; + errCnt=0; + size=0; + //SpinDelay(50); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; - int idx = 0; - uint32_t code = 0, code2 = 0; - uint8_t version = 0; - uint8_t facilitycode = 0; - uint16_t number = 0; + uint8_t *dest = (uint8_t *)BigBuf; + int idx=0; + uint32_t code=0, code2=0; + uint8_t version=0; + uint8_t facilitycode=0; + uint16_t number=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - LFSetupFPGAForADC(0, true); + while(!BUTTON_PRESS()) { + WDT_HIT(); + if (ledcontrol) LED_A_ON(); + DoAcquisition125k_internal(-1,true); + //fskdemod and get start index + WDT_HIT(); + idx = IOdemodFSK(dest,sizeof(BigBuf)); + if (idx>0){ + //valid tag found - while(!BUTTON_PRESS()) { + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- + //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 + // + //XSF(version)facility:codeone+codetwo + //Handle the data + if(findone){ //only print binary if we are doing one + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); + Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); + } + code = bytebits_to_byte(dest+idx,32); + code2 = bytebits_to_byte(dest+idx+32,32); + version = bytebits_to_byte(dest+idx+27,8); //14,4 + facilitycode = bytebits_to_byte(dest+idx+18,8) ; + number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 - WDT_HIT(); - if (ledcontrol) LED_A_ON(); - - DoAcquisition125k_internal(-1, true); - - idx = IOdemodFSK(dest, BIGBUF_SIZE); - - if ( idx < 0 ) - continue; - - WDT_HIT(); - - //Index map - //0 10 20 30 40 50 60 - //| | | | | | | - //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 - //----------------------------------------------------------------------------- - //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 - // - //XSF(version)facility:codeone+codetwo - //Handle the data - - if(findone){ //only print binary if we are doing one - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); - Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); - } - - code = bytebits_to_byte(dest+idx,32); - code2 = bytebits_to_byte(dest+idx+32,32); - version = bytebits_to_byte(dest+idx+27,8); //14,4 - facilitycode = bytebits_to_byte(dest+idx+18,8) ; - number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 - - Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)", version, facilitycode, number, code, code2); - if (findone){ - if (ledcontrol) LED_A_OFF(); - return; - } - code = code2 = 0; - version = facilitycode = 0; - number = 0; - idx = 0; - } - - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); + // if we're only looking for one tag + if (findone){ + if (ledcontrol) LED_A_OFF(); + //LED_A_OFF(); + return; + } + code=code2=0; + version=facilitycode=0; + number=0; + idx=0; + } + WDT_HIT(); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } /*------------------------------ @@ -936,14 +844,14 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) */ /* T55x7 configuration register definitions */ -#define T55x7_POR_DELAY 0x00000001 -#define T55x7_ST_TERMINATOR 0x00000008 -#define T55x7_PWD 0x00000010 +#define T55x7_POR_DELAY 0x00000001 +#define T55x7_ST_TERMINATOR 0x00000008 +#define T55x7_PWD 0x00000010 #define T55x7_MAXBLOCK_SHIFT 5 -#define T55x7_AOR 0x00000200 -#define T55x7_PSKCF_RF_2 0 -#define T55x7_PSKCF_RF_4 0x00000400 -#define T55x7_PSKCF_RF_8 0x00000800 +#define T55x7_AOR 0x00000200 +#define T55x7_PSKCF_RF_2 0 +#define T55x7_PSKCF_RF_4 0x00000400 +#define T55x7_PSKCF_RF_8 0x00000800 #define T55x7_MODULATION_DIRECT 0 #define T55x7_MODULATION_PSK1 0x00001000 #define T55x7_MODULATION_PSK2 0x00002000 @@ -954,17 +862,17 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) #define T55x7_MODULATION_FSK2a 0x00007000 #define T55x7_MODULATION_MANCHESTER 0x00008000 #define T55x7_MODULATION_BIPHASE 0x00010000 -#define T55x7_BITRATE_RF_8 0 -#define T55x7_BITRATE_RF_16 0x00040000 -#define T55x7_BITRATE_RF_32 0x00080000 -#define T55x7_BITRATE_RF_40 0x000C0000 -#define T55x7_BITRATE_RF_50 0x00100000 -#define T55x7_BITRATE_RF_64 0x00140000 +#define T55x7_BITRATE_RF_8 0 +#define T55x7_BITRATE_RF_16 0x00040000 +#define T55x7_BITRATE_RF_32 0x00080000 +#define T55x7_BITRATE_RF_40 0x000C0000 +#define T55x7_BITRATE_RF_50 0x00100000 +#define T55x7_BITRATE_RF_64 0x00140000 #define T55x7_BITRATE_RF_100 0x00180000 #define T55x7_BITRATE_RF_128 0x001C0000 /* T5555 (Q5) configuration register definitions */ -#define T5555_ST_TERMINATOR 0x00000001 +#define T5555_ST_TERMINATOR 0x00000001 #define T5555_MAXBLOCK_SHIFT 0x00000001 #define T5555_MODULATION_MANCHESTER 0 #define T5555_MODULATION_PSK1 0x00000010 @@ -974,321 +882,330 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) #define T5555_MODULATION_FSK2 0x00000050 #define T5555_MODULATION_BIPHASE 0x00000060 #define T5555_MODULATION_DIRECT 0x00000070 -#define T5555_INVERT_OUTPUT 0x00000080 -#define T5555_PSK_RF_2 0 -#define T5555_PSK_RF_4 0x00000100 -#define T5555_PSK_RF_8 0x00000200 -#define T5555_USE_PWD 0x00000400 -#define T5555_USE_AOR 0x00000800 -#define T5555_BITRATE_SHIFT 12 -#define T5555_FAST_WRITE 0x00004000 -#define T5555_PAGE_SELECT 0x00008000 +#define T5555_INVERT_OUTPUT 0x00000080 +#define T5555_PSK_RF_2 0 +#define T5555_PSK_RF_4 0x00000100 +#define T5555_PSK_RF_8 0x00000200 +#define T5555_USE_PWD 0x00000400 +#define T5555_USE_AOR 0x00000800 +#define T5555_BITRATE_SHIFT 12 +#define T5555_FAST_WRITE 0x00004000 +#define T5555_PAGE_SELECT 0x00008000 /* * Relevant times in microsecond * To compensate antenna falling times shorten the write times * and enlarge the gap ones. */ -#define START_GAP 30*8 // 10 - 50fc 250 -#define WRITE_GAP 20*8 // 8 - 30fc -#define WRITE_0 24*8 // 16 - 31fc 24fc 192 -#define WRITE_1 54*8 // 48 - 63fc 54fc 432 for T55x7; 448 for E5550 - -// VALUES TAKEN FROM EM4x function: SendForward -// START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle) -// WRITE_GAP = 128; (16*8) -// WRITE_1 = 256 32*8; (32*8) - -// These timings work for 4469/4269/4305 (with the 55*8 above) -// WRITE_0 = 23*8 , 9*8 SpinDelayUs(23*8); - -#define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..) +#define START_GAP 250 +#define WRITE_GAP 160 +#define WRITE_0 144 // 192 +#define WRITE_1 400 // 432 for T55x7; 448 for E5550 // Write one bit to card void T55xxWriteBit(int bit) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - if (!bit) - SpinDelayUs(WRITE_0); - else - SpinDelayUs(WRITE_1); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(WRITE_GAP); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + if (bit == 0) + SpinDelayUs(WRITE_0); + else + SpinDelayUs(WRITE_1); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(WRITE_GAP); } // Write one card block in page 0, no lock void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - uint32_t i = 0; + //unsigned int i; //enio adjustment 12/10/14 + uint32_t i; - // Set up FPGA, 125kHz - // Wait for config.. (192+8190xPOW)x8 == 67ms - LFSetupFPGAForADC(0, true); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ - // Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Lock bit - T55xxWriteBit(0); + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); - // Data - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Data & i); + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ + // Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } + // Lock bit + T55xxWriteBit(0); - // Block - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); + // Data + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Data & i); - // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, - // so wait a little more) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - SpinDelay(20); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // Block + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); + + // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, + // so wait a little more) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + SpinDelay(20); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); } // Read one card block in page 0 void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - uint8_t *dest = get_bigbufptr_recvrespbuf(); - uint16_t bufferlength = T55xx_SAMPLES_SIZE; - uint32_t i = 0; + uint8_t *dest = (uint8_t *)BigBuf; + //int m=0, i=0; //enio adjustment 12/10/14 + uint32_t m=0, i=0; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); - // Clear destination buffer before sending the command 0x80 = average. - memset(dest, 0x80, bufferlength); + LED_D_ON(); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Set up FPGA, 125kHz - // Wait for config.. (192+8190xPOW)x8 == 67ms - LFSetupFPGAForADC(0, true); + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); + + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); + + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ + // Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } + // Lock bit + T55xxWriteBit(0); + // Block + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); + + // Turn field on to read the response + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + // we don't care about actual value, only if it's more or less than a + // threshold essentially we capture zero crossings for later analysis + // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1; + i++; + if (i >= m) break; + } + } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); - - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ - // Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Lock bit - T55xxWriteBit(0); - // Block - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); - - // Turn field on to read the response - TurnReadLFOn(); - - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - //AT91C_BASE_SSC->SSC_THR = 0xff; - LED_D_ON(); - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - ++i; - LED_D_OFF(); - if (i >= bufferlength) break; - } - } - - cmd_send(CMD_ACK,0,0,0,0,0); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + LED_D_OFF(); + DbpString("DONE!"); } // Read card traceability data (page 1) void T55xxReadTrace(void){ - uint8_t *dest = get_bigbufptr_recvrespbuf(); - uint16_t bufferlength = T55xx_SAMPLES_SIZE; - uint32_t i = 0; - - // Clear destination buffer before sending the command 0x80 = average - memset(dest, 0x80, bufferlength); - - LFSetupFPGAForADC(0, true); - - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); - - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(1); //Page 1 - - // Turn field on to read the response - TurnReadLFOn(); - - // Now do the acquisition - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - ++i; - LED_D_OFF(); - - if (i >= bufferlength) break; - } - } - - cmd_send(CMD_ACK,0,0,0,0,0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); -} + uint8_t *dest = (uint8_t *)BigBuf; + int m=0, i=0; -void TurnReadLFOn(){ - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - //SpinDelay(30); - SpinDelayUs(8*150); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + LED_D_ON(); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); + + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); + + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(1); //Page 1 + + // Turn field on to read the response + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + if (i >= m) break; + } + } + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); + DbpString("DONE!"); } /*-------------- Cloning routines -----------*/ // Copy HID id to card and setup block 0 config void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { - int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format - int last_block = 0; - - if (longFMT){ - // Ensure no more than 84 bits supplied - if (hi2>0xFFFFF) { - DbpString("Tags can only have 84 bits."); - return; - } - // Build the 6 data blocks for supplied 84bit ID - last_block = 6; - data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded) - for (int i=0;i<4;i++) { - if (hi2 & (1<<(19-i))) - data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((3-i)*2)); // 0 -> 01 - } - - data2 = 0; - for (int i=0;i<16;i++) { - if (hi2 & (1<<(15-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 + int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format + int last_block = 0; + + if (longFMT){ + // Ensure no more than 84 bits supplied + if (hi2>0xFFFFF) { + DbpString("Tags can only have 84 bits."); + return; + } + // Build the 6 data blocks for supplied 84bit ID + last_block = 6; + data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded) + for (int i=0;i<4;i++) { + if (hi2 & (1<<(19-i))) + data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10 + else + data1 |= (1<<((3-i)*2)); // 0 -> 01 + } + + data2 = 0; + for (int i=0;i<16;i++) { + if (hi2 & (1<<(15-i))) + data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data2 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data3 = 0; + for (int i=0;i<16;i++) { + if (hi & (1<<(31-i))) + data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data3 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data4 = 0; + for (int i=0;i<16;i++) { + if (hi & (1<<(15-i))) + data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data4 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data5 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(31-i))) + data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data5 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data6 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(15-i))) + data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data6 |= (1<<((15-i)*2)); // 0 -> 01 + } } - - data3 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(31-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data4 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(15-i))) - data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data4 |= (1<<((15-i)*2)); // 0 -> 01 + else { + // Ensure no more than 44 bits supplied + if (hi>0xFFF) { + DbpString("Tags can only have 44 bits."); + return; + } + + // Build the 3 data blocks for supplied 44bit ID + last_block = 3; + + data1 = 0x1D000000; // load preamble + + for (int i=0;i<12;i++) { + if (hi & (1<<(11-i))) + data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10 + else + data1 |= (1<<((11-i)*2)); // 0 -> 01 + } + + data2 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(31-i))) + data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data2 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data3 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(15-i))) + data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data3 |= (1<<((15-i)*2)); // 0 -> 01 + } } - - data5 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data5 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data6 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data6 |= (1<<((15-i)*2)); // 0 -> 01 + + LED_D_ON(); + // Program the data blocks for supplied ID + // and the block 0 for HID format + T55xxWriteBlock(data1,1,0,0); + T55xxWriteBlock(data2,2,0,0); + T55xxWriteBlock(data3,3,0,0); + + if (longFMT) { // if long format there are 6 blocks + T55xxWriteBlock(data4,4,0,0); + T55xxWriteBlock(data5,5,0,0); + T55xxWriteBlock(data6,6,0,0); } - } - else { - // Ensure no more than 44 bits supplied - if (hi>0xFFF) { - DbpString("Tags can only have 44 bits."); - return; - } - - // Build the 3 data blocks for supplied 44bit ID - last_block = 3; - - data1 = 0x1D000000; // load preamble - - for (int i=0;i<12;i++) { - if (hi & (1<<(11-i))) - data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((11-i)*2)); // 0 -> 01 - } - - data2 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data3 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } - } - - LED_D_ON(); - // Program the data blocks for supplied ID - // and the block 0 for HID format - T55xxWriteBlock(data1,1,0,0); - T55xxWriteBlock(data2,2,0,0); - T55xxWriteBlock(data3,3,0,0); - - if (longFMT) { // if long format there are 6 blocks - T55xxWriteBlock(data4,4,0,0); - T55xxWriteBlock(data5,5,0,0); - T55xxWriteBlock(data6,6,0,0); - } - - // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) - T55xxWriteBlock(T55x7_BITRATE_RF_50 | - T55x7_MODULATION_FSK2a | - last_block << T55x7_MAXBLOCK_SHIFT, - 0,0,0); - - LED_D_OFF(); - - DbpString("DONE!"); + + // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) + T55xxWriteBlock(T55x7_BITRATE_RF_50 | + T55x7_MODULATION_FSK2a | + last_block << T55x7_MAXBLOCK_SHIFT, + 0,0,0); + + LED_D_OFF(); + + DbpString("DONE!"); } void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) { - int data1=0, data2=0; //up to six blocks for long format - + int data1=0, data2=0; //up to six blocks for long format + data1 = hi; // load preamble data2 = lo; @@ -1297,11 +1214,11 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) // and the block 0 for HID format T55xxWriteBlock(data1,1,0,0); T55xxWriteBlock(data2,2,0,0); - + //Config Block T55xxWriteBlock(0x00147040,0,0,0); LED_D_OFF(); - + DbpString("DONE!"); } @@ -1311,148 +1228,148 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) { - int i, id_bit; - uint64_t id = EM410X_HEADER; - uint64_t rev_id = 0; // reversed ID - int c_parity[4]; // column parity - int r_parity = 0; // row parity - uint32_t clock = 0; + int i, id_bit; + uint64_t id = EM410X_HEADER; + uint64_t rev_id = 0; // reversed ID + int c_parity[4]; // column parity + int r_parity = 0; // row parity + uint32_t clock = 0; - // Reverse ID bits given as parameter (for simpler operations) - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - if (i < 32) { - rev_id = (rev_id << 1) | (id_lo & 1); - id_lo >>= 1; - } else { - rev_id = (rev_id << 1) | (id_hi & 1); - id_hi >>= 1; - } - } + // Reverse ID bits given as parameter (for simpler operations) + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + if (i < 32) { + rev_id = (rev_id << 1) | (id_lo & 1); + id_lo >>= 1; + } else { + rev_id = (rev_id << 1) | (id_hi & 1); + id_hi >>= 1; + } + } - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - id_bit = rev_id & 1; + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + id_bit = rev_id & 1; - if (i % 4 == 0) { - // Don't write row parity bit at start of parsing - if (i) - id = (id << 1) | r_parity; - // Start counting parity for new row - r_parity = id_bit; - } else { - // Count row parity - r_parity ^= id_bit; - } + if (i % 4 == 0) { + // Don't write row parity bit at start of parsing + if (i) + id = (id << 1) | r_parity; + // Start counting parity for new row + r_parity = id_bit; + } else { + // Count row parity + r_parity ^= id_bit; + } - // First elements in column? - if (i < 4) - // Fill out first elements - c_parity[i] = id_bit; - else - // Count column parity - c_parity[i % 4] ^= id_bit; + // First elements in column? + if (i < 4) + // Fill out first elements + c_parity[i] = id_bit; + else + // Count column parity + c_parity[i % 4] ^= id_bit; - // Insert ID bit - id = (id << 1) | id_bit; - rev_id >>= 1; - } + // Insert ID bit + id = (id << 1) | id_bit; + rev_id >>= 1; + } - // Insert parity bit of last row - id = (id << 1) | r_parity; + // Insert parity bit of last row + id = (id << 1) | r_parity; - // Fill out column parity at the end of tag - for (i = 0; i < 4; ++i) - id = (id << 1) | c_parity[i]; + // Fill out column parity at the end of tag + for (i = 0; i < 4; ++i) + id = (id << 1) | c_parity[i]; - // Add stop bit - id <<= 1; + // Add stop bit + id <<= 1; - Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); - LED_D_ON(); + Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); + LED_D_ON(); - // Write EM410x ID - T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0); - T55xxWriteBlock((uint32_t)id, 2, 0, 0); + // Write EM410x ID + T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0); + T55xxWriteBlock((uint32_t)id, 2, 0, 0); - // Config for EM410x (RF/64, Manchester, Maxblock=2) - if (card) { - // Clock rate is stored in bits 8-15 of the card value - clock = (card & 0xFF00) >> 8; - Dbprintf("Clock rate: %d", clock); - switch (clock) - { - case 32: - clock = T55x7_BITRATE_RF_32; - break; - case 16: - clock = T55x7_BITRATE_RF_16; - break; - case 0: - // A value of 0 is assumed to be 64 for backwards-compatibility - // Fall through... - case 64: - clock = T55x7_BITRATE_RF_64; - break; - default: - Dbprintf("Invalid clock rate: %d", clock); - return; - } + // Config for EM410x (RF/64, Manchester, Maxblock=2) + if (card) { + // Clock rate is stored in bits 8-15 of the card value + clock = (card & 0xFF00) >> 8; + Dbprintf("Clock rate: %d", clock); + switch (clock) + { + case 32: + clock = T55x7_BITRATE_RF_32; + break; + case 16: + clock = T55x7_BITRATE_RF_16; + break; + case 0: + // A value of 0 is assumed to be 64 for backwards-compatibility + // Fall through... + case 64: + clock = T55x7_BITRATE_RF_64; + break; + default: + Dbprintf("Invalid clock rate: %d", clock); + return; + } - // Writing configuration for T55x7 tag - T55xxWriteBlock(clock | - T55x7_MODULATION_MANCHESTER | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); - } - else - // Writing configuration for T5555(Q5) tag - T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT | - T5555_MODULATION_MANCHESTER | - 2 << T5555_MAXBLOCK_SHIFT, - 0, 0, 0); + // Writing configuration for T55x7 tag + T55xxWriteBlock(clock | + T55x7_MODULATION_MANCHESTER | + 2 << T55x7_MAXBLOCK_SHIFT, + 0, 0, 0); + } + else + // Writing configuration for T5555(Q5) tag + T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT | + T5555_MODULATION_MANCHESTER | + 2 << T5555_MAXBLOCK_SHIFT, + 0, 0, 0); - LED_D_OFF(); - Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555", - (uint32_t)(id >> 32), (uint32_t)id); + LED_D_OFF(); + Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555", + (uint32_t)(id >> 32), (uint32_t)id); } // Clone Indala 64-bit tag by UID to T55x7 void CopyIndala64toT55x7(int hi, int lo) { - //Program the 2 data blocks for supplied 64bit UID - // and the block 0 for Indala64 format - T55xxWriteBlock(hi,1,0,0); - T55xxWriteBlock(lo,2,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) - // T5567WriteBlock(0x603E1042,0); + //Program the 2 data blocks for supplied 64bit UID + // and the block 0 for Indala64 format + T55xxWriteBlock(hi,1,0,0); + T55xxWriteBlock(lo,2,0,0); + //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2) + T55xxWriteBlock(T55x7_BITRATE_RF_32 | + T55x7_MODULATION_PSK1 | + 2 << T55x7_MAXBLOCK_SHIFT, + 0, 0, 0); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) + // T5567WriteBlock(0x603E1042,0); - DbpString("DONE!"); + DbpString("DONE!"); } void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7) { - //Program the 7 data blocks for supplied 224bit UID - // and the block 0 for Indala224 format - T55xxWriteBlock(uid1,1,0,0); - T55xxWriteBlock(uid2,2,0,0); - T55xxWriteBlock(uid3,3,0,0); - T55xxWriteBlock(uid4,4,0,0); - T55xxWriteBlock(uid5,5,0,0); - T55xxWriteBlock(uid6,6,0,0); - T55xxWriteBlock(uid7,7,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 7 << T55x7_MAXBLOCK_SHIFT, - 0,0,0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) - // T5567WriteBlock(0x603E10E2,0); + //Program the 7 data blocks for supplied 224bit UID + // and the block 0 for Indala224 format + T55xxWriteBlock(uid1,1,0,0); + T55xxWriteBlock(uid2,2,0,0); + T55xxWriteBlock(uid3,3,0,0); + T55xxWriteBlock(uid4,4,0,0); + T55xxWriteBlock(uid5,5,0,0); + T55xxWriteBlock(uid6,6,0,0); + T55xxWriteBlock(uid7,7,0,0); + //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) + T55xxWriteBlock(T55x7_BITRATE_RF_32 | + T55x7_MODULATION_PSK1 | + 7 << T55x7_MAXBLOCK_SHIFT, + 0,0,0); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) + // T5567WriteBlock(0x603E10E2,0); - DbpString("DONE!"); + DbpString("DONE!"); } @@ -1460,260 +1377,260 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int #define max(x,y) ( x GraphBuffer[0]) { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) - break; - i++; + uint8_t BitStream[256]; + uint8_t Blocks[8][16]; + uint8_t *GraphBuffer = (uint8_t *)BigBuf; + int GraphTraceLen = sizeof(BigBuf); + int i, j, lastval, bitidx, half_switch; + int clock = 64; + int tolerance = clock / 8; + int pmc, block_done; + int lc, warnings = 0; + int num_blocks = 0; + int lmin=128, lmax=128; + uint8_t dir; + + AcquireRawAdcSamples125k(0); + + lmin = 64; + lmax = 192; + + i = 2; + + /* Find first local max/min */ + if(GraphBuffer[1] > GraphBuffer[0]) { + while(i < GraphTraceLen) { + if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) + break; + i++; + } + dir = 0; } - dir = 0; - } - else { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) - break; - i++; + else { + while(i < GraphTraceLen) { + if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) + break; + i++; + } + dir = 1; } - dir = 1; - } - - lastval = i++; - half_switch = 0; - pmc = 0; - block_done = 0; - - for (bitidx = 0; i < GraphTraceLen; i++) - { - if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) + + lastval = i++; + half_switch = 0; + pmc = 0; + block_done = 0; + + for (bitidx = 0; i < GraphTraceLen; i++) { - lc = i - lastval; - lastval = i; - - // Switch depending on lc length: - // Tolerance is 1/8 of clock rate (arbitrary) - if (abs(lc-clock/4) < tolerance) { - // 16T0 - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33+16)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else { - pmc = i; - } - } else if (abs(lc-clock/2) < tolerance) { - // 32TO - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else if(half_switch == 1) { - BitStream[bitidx++] = 0; - half_switch = 0; - } - else - half_switch++; - } else if (abs(lc-clock) < tolerance) { - // 64TO - BitStream[bitidx++] = 1; - } else { - // Error - warnings++; - if (warnings > 10) + if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) { - Dbprintf("Error: too many detection errors, aborting."); - return 0; + lc = i - lastval; + lastval = i; + + // Switch depending on lc length: + // Tolerance is 1/8 of clock rate (arbitrary) + if (abs(lc-clock/4) < tolerance) { + // 16T0 + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33+16)-1; + lastval = i; + pmc = 0; + block_done = 1; + } + else { + pmc = i; + } + } else if (abs(lc-clock/2) < tolerance) { + // 32TO + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33)-1; + lastval = i; + pmc = 0; + block_done = 1; + } + else if(half_switch == 1) { + BitStream[bitidx++] = 0; + half_switch = 0; + } + else + half_switch++; + } else if (abs(lc-clock) < tolerance) { + // 64TO + BitStream[bitidx++] = 1; + } else { + // Error + warnings++; + if (warnings > 10) + { + Dbprintf("Error: too many detection errors, aborting."); + return 0; + } + } + + if(block_done == 1) { + if(bitidx == 128) { + for(j=0; j<16; j++) { + Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ + 64*BitStream[j*8+6]+ + 32*BitStream[j*8+5]+ + 16*BitStream[j*8+4]+ + 8*BitStream[j*8+3]+ + 4*BitStream[j*8+2]+ + 2*BitStream[j*8+1]+ + BitStream[j*8]; + } + num_blocks++; + } + bitidx = 0; + block_done = 0; + half_switch = 0; + } + if(i < GraphTraceLen) + { + if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; + else dir = 1; + } } - } - - if(block_done == 1) { - if(bitidx == 128) { - for(j=0; j<16; j++) { - Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ - 64*BitStream[j*8+6]+ - 32*BitStream[j*8+5]+ - 16*BitStream[j*8+4]+ - 8*BitStream[j*8+3]+ - 4*BitStream[j*8+2]+ - 2*BitStream[j*8+1]+ - BitStream[j*8]; - } - num_blocks++; - } - bitidx = 0; - block_done = 0; - half_switch = 0; - } - if(i < GraphTraceLen) - { - if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; - else dir = 1; + if(bitidx==255) + bitidx=0; + warnings = 0; + if(num_blocks == 4) break; } - } - if(bitidx==255) - bitidx=0; - warnings = 0; - if(num_blocks == 4) break; - } - memcpy(outBlocks, Blocks, 16*num_blocks); - return num_blocks; + memcpy(outBlocks, Blocks, 16*num_blocks); + return num_blocks; } int IsBlock0PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled - return 1; - if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? - return 1; - return 0; + // Assume RFU means 0 :) + if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled + return 1; + if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? + return 1; + return 0; } int IsBlock1PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) - if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) - return 1; - - return 0; + // Assume RFU means 0 :) + if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) + if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) + return 1; + + return 0; } #define ALLOC 16 void ReadPCF7931() { - uint8_t Blocks[8][17]; - uint8_t tmpBlocks[4][16]; - int i, j, ind, ind2, n; - int num_blocks = 0; - int max_blocks = 8; - int ident = 0; - int error = 0; - int tries = 0; - - memset(Blocks, 0, 8*17*sizeof(uint8_t)); - - do { - memset(tmpBlocks, 0, 4*16*sizeof(uint8_t)); - n = DemodPCF7931((uint8_t**)tmpBlocks); - if(!n) - error++; - if(error==10 && num_blocks == 0) { - Dbprintf("Error, no tag or bad tag"); - return; - } - else if (tries==20 || error==10) { - Dbprintf("Error reading the tag"); - Dbprintf("Here is the partial content"); - goto end; - } - - for(i=0; i= 0; ind--,ind2--) { - if(ind2 < 0) - ind2 = max_blocks; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { - if(ind2 > max_blocks) - ind2 = 0; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - } - } + else if (tries==20 || error==10) { + Dbprintf("Error reading the tag"); + Dbprintf("Here is the partial content"); + goto end; } - } - } - tries++; - if (BUTTON_PRESS()) return; - } while (num_blocks != max_blocks); + + for(i=0; i= 0; ind--,ind2--) { + if(ind2 < 0) + ind2 = max_blocks; + if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found + // Dbprintf("Tmp %d -> Block %d", ind, ind2); + memcpy(Blocks[ind2], tmpBlocks[ind], 16); + Blocks[ind2][ALLOC] = 1; + num_blocks++; + if(num_blocks == max_blocks) goto end; + } + } + for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { + if(ind2 > max_blocks) + ind2 = 0; + if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found + // Dbprintf("Tmp %d -> Block %d", ind, ind2); + memcpy(Blocks[ind2], tmpBlocks[ind], 16); + Blocks[ind2][ALLOC] = 1; + num_blocks++; + if(num_blocks == max_blocks) goto end; + } + } + } + } + } + } + } + tries++; + if (BUTTON_PRESS()) return; + } while (num_blocks != max_blocks); end: - Dbprintf("-----------------------------------------"); - Dbprintf("Memory content:"); - Dbprintf("-----------------------------------------"); - for(i=0; i", i); - } - Dbprintf("-----------------------------------------"); - - return ; + Dbprintf("-----------------------------------------"); + Dbprintf("Memory content:"); + Dbprintf("-----------------------------------------"); + for(i=0; i", i); + } + Dbprintf("-----------------------------------------"); + + return ; } @@ -1737,20 +1654,20 @@ uint8_t * fwd_write_ptr; //forwardlink bit pointer //==================================================================== //-------------------------------------------------------------------- uint8_t Prepare_Cmd( uint8_t cmd ) { - //-------------------------------------------------------------------- - - *forward_ptr++ = 0; //start bit - *forward_ptr++ = 0; //second pause for 4050 code - - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - - return 6; //return number of emited bits + //-------------------------------------------------------------------- + + *forward_ptr++ = 0; //start bit + *forward_ptr++ = 0; //second pause for 4050 code + + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + + return 6; //return number of emited bits } //==================================================================== @@ -1760,21 +1677,21 @@ uint8_t Prepare_Cmd( uint8_t cmd ) { //-------------------------------------------------------------------- uint8_t Prepare_Addr( uint8_t addr ) { - //-------------------------------------------------------------------- - - register uint8_t line_parity; - - uint8_t i; - line_parity = 0; - for(i=0;i<6;i++) { - *forward_ptr++ = addr; - line_parity ^= addr; - addr >>= 1; - } - - *forward_ptr++ = (line_parity & 1); - - return 7; //return number of emited bits + //-------------------------------------------------------------------- + + register uint8_t line_parity; + + uint8_t i; + line_parity = 0; + for(i=0;i<6;i++) { + *forward_ptr++ = addr; + line_parity ^= addr; + addr >>= 1; + } + + *forward_ptr++ = (line_parity & 1); + + return 7; //return number of emited bits } //==================================================================== @@ -1784,36 +1701,36 @@ uint8_t Prepare_Addr( uint8_t addr ) { //-------------------------------------------------------------------- uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { - //-------------------------------------------------------------------- - - register uint8_t line_parity; - register uint8_t column_parity; - register uint8_t i, j; - register uint16_t data; - - data = data_low; - column_parity = 0; - - for(i=0; i<4; i++) { - line_parity = 0; - for(j=0; j<8; j++) { - line_parity ^= data; - column_parity ^= (data & 1) << j; - *forward_ptr++ = data; - data >>= 1; + //-------------------------------------------------------------------- + + register uint8_t line_parity; + register uint8_t column_parity; + register uint8_t i, j; + register uint16_t data; + + data = data_low; + column_parity = 0; + + for(i=0; i<4; i++) { + line_parity = 0; + for(j=0; j<8; j++) { + line_parity ^= data; + column_parity ^= (data & 1) << j; + *forward_ptr++ = data; + data >>= 1; + } + *forward_ptr++ = line_parity; + if(i == 1) + data = data_hi; } - *forward_ptr++ = line_parity; - if(i == 1) - data = data_hi; - } - - for(j=0; j<8; j++) { - *forward_ptr++ = column_parity; - column_parity >>= 1; - } - *forward_ptr = 0; - - return 45; //return number of emited bits + + for(j=0; j<8; j++) { + *forward_ptr++ = column_parity; + column_parity >>= 1; + } + *forward_ptr = 0; + + return 45; //return number of emited bits } //==================================================================== @@ -1822,123 +1739,116 @@ uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { // fwd_bit_count set with number of bits to be sent //==================================================================== void SendForward(uint8_t fwd_bit_count) { - - fwd_write_ptr = forwardLink_data; - fwd_bit_sz = fwd_bit_count; - - LED_D_ON(); - - //Field on - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - - // force 1st mod pulse (start gap must be longer for 4305) - fwd_bit_sz--; //prepare next bit modulation - fwd_write_ptr++; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(16*8); //16 cycles on (8us each) - - // now start writting - while(fwd_bit_sz-- > 0) { //prepare next bit modulation - if(((*fwd_write_ptr++) & 1) == 1) - SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) - else { - //These timings work for 4469/4269/4305 (with the 55*8 above) - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - SpinDelayUs(23*8); //16-4 cycles off (8us each) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(9*8); //16 cycles on (8us each) + + fwd_write_ptr = forwardLink_data; + fwd_bit_sz = fwd_bit_count; + + LED_D_ON(); + + //Field on + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); + + // force 1st mod pulse (start gap must be longer for 4305) + fwd_bit_sz--; //prepare next bit modulation + fwd_write_ptr++; + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on + SpinDelayUs(16*8); //16 cycles on (8us each) + + // now start writting + while(fwd_bit_sz-- > 0) { //prepare next bit modulation + if(((*fwd_write_ptr++) & 1) == 1) + SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) + else { + //These timings work for 4469/4269/4305 (with the 55*8 above) + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + SpinDelayUs(23*8); //16-4 cycles off (8us each) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on + SpinDelayUs(9*8); //16 cycles on (8us each) + } } - } } void EM4xLogin(uint32_t Password) { - - uint8_t fwd_bit_count; - - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN ); - fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 ); - - SendForward(fwd_bit_count); - - //Wait for command to complete - SpinDelay(20); - + + uint8_t fwd_bit_count; + + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN ); + fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 ); + + SendForward(fwd_bit_count); + + //Wait for command to complete + SpinDelay(20); + } void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - - uint8_t *dest = (uint8_t *)BigBuf; - uint16_t bufferlength = 12000; - uint32_t i = 0; - // Clear destination buffer before sending the command 0x80 = average. - memset(dest, 0x80, bufferlength); - - uint8_t fwd_bit_count; - - //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); - - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); - fwd_bit_count += Prepare_Addr( Address ); - - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - - SendForward(fwd_bit_count); - - // // Turn field on to read the response - // TurnReadLFOn(); - - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - ++i; - if (i >= bufferlength) break; - } - } - - cmd_send(CMD_ACK,0,0,0,0,0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + uint8_t fwd_bit_count; + uint8_t *dest = (uint8_t *)BigBuf; + int m=0, i=0; + + //If password mode do login + if (PwdMode == 1) EM4xLogin(Pwd); + + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); + fwd_bit_count += Prepare_Addr( Address ); + + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + SendForward(fwd_bit_count); + + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + if (i >= m) break; + } + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - - uint8_t fwd_bit_count; - - //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); - - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); - fwd_bit_count += Prepare_Addr( Address ); - fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 ); - - SendForward(fwd_bit_count); - - //Wait for write to complete - SpinDelay(20); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + + uint8_t fwd_bit_count; + + //If password mode do login + if (PwdMode == 1) EM4xLogin(Pwd); + + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); + fwd_bit_count += Prepare_Addr( Address ); + fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 ); + + SendForward(fwd_bit_count); + + //Wait for write to complete + SpinDelay(20); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index fc480a38..8541553b 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -15,9 +15,6 @@ #include "mifarecmd.h" #include "apps.h" -#include "util.h" -#include "desfire.h" -#include "../common/crc.h" //----------------------------------------------------------------------------- // Select, Authenticate, Read a MIFARE tag. @@ -76,75 +73,13 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) // ----------------------------- crypto1 destroy crypto1_destroy(pcs); - if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED"); + if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED"); LED_B_ON(); cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16); LED_B_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); -} - - -void MifareUC_Auth1(uint8_t arg0, uint8_t *datain){ - // variables - byte_t isOK = 0; - byte_t dataoutbuf[16]; - uint8_t uid[10]; - uint32_t cuid; - - // clear trace - iso14a_clear_trace(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); - - - if(!iso14443a_select_card(uid, NULL, &cuid)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card, something went wrong before auth"); - }; - - if(mifare_ultra_auth1(cuid, dataoutbuf)){ - if (MF_DBGLEVEL >= 1) Dbprintf("Authentication part1: Fail."); - } - - isOK=1; - if (MF_DBGLEVEL >= 2) DbpString("AUTH 1 FINISHED"); - - LED_B_ON(); - cmd_send(CMD_ACK,isOK,cuid,0,dataoutbuf,11); - LED_B_OFF(); - // Thats it... - LEDsoff(); -} -void MifareUC_Auth2(uint32_t arg0, uint8_t *datain){ - // params - uint32_t cuid = arg0; - uint8_t key[16]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - // variables - byte_t isOK = 0; - byte_t dataoutbuf[16]; - - memcpy(key, datain, 16); - - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); - - if(mifare_ultra_auth2(cuid, key, dataoutbuf)){ - if (MF_DBGLEVEL >= 1) Dbprintf("Authentication part2: Fail..."); - } - isOK=1; - if (MF_DBGLEVEL >= 2) DbpString("AUTH 2 FINISHED"); - - LED_B_ON(); - cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,11); - LED_B_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); } @@ -265,38 +200,37 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) LEDsoff(); } -void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain) + +void MifareUReadCard(uint8_t arg0, uint8_t *datain) { - // params - uint8_t sectorNo = arg0; - int Pages=arg1; - int count_Pages=0; - // variables - byte_t isOK = 0; - byte_t dataoutbuf[176]; - uint8_t uid[10]; - uint32_t cuid; + // params + uint8_t sectorNo = arg0; + + // variables + byte_t isOK = 0; + byte_t dataoutbuf[16 * 4]; + uint8_t uid[10]; + uint32_t cuid; - // clear trace - iso14a_clear_trace(); + // clear trace + iso14a_clear_trace(); +// iso14a_set_tracing(false); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + + LED_A_ON(); + LED_B_OFF(); + LED_C_OFF(); - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); - Dbprintf("Pages %d",Pages); while (true) { if(!iso14443a_select_card(uid, NULL, &cuid)) { if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); break; }; - for(int sec=0;sec= 1) Dbprintf("Read block %d error",sec); break; - }else{ - count_Pages++; }; } if(mifare_ultra_halt(cuid)) { @@ -307,18 +241,16 @@ void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain) isOK = 1; break; } - Dbprintf("Pages read %d",count_Pages); - if (MF_DBGLEVEL >= 2) DbpString("READ CARD FINISHED"); + + if (MF_DBGLEVEL >= 2) DbpString("READ CARD FINISHED"); LED_B_ON(); - if (Pages==16) cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,64); - if (Pages==44 && count_Pages==16) cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,64); - if (Pages==44 && count_Pages>16) cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,176); + cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,64); LED_B_OFF(); - // Thats it... - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); + // Thats it... + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); } @@ -505,7 +437,7 @@ void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain) } // Return 1 if the nonce is invalid else return 0 -int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t * parity) { +int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) { return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \ (oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \ (oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0; @@ -541,7 +473,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat struct Crypto1State mpcs = {0, 0}; struct Crypto1State *pcs; pcs = &mpcs; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); + uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint32_t auth1_time, auth2_time; static uint16_t delta_time; @@ -562,7 +494,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat WDT_HIT(); davg = dmax = 0; - dmin = 2000; + dmin = 2000; delta_time = 0; for (rtr = 0; rtr < 17; rtr++) { @@ -599,7 +531,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat }; nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160 - for (i = 141; i < 1200; i++) { + for (i = 101; i < 1200; i++) { nttmp = prng_successor(nttmp, 1); if (nttmp == nt2) break; } @@ -617,7 +549,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat } } - if (rtr <= 1) return; + if (rtr <= 1) return; davg = (davg + (rtr - 1)/2) / (rtr - 1); @@ -636,18 +568,9 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat // get crypted nonces for target sector for(i=0; i < 2; i++) { // look for exactly two different nonces - WDT_HIT(); - if(BUTTON_PRESS()) { - DbpString("Nested: cancelled"); - crypto1_destroy(pcs); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - return; - } - target_nt[i] = 0; while(target_nt[i] == 0) { // continue until we have an unambiguous nonce - + // prepare next select. No need to power down the card. if(mifare_classic_halt(pcs, cuid)) { if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Halt error"); @@ -707,7 +630,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat if (target_nt[i] == 0 && j == dmax+1 && MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (all invalid)", i+1); } } - + LED_C_OFF(); // ----------------------------- crypto1 destroy @@ -941,15 +864,15 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai uint8_t d_block[18] = {0x00}; uint32_t cuid; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); + uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; - + // reset FPGA and LED if (workFlags & 0x08) { LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - + iso14a_clear_trace(); iso14a_set_tracing(TRUE); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -1067,7 +990,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - + iso14a_clear_trace(); iso14a_set_tracing(TRUE); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -1148,75 +1071,3 @@ void MifareCIdent(){ // // DESFIRE // - -void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){ - // variables - byte_t isOK = 0; - byte_t dataoutbuf[16]; - uint8_t uid[10]; - uint32_t cuid; - - // clear trace - iso14a_clear_trace(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); - - - if(!iso14443a_select_card(uid, NULL, &cuid)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card, something went wrong before auth"); - }; - - if(mifare_desfire_des_auth1(cuid, dataoutbuf)){ - if (MF_DBGLEVEL >= 1) Dbprintf("Authentication part1: Fail."); - } - - isOK=1; - if (MF_DBGLEVEL >= 2) DbpString("AUTH 1 FINISHED"); - - LED_B_ON(); - cmd_send(CMD_ACK,isOK,cuid,0,dataoutbuf,11); - LED_B_OFF(); - - // Thats it... - //FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); -} - -void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){ - // params - uint32_t cuid = arg0; - uint8_t key[16]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - // variables - byte_t isOK = 0; - byte_t dataoutbuf[16]; - - memcpy(key, datain, 16); - // clear trace - //iso14a_clear_trace(); - //iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); - -// Dbprintf("Sending %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", -// key[0],key[1],key[2],key[3],key[4],key[5],key[6],key[7],key[8], -// key[9],key[10],key[11],key[12],key[13],key[14],key[15]); - - if(mifare_desfire_des_auth2(cuid, key, dataoutbuf)){ - if (MF_DBGLEVEL >= 1) Dbprintf("Authentication part2: Fail..."); - } - isOK=1; - if (MF_DBGLEVEL >= 2) DbpString("AUTH 2 FINISHED"); - - LED_B_ON(); - cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,12); - LED_B_OFF(); - - // Thats it... - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); -} \ No newline at end of file diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 2c5a7e3f..3c00a343 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -13,15 +13,16 @@ #ifndef __MIFARECMD_H #define __MIFARECMD_H -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" #include "util.h" #include "string.h" -#include "../common/iso14443crc.h" +#include "iso14443crc.h" #include "iso14443a.h" #include "crapto1.h" #include "mifareutil.h" -#include "../include/common.h" +#include "common.h" + #endif \ No newline at end of file diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c deleted file mode 100644 index 155538cb..00000000 --- a/armsrc/mifaredesfire.c +++ /dev/null @@ -1,521 +0,0 @@ -#include "mifaredesfire.h" -#include "des.h" - -#define MAX_APPLICATION_COUNT 28 -#define MAX_FILE_COUNT 16 -#define MAX_DESFIRE_FRAME_SIZE 60 -#define NOT_YET_AUTHENTICATED 255 -#define FRAME_PAYLOAD_SIZE (MAX_DESFIRE_FRAME_SIZE - 5) -#define RECEIVE_SIZE 64 - -// the block number for the ISO14443-4 PCB -uint8_t pcb_blocknum = 0; -// Deselect card by sending a s-block. the crc is precalced for speed -static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4}; - -//static uint8_t __msg[MAX_FRAME_SIZE] = { 0x0A, 0x00, 0x00, /* ..., */ 0x00 }; -/* PCB CID CMD PAYLOAD */ -//static uint8_t __res[MAX_FRAME_SIZE]; - -bool InitDesfireCard(){ - - // Make sure it is off. -// FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); -// SpinDelay(300); - - byte_t cardbuf[USB_CMD_DATA_SIZE]; - memset(cardbuf,0,sizeof(cardbuf)); - iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf; - - iso14a_set_tracing(TRUE); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - - int len = iso14443a_select_card(NULL,card,NULL); - - if (!len) { - if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); - OnError(); - return false; - } - return true; -} - -// ARG0 flag enums -enum { - NONE = 0x00, - INIT = 0x01, - DISCONNECT = 0x02, - CLEARTRACE = 0x04, - BAR = 0x08, -} CmdOptions ; - -void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){ - - /* ARG0 contains flags. - 0x01 = init card. - 0x02 = Disconnect - 0x03 - */ - uint8_t flags = arg0; - size_t datalen = arg1; - uint8_t resp[RECEIVE_SIZE]; - memset(resp,0,sizeof(resp)); - - if (MF_DBGLEVEL >= 4) { - Dbprintf(" flags : %02X", flags); - Dbprintf(" len : %02X", datalen); - print_result(" RX : ", datain, datalen); - } - - if ( flags & CLEARTRACE ){ - iso14a_clear_trace(); - } - - if ( flags & INIT ){ - if ( !InitDesfireCard() ) - return; - } - - int len = DesfireAPDU(datain, datalen, resp); - if (MF_DBGLEVEL >= 4) { - print_result("ERR <--: ", resp, len); - } - - if ( !len ) { - OnError(); - return; - } - - // reset the pcb_blocknum, - pcb_blocknum = 0; - - if ( flags & DISCONNECT ){ - OnSuccess(); - } - - cmd_send(CMD_ACK,1,len,0,resp,len); -} - -void MifareDesfireGetInformation(){ - - int len = 0; - uint8_t resp[USB_CMD_DATA_SIZE]; - uint8_t dataout[USB_CMD_DATA_SIZE]; - byte_t cardbuf[USB_CMD_DATA_SIZE]; - - memset(resp,0,sizeof(resp)); - memset(dataout,0, sizeof(dataout)); - memset(cardbuf,0,sizeof(cardbuf)); - - /* - 1 = PCB 1 - 2 = cid 2 - 3 = desfire command 3 - 4-5 = crc 4 key - 5-6 crc - PCB == 0x0A because sending CID byte. - CID == 0x00 first card? - */ - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - - // card select - information - iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf; - byte_t isOK = iso14443a_select_card(NULL, card, NULL); - if ( isOK == 0) { - if (MF_DBGLEVEL >= 1) { - Dbprintf("Can't select card"); - } - OnError(); - return; - } - - memcpy(dataout,card->uid,7); - - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); - - uint8_t cmd[] = {GET_VERSION}; - size_t cmd_len = sizeof(cmd); - - len = DesfireAPDU(cmd, cmd_len, resp); - if ( !len ) { - print_result("ERROR <--: ", resp, len); - OnError(); - return; - } - - LED_A_OFF(); - LED_B_ON(); - memcpy(dataout+7,resp+3,7); - - // ADDITION_FRAME 1 - cmd[0] = ADDITIONAL_FRAME; - len = DesfireAPDU(cmd, cmd_len, resp); - if ( !len ) { - print_result("ERROR <--: ", resp, len); - OnError(); - return; - } - - LED_B_OFF(); - LED_C_ON(); - memcpy(dataout+7+7,resp+3,7); - - // ADDITION_FRAME 2 - len = DesfireAPDU(cmd, cmd_len, resp); - if ( !len ) { - print_result("ERROR <--: ", resp, len); - OnError(); - return; - } - - memcpy(dataout+7+7+7,resp+3,14); - - cmd_send(CMD_ACK,1,0,0,dataout,sizeof(dataout)); - - // reset the pcb_blocknum, - pcb_blocknum = 0; - OnSuccess(); -} - -void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain){ - - int len = 0; - //uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47}; - uint8_t PICC_MASTER_KEY16[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f }; - uint8_t null_key_data8[8] = {0x00}; - //uint8_t null_key_data16[16] = {0x00}; - //uint8_t new_key_data8[8] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77}; - //uint8_t new_key_data16[16] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}; - - //uint8_t* bigbuffer = get_bigbufptr_recvrespbuf(); - uint8_t resp[256] = {0x00}; - uint8_t IV[16] = {0x00}; - - size_t datalen = datain[0]; - - uint8_t cmd[40] = {0x00}; - uint8_t encRndB[16] = {0x00}; - uint8_t decRndB[16] = {0x00}; - uint8_t nonce[16] = {0x00}; - uint8_t both[32] = {0x00}; - uint8_t encBoth[32] = {0x00}; - - InitDesfireCard(); - - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); - - // 3 olika sätt att authenticera. AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32) - // 4 olika crypto algo DES, 3DES, 3K3DES, AES - // 3 olika kommunikations sätt, PLAIN,MAC,CRYPTO - - // des, nyckel 0, - switch (mode){ - case 1:{ - if (algo == 1) { - - uint8_t keybytes[8]; - uint8_t RndA[8] = {0x00}; - uint8_t RndB[8] = {0x00}; - - if (datain[1] == 0xff){ - memcpy(keybytes,null_key_data8,8); - } else{ - memcpy(keybytes, datain+1, datalen); - } - - struct desfire_key defaultkey = {0}; - desfirekey_t key = &defaultkey; - Desfire_des_key_new(keybytes, key); - - cmd[0] = AUTHENTICATE; - cmd[1] = keyno; //keynumber - len = DesfireAPDU(cmd, 2, resp); - if ( !len ) { - if (MF_DBGLEVEL >= 1) { - DbpString("Authentication failed. Card timeout."); - } - OnError(); - return; - } - - if ( resp[2] == 0xaf ){ - } else { - DbpString("Authetication failed. Invalid key number."); - OnError(); - return; - } - - memcpy( encRndB, resp+3, 8); - - des_dec(&decRndB, &encRndB, key->data); - memcpy(RndB, decRndB, 8); - rol(decRndB,8); - - // This should be random - uint8_t decRndA[8] = {0x00}; - memcpy(RndA, decRndA, 8); - uint8_t encRndA[8] = {0x00}; - - des_dec(&encRndA, &decRndA, key->data); - - memcpy(both, encRndA, 8); - - for (int x = 0; x < 8; x++) { - decRndB[x] = decRndB[x] ^ encRndA[x]; - - } - - des_dec(&encRndB, &decRndB, key->data); - - memcpy(both + 8, encRndB, 8); - - cmd[0] = ADDITIONAL_FRAME; - memcpy(cmd+1, both, 16 ); - - len = DesfireAPDU(cmd, 17, resp); - if ( !len ) { - if (MF_DBGLEVEL >= 1) { - DbpString("Authentication failed. Card timeout."); - } - OnError(); - return; - } - - if ( resp[2] == 0x00 ){ - - struct desfire_key sessionKey = {0}; - desfirekey_t skey = &sessionKey; - Desfire_session_key_new( RndA, RndB , key, skey ); - //print_result("SESSION : ", skey->data, 8); - - memcpy(encRndA, resp+3, 8); - des_dec(&encRndA, &encRndA, key->data); - rol(decRndA,8); - for (int x = 0; x < 8; x++) { - if (decRndA[x] != encRndA[x]) { - DbpString("Authetication failed. Cannot varify PICC."); - OnError(); - return; - } - } - - //Change the selected key to a new value. - /* - - cmd[0] = CHANGE_KEY; - cmd[1] = keyno; - - uint8_t newKey[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77}; - - uint8_t first, second; - uint8_t buff1[8] = {0x00}; - uint8_t buff2[8] = {0x00}; - uint8_t buff3[8] = {0x00}; - - memcpy(buff1,newKey, 8); - memcpy(buff2,newKey + 8, 8); - - ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second); - memcpy(buff3, &first, 1); - memcpy(buff3 + 1, &second, 1); - - des_dec(&buff1, &buff1, skey->data); - memcpy(cmd+2,buff1,8); - - for (int x = 0; x < 8; x++) { - buff2[x] = buff2[x] ^ buff1[x]; - } - des_dec(&buff2, &buff2, skey->data); - memcpy(cmd+10,buff2,8); - - for (int x = 0; x < 8; x++) { - buff3[x] = buff3[x] ^ buff2[x]; - } - des_dec(&buff3, &buff3, skey->data); - memcpy(cmd+18,buff3,8); - - // The command always times out on the first attempt, this will retry until a response - // is recieved. - len = 0; - while(!len) { - len = DesfireAPDU(cmd,26,resp); - } - */ - - OnSuccess(); - cmd_send(CMD_ACK,1,0,0,skey->data,8); - - } else { - DbpString("Authetication failed."); - OnError(); - return; - } - - } - } - break; - case 2: - //SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp); - break; - case 3:{ - - //defaultkey - uint8_t keybytes[16]; - if (datain[1] == 0xff){ - memcpy(keybytes,PICC_MASTER_KEY16,16); - } else{ - memcpy(keybytes, datain+1, datalen); - } - - struct desfire_key defaultkey = {0}; - desfirekey_t key = &defaultkey; - Desfire_aes_key_new( keybytes, key); - - AesCtx ctx; - if ( AesCtxIni(&ctx, IV, key->data, KEY128, CBC) < 0 ){ - if( MF_DBGLEVEL >= 4) { - Dbprintf("AES context failed to init"); - } - OnError(); - return; - } - - cmd[0] = AUTHENTICATE_AES; - cmd[1] = 0x00; //keynumber - len = DesfireAPDU(cmd, 2, resp); - if ( !len ) { - if (MF_DBGLEVEL >= 1) { - DbpString("Authentication failed. Card timeout."); - } - OnError(); - return; - } - - memcpy( encRndB, resp+3, 16); - - // dekryptera tagnonce. - AesDecrypt(&ctx, encRndB, decRndB, 16); - rol(decRndB,16); - memcpy(both, nonce,16); - memcpy(both+16, decRndB ,16 ); - AesEncrypt(&ctx, both, encBoth, 32 ); - - cmd[0] = ADDITIONAL_FRAME; - memcpy(cmd+1, encBoth, 32 ); - - len = DesfireAPDU(cmd, 33, resp); // 1 + 32 == 33 - if ( !len ) { - if (MF_DBGLEVEL >= 1) { - DbpString("Authentication failed. Card timeout."); - } - OnError(); - return; - } - - if ( resp[2] == 0x00 ){ - // Create AES Session key - struct desfire_key sessionKey = {0}; - desfirekey_t skey = &sessionKey; - Desfire_session_key_new( nonce, decRndB , key, skey ); - print_result("SESSION : ", skey->data, 16); - } else { - DbpString("Authetication failed."); - OnError(); - return; - } - - break; - } - } - - OnSuccess(); - cmd_send(CMD_ACK,1,len,0,resp,len); -} - -// 3 olika ISO sätt att skicka data till DESFIRE (direkt, inkapslat, inkapslat ISO) -// cmd = cmd bytes to send -// cmd_len = length of cmd -// dataout = pointer to response data array -int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){ - - size_t len = 0; - size_t wrappedLen = 0; - uint8_t wCmd[USB_CMD_DATA_SIZE] = {0}; - - uint8_t *resp = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET; - uint8_t *resp_par = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET; - - wrappedLen = CreateAPDU( cmd, cmd_len, wCmd); - - if (MF_DBGLEVEL >= 4) { - print_result("WCMD <--: ", wCmd, wrappedLen); - } - ReaderTransmit( wCmd, wrappedLen, NULL); - - len = ReaderReceive(resp, resp_par); - - if( len == 0x00 ){ - if (MF_DBGLEVEL >= 4) { - Dbprintf("fukked"); - } - return FALSE; //DATA LINK ERROR - } - // if we received an I- or R(ACK)-Block with a block number equal to the - // current block number, toggle the current block number - else if (len >= 4 // PCB+CID+CRC = 4 bytes - && ((resp[0] & 0xC0) == 0 // I-Block - || (resp[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0 - && (resp[0] & 0x01) == pcb_blocknum) // equal block numbers - { - pcb_blocknum ^= 1; //toggle next block - } - - memcpy(dataout, resp, len); - return len; -} - -// CreateAPDU -size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout){ - - size_t cmdlen = MIN(len+4, USB_CMD_DATA_SIZE-1); - - uint8_t cmd[cmdlen]; - memset(cmd, 0, cmdlen); - - cmd[0] = 0x0A; // 0x0A = skicka cid, 0x02 = ingen cid. Särskilda bitar // - cmd[0] |= pcb_blocknum; // OR the block number into the PCB - cmd[1] = 0x00; // CID: 0x00 //TODO: allow multiple selected cards - - memcpy(cmd+2, datain, len); - AppendCrc14443a(cmd, len+2); - - memcpy(dataout, cmd, cmdlen); - - return cmdlen; -} - - // crc_update(&desfire_crc32, 0, 1); /* CMD_WRITE */ - // crc_update(&desfire_crc32, addr, addr_sz); - // crc_update(&desfire_crc32, byte, 8); - // uint32_t crc = crc_finish(&desfire_crc32); - -void OnSuccess(){ - pcb_blocknum = 0; - ReaderTransmit(deselect_cmd, 3 , NULL); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); -} - -void OnError(){ - pcb_blocknum = 0; - ReaderTransmit(deselect_cmd, 3 , NULL); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - cmd_send(CMD_ACK,0,0,0,0,0); - LEDsoff(); -} diff --git a/armsrc/mifaredesfire.h b/armsrc/mifaredesfire.h deleted file mode 100644 index 659e0057..00000000 --- a/armsrc/mifaredesfire.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __MIFAREDESFIRE_H -#define __MIFAREDESFIRE_H - -#include "../include/proxmark3.h" -#include "apps.h" -#include "util.h" -#include "string.h" - -#include "../common/iso14443crc.h" -#include "iso14443a.h" -#include "desfire_key.h" -#include "mifareutil.h" -#include "../include/common.h" - -#endif diff --git a/armsrc/mifaresniff.h b/armsrc/mifaresniff.h index aa2a860f..22daffee 100644 --- a/armsrc/mifaresniff.h +++ b/armsrc/mifaresniff.h @@ -11,16 +11,16 @@ #ifndef __MIFARESNIFF_H #define __MIFARESNIFF_H -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" #include "util.h" #include "string.h" -#include "../common/iso14443crc.h" +#include "iso14443crc.h" #include "iso14443a.h" #include "crapto1.h" #include "mifareutil.h" -#include "../include/common.h" +#include "common.h" #define SNF_INIT 0 #define SNF_NO_FIELD 1 diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 84f77a35..7c856557 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -9,12 +9,12 @@ // Work with mifare cards. //----------------------------------------------------------------------------- -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" #include "util.h" #include "string.h" -#include "../common/iso14443crc.h" +#include "iso14443crc.h" #include "iso14443a.h" #include "crapto1.h" #include "mifareutil.h" @@ -23,7 +23,7 @@ int MF_DBGLEVEL = MF_DBG_ALL; // memory management uint8_t* get_bigbufptr_recvrespbuf(void) { - return (((uint8_t *)BigBuf) + RECV_RESP_OFFSET); + return (((uint8_t *)BigBuf) + RECV_RESP_OFFSET); } uint8_t* get_bigbufptr_recvcmdbuf(void) { return (((uint8_t *)BigBuf) + RECV_CMD_OFFSET); @@ -76,7 +76,7 @@ uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) { } // send commands -int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) +int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) { return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, answer_parity, timing); } @@ -84,39 +84,19 @@ int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) { uint8_t dcmd[8]; - dcmd[0] = cmd; - dcmd[1] = data[0]; + dcmd[0] = cmd; + dcmd[1] = data[0]; dcmd[2] = data[1]; - dcmd[3] = data[2]; - dcmd[4] = data[3]; - dcmd[5] = data[4]; + dcmd[3] = data[2]; + dcmd[4] = data[3]; + dcmd[5] = data[4]; AppendCrc14443a(dcmd, 6); ReaderTransmit(dcmd, sizeof(dcmd), NULL); int len = ReaderReceive(answer, answer_parity); - if(!len) { - if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout."); - return 2; - } - return len; -} - -int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) -{ - uint8_t dcmd[19]; - int len; - dcmd[0] = cmd; - memcpy(dcmd+1,data,16); - AppendCrc14443a(dcmd, 17); - - ReaderTransmit(dcmd, sizeof(dcmd), timing); - len = ReaderReceive(answer, answer_parity); - if(!len) { - if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout."); - len = ReaderReceive(answer,answer_parity); - } - if(len==1) { - if (MF_DBGLEVEL >= 1) Dbprintf("NAK - Authentication failed."); - return 1; + if(!len) + { + if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout."); + return 2; } return len; } @@ -149,7 +129,7 @@ int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cm int len = ReaderReceive(answer, par); if (answer_parity) *answer_parity = par[0]; - + if (crypted == CRYPT_ALL) { if (len == 1) { res = 0; @@ -175,7 +155,7 @@ int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL); } -int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing) +int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing) { // variables int len; @@ -186,9 +166,9 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN uint32_t nt, ntpp; // Supplied tag nonce uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); + uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; - + // Transmit MIFARE_CLASSIC_AUTH len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing); if (MF_DBGLEVEL >= 4) Dbprintf("rand tag nonce len: %x", len); @@ -296,56 +276,6 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo memcpy(blockData, receivedAnswer, 16); return 0; -} - -int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){ - // variables - uint16_t len; - - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; - - // command MIFARE_CLASSIC_READBLOCK - len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL); - if (len == 1) { - if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); - return 1; - } - if (len == 11) { - if (MF_DBGLEVEL >= 1) Dbprintf("Auth1 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4], - receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9], - receivedAnswer[10]); - memcpy(blockData, receivedAnswer, 11); - return 0; - } - //else something went wrong??? - return 1; -} - -int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){ - // variables - uint16_t len; - - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; - - // command MIFARE_CLASSIC_READBLOCK - len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer, receivedAnswerPar, NULL); - if (len == 1) { - if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); - return 1; - } - if (len == 11){ - if (MF_DBGLEVEL >= 1) Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4], - receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9], - receivedAnswer[10]); - memcpy(blockData, receivedAnswer, 11); - return 0; - } - //something went wrong? - return 1; } int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData) @@ -354,10 +284,10 @@ int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData) uint16_t len; uint8_t bt[2]; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; - + uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); + uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + // command MIFARE_CLASSIC_READBLOCK len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL); if (len == 1) { @@ -430,34 +360,34 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData) { - // variables - uint16_t len; - uint8_t par[3] = {0}; // enough for 18 parity bits - uint8_t d_block[18]; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); + // variables + uint16_t len; + uint8_t par[3] = {0}; // enough for 18 parity bits + uint8_t d_block[18]; + uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; - - // command MIFARE_CLASSIC_WRITEBLOCK - len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL); + + // command MIFARE_CLASSIC_WRITEBLOCK + len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL); - if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK - if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]); - return 1; - } + if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK + if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]); + return 1; + } memset(d_block,'\0',18); memcpy(d_block, blockData, 16); AppendCrc14443a(d_block, 16); ReaderTransmitPar(d_block, sizeof(d_block), par, NULL); - - // Receive the response + + // Receive the response len = ReaderReceive(receivedAnswer, receivedAnswerPar); if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK - if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len); - return 2; - } + if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len); + return 2; + } return 0; } @@ -465,8 +395,8 @@ int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData) int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData) { uint16_t len; - uint8_t d_block[8]; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); + uint8_t d_block[8]; + uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; // command MIFARE_CLASSIC_WRITEBLOCK @@ -478,17 +408,17 @@ int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *bloc //i know the data send here is correct len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL); - if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK - if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len); - return 1; - } - return 0; + if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK + if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len); + return 1; + } + return 0; } int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) { uint16_t len; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); + uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL); @@ -502,9 +432,9 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) int mifare_ultra_halt(uint32_t uid) { - uint16_t len; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint16_t len; + uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); + uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL); if (len != 0) { @@ -538,7 +468,7 @@ uint8_t FirstBlockOfSector(uint8_t sectorNo) // work with emulator memory void emlSetMem(uint8_t *data, int blockNum, int blocksCount) { - uint8_t* emCARD = get_bigbufptr_emlcardmem(); + uint8_t* emCARD = get_bigbufptr_emlcardmem(); memcpy(emCARD + blockNum * 16, data, blocksCount * 16); } @@ -576,7 +506,7 @@ int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) { } memcpy(blReg, data, 4); - *blBlock = data[12]; + *blBlock = data[12]; return 0; } @@ -623,91 +553,3 @@ void emlClearMem(void) { emlSetMem((uint8_t *)uid, 0, 1); return; } - -// -//DESFIRE -// -int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) -{ - uint8_t dcmd[5] = {0x00}; - dcmd[0] = cmd; - memcpy(dcmd+1,data,2); - AppendCrc14443a(dcmd, 3); - - ReaderTransmit(dcmd, sizeof(dcmd), NULL); - int len = ReaderReceive(answer, answer_parity); - if(!len) { - if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout."); - return 2; - } - return len; -} - -int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer,uint8_t *answer_parity, uint32_t *timing) -{ - uint8_t dcmd[20] = {0x00}; - dcmd[0] = cmd; - memcpy(dcmd+1,data,17); - AppendCrc14443a(dcmd, 18); - - ReaderTransmit(dcmd, sizeof(dcmd), NULL); - int len = ReaderReceive(answer, answer_parity); - if(!len){ - if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout."); - return 2; - } - return len; -} - -int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData){ - // variables - int len; - // load key, keynumber - uint8_t data[2]={0x0a, 0x00}; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; - - // command MIFARE_CLASSIC_READBLOCK - len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer,receivedAnswerPar,NULL); - if (len == 1) { - if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); - return 1; - } - - if (len == 12) { - if (MF_DBGLEVEL >= 1) Dbprintf("Auth1 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4], - receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9], - receivedAnswer[10],receivedAnswer[11]); - memcpy(blockData, receivedAnswer, 12); - return 0; - } - return 1; -} - -int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){ - // variables - int len; - uint8_t data[17]={0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - memcpy(data+1,key,16); - - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; - - // command MIFARE_CLASSIC_READBLOCK - len = mifare_sendcmd_special2(NULL, 1, 0x03, data, receivedAnswer, receivedAnswerPar ,NULL); - - if ((receivedAnswer[0] == 0x03)&&(receivedAnswer[1] == 0xae)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Auth Error: %02x %02x", receivedAnswer[0], receivedAnswer[1]); - return 1; - } - if (len == 12){ - if (MF_DBGLEVEL >= 1) Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4], - receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9], - receivedAnswer[10],receivedAnswer[11]); - memcpy(blockData, receivedAnswer, 12); - return 0; - } - return 1; -} \ No newline at end of file diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index 6ef5e0a5..c8f3dadf 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -16,7 +16,7 @@ #define CRYPT_NONE 0 #define CRYPT_ALL 1 #define CRYPT_REQUEST 2 -#define AUTH_FIRST 0 +#define AUTH_FIRST 0 #define AUTH_NESTED 2 // mifare 4bit card answers @@ -55,28 +55,18 @@ extern int MF_DBGLEVEL; //functions uint8_t* mifare_get_bigbufptr(void); int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); -int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing); - -int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing); +int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested); int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing); int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); -int mifare_ultra_auth1(uint32_t cuid, uint8_t *blockData); -int mifare_ultra_auth2(uint32_t cuid, uint8_t *key, uint8_t *blockData); int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData); int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData); int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData); int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid); int mifare_ultra_halt(uint32_t uid); - -// desfire -int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); -int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer,uint8_t *answer_parity, uint32_t *timing); -int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData); -int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData); // crypto functions void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *receivedCmd, int len); diff --git a/armsrc/start.c b/armsrc/start.c index 3f5dc676..d7332bda 100644 --- a/armsrc/start.c +++ b/armsrc/start.c @@ -9,7 +9,7 @@ // with the linker script. //----------------------------------------------------------------------------- -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" extern char __data_start__, __data_src_start__, __data_end__, __bss_start__, __bss_end__; diff --git a/armsrc/string.c b/armsrc/string.c index 945a4cf6..cc71276c 100644 --- a/armsrc/string.c +++ b/armsrc/string.c @@ -48,11 +48,6 @@ int memcmp(const void *av, const void *bv, int len) return 0; } -void memxor(uint8_t * dest, uint8_t * src, size_t len) { - for( ; len > 0; len--,dest++,src++) - *dest ^= *src; -} - int strlen(const char *str) { int l = 0; diff --git a/armsrc/string.h b/armsrc/string.h index 6e2c7883..46ee218d 100644 --- a/armsrc/string.h +++ b/armsrc/string.h @@ -12,14 +12,10 @@ #ifndef __STRING_H #define __STRING_H -#include -#include - int strlen(const char *str); -RAMFUNC void *memcpy(void *dest, const void *src, int len); +void *memcpy(void *dest, const void *src, int len); void *memset(void *dest, int c, int len); -RAMFUNC int memcmp(const void *av, const void *bv, int len); -void memxor(uint8_t * dest, uint8_t * src, size_t len); +int memcmp(const void *av, const void *bv, int len); char *strncat(char *dest, const char *src, unsigned int n); char *strcat(char *dest, const char *src); void strreverse(char s[]); diff --git a/armsrc/util.c b/armsrc/util.c index 0558fb94..5b68f513 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -8,31 +8,11 @@ // Utility functions used in many places, not specific to any piece of code. //----------------------------------------------------------------------------- -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "util.h" #include "string.h" #include "apps.h" - - -void print_result(char *name, uint8_t *buf, size_t len) { - uint8_t *p = buf; - - if ( len % 16 == 0 ) { - for(; p-buf < len; p += 16) - Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", - name, - p-buf, - len, - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15] - ); - } - else { - for(; p-buf < len; p += 8) - Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x", name, p-buf, len, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - } -} - size_t nbytes(size_t nbits) { return (nbits/8)+((nbits%8)>0); } @@ -65,26 +45,6 @@ uint64_t bytes_to_num(uint8_t* src, size_t len) return num; } -// RotateLeft - Ultralight, Desfire -void rol(uint8_t *data, const size_t len){ - uint8_t first = data[0]; - for (size_t i = 0; i < len-1; i++) { - data[i] = data[i+1]; - } - data[len-1] = first; -} -void lsl (uint8_t *data, size_t len) { - for (size_t n = 0; n < len - 1; n++) { - data[n] = (data[n] << 1) | (data[n+1] >> 7); - } - data[len - 1] <<= 1; -} - -int32_t le24toh (uint8_t data[3]) -{ - return (data[2] << 16) | (data[1] << 8) | data[0]; -} - void LEDsoff() { LED_A_OFF(); diff --git a/armsrc/util.h b/armsrc/util.h index c6503395..e8b9cdff 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -13,7 +13,7 @@ #include #include -#include "../include/common.h" +#include #define BYTEx(x, n) (((x) >> (n * 8)) & 0xff ) @@ -27,14 +27,10 @@ #define BUTTON_DOUBLE_CLICK -2 #define BUTTON_ERROR -99 -void print_result(char *name, uint8_t *buf, size_t len); size_t nbytes(size_t nbits); uint32_t SwapBits(uint32_t value, int nrbits); void num_to_bytes(uint64_t n, size_t len, uint8_t* dest); uint64_t bytes_to_num(uint8_t* src, size_t len); -void rol(uint8_t *data, const size_t len); -void lsl (uint8_t *data, size_t len); -int32_t le24toh (uint8_t data[3]); void SpinDelay(int ms); void SpinDelayUs(int us); diff --git a/client/Makefile b/client/Makefile index 83d00260..b2b215e1 100644 --- a/client/Makefile +++ b/client/Makefile @@ -13,14 +13,14 @@ CXX=g++ VPATH = ../common OBJDIR = obj -LDLIBS = -L/mingw/lib -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lm -lreadline -lpthread -lcrypto -lgdi32 +LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread ../liblua/liblua.a LDFLAGS = $(COMMON_FLAGS) -CFLAGS = -std=c99 -I. -I../include -I../common -I/mingw/include -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4 $(ICE_FLAGS) +CFLAGS = -std=c99 -lcrypto -I. -I../include -I../common -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4 LUAPLATFORM = generic ifneq (,$(findstring MINGW,$(platform))) -CXXFLAGS = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui -I$(QTDIR)/include/QtWidgets -I/mingw/include -QTLDLIBS = -L$(QTDIR)/lib -lQt5Core -lQt5Gui -lQt5Widgets +CXXFLAGS = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui +QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4 MOC = $(QTDIR)/bin/moc LUAPLATFORM = mingw else ifeq ($(platform),Darwin) @@ -56,14 +56,13 @@ CORESRCS = uart.c \ CMDSRCS = nonce2key/crapto1.c\ nonce2key/crypto1.c\ nonce2key/nonce2key.c\ - loclass/cipher.c \ - loclass/cipherutils.c \ - loclass/des.c \ - loclass/ikeys.c \ - loclass/elite_crack.c \ - loclass/fileutils.c \ - loclass/hash1_brute.c \ - mifarehost.c \ + loclass/cipher.c \ + loclass/cipherutils.c \ + loclass/des.c \ + loclass/ikeys.c \ + loclass/elite_crack.c\ + loclass/fileutils.c\ + mifarehost.c\ crc16.c \ iso14443crc.c \ iso15693tools.c \ @@ -80,12 +79,8 @@ CMDSRCS = nonce2key/crapto1.c\ cmdhflegic.c \ cmdhficlass.c \ cmdhfmf.c \ - cmdhfmfu.c \ - cmdhfmfdes.c \ - cmdhfdes.c \ cmdhw.c \ cmdlf.c \ - cmdlfawid26.c \ cmdlfio.c \ cmdlfhid.c \ cmdlfem4x.c \ diff --git a/client/cmddata.c b/client/cmddata.c index 9a19dca7..38917a33 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -26,33 +26,37 @@ static int CmdHelp(const char *Cmd); int CmdAmp(const char *Cmd) { - int i, rising, falling; - int max = INT_MIN, min = INT_MAX; + int i, rising, falling; + int max = INT_MIN, min = INT_MAX; - DetectHighLowInGraph( &max, &min, FALSE); + for (i = 10; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] > max) + max = GraphBuffer[i]; + if (GraphBuffer[i] < min) + min = GraphBuffer[i]; + } - if (max != min) { - rising = falling = 0; - - for (i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i + 1] < GraphBuffer[i]) { - if (rising) { - GraphBuffer[i] = max; - rising = 0; - } - falling = 1; - } - if (GraphBuffer[i + 1] > GraphBuffer[i]) { - if (falling) { - GraphBuffer[i] = min; - falling = 0; - } - rising= 1; - } - } - } - RepaintGraphWindow(); - return 0; + if (max != min) { + rising = falling= 0; + for (i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i + 1] < GraphBuffer[i]) { + if (rising) { + GraphBuffer[i] = max; + rising = 0; + } + falling = 1; + } + if (GraphBuffer[i + 1] > GraphBuffer[i]) { + if (falling) { + GraphBuffer[i] = min; + falling = 0; + } + rising= 1; + } + } + } + RepaintGraphWindow(); + return 0; } /* @@ -69,167 +73,171 @@ int CmdAmp(const char *Cmd) //this method is dependant on all highs and lows to be the same(or clipped) this creates issues[marshmellow] it also ignores the clock int Cmdaskdemod(const char *Cmd) { - int i; - int c, high = 0, low = 0; + int i; + int c, high = 0, low = 0; - sscanf(Cmd, "%i", &c); + // TODO: complain if we do not give 2 arguments here ! + // (AL - this doesn't make sense! we're only using one argument!!!) + sscanf(Cmd, "%i", &c); - if (c != 0 && c != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return 0; - } - - DetectHighLowInGraph( &high, &low, FALSE); - - high = abs(high * .75); - low = abs(low * .75); - - //prime loop - if (GraphBuffer[0] > 0) { - GraphBuffer[0] = 1-c; - } else { - GraphBuffer[0] = c; - } - - for (i = 1; i < GraphTraceLen; ++i) { - /* Transitions are detected at each peak - * Transitions are either: - * - we're low: transition if we hit a high - * - we're high: transition if we hit a low - * (we need to do it this way because some tags keep high or - * low for long periods, others just reach the peak and go - * down) - */ + /* Detect high and lows and clock */ + // (AL - clock???) + for (i = 0; i < GraphTraceLen; ++i) + { + if (GraphBuffer[i] > high) + high = GraphBuffer[i]; + else if (GraphBuffer[i] < low) + low = GraphBuffer[i]; + } + high=abs(high*.75); + low=abs(low*.75); + if (c != 0 && c != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + //prime loop + if (GraphBuffer[0] > 0) { + GraphBuffer[0] = 1-c; + } else { + GraphBuffer[0] = c; + } + for (i = 1; i < GraphTraceLen; ++i) { + /* Transitions are detected at each peak + * Transitions are either: + * - we're low: transition if we hit a high + * - we're high: transition if we hit a low + * (we need to do it this way because some tags keep high or + * low for long periods, others just reach the peak and go + * down) + */ //[marhsmellow] change == to >= for high and <= for low for fuzz - if ((GraphBuffer[i] == high) && (GraphBuffer[i - 1] == c)) { - GraphBuffer[i] = 1 - c; - } else if ((GraphBuffer[i] == low) && (GraphBuffer[i - 1] == (1 - c))){ - GraphBuffer[i] = c; - } else { - /* No transition */ - GraphBuffer[i] = GraphBuffer[i - 1]; - } - } + if ((GraphBuffer[i] == high) && (GraphBuffer[i - 1] == c)) { + GraphBuffer[i] = 1 - c; + } else if ((GraphBuffer[i] == low) && (GraphBuffer[i - 1] == (1 - c))){ + GraphBuffer[i] = c; + } else { + /* No transition */ + GraphBuffer[i] = GraphBuffer[i - 1]; + } + } RepaintGraphWindow(); return 0; } -void printBitStream(uint8_t bits[], uint32_t bitLen){ - - uint32_t i = 0; - if (bitLen < 16) { - PrintAndLog("Too few bits found: %d",bitLen); - return; - } - if (bitLen > 512) - bitLen = 512; - - if ( ( bitLen % 16 ) > 0) { - bitLen = ((bitLen / 16) * 16); - PrintAndLog("ICE: equally divided with 16 = %d",bitLen); - } - - for (i = 0; i <= ( bitLen - 16); i += 16) { - PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", - bits[i], - bits[i+1], - bits[i+2], - bits[i+3], - bits[i+4], - bits[i+5], - bits[i+6], - bits[i+7], - bits[i+8], - bits[i+9], - bits[i+10], - bits[i+11], - bits[i+12], - bits[i+13], - bits[i+14], - bits[i+15]); - } +//by marshmellow +void printBitStream(uint8_t BitStream[], uint32_t bitLen) +{ + uint32_t i = 0; + if (bitLen<16) { + PrintAndLog("Too few bits found: %d",bitLen); + return; + } + if (bitLen>512) bitLen=512; + for (i = 0; i <= (bitLen-16); i+=16) { + PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", + BitStream[i], + BitStream[i+1], + BitStream[i+2], + BitStream[i+3], + BitStream[i+4], + BitStream[i+5], + BitStream[i+6], + BitStream[i+7], + BitStream[i+8], + BitStream[i+9], + BitStream[i+10], + BitStream[i+11], + BitStream[i+12], + BitStream[i+13], + BitStream[i+14], + BitStream[i+15]); + } return; } - -void printEM410x(uint64_t id) { - - if ( id <= 0 ) return; - - uint64_t id2lo = 0; - uint32_t i,j; - i = j = 0; - - for (j = 5; j > 0; j--){ - for (i = 0; i < 8; i++){ - id2lo = ( id2lo << 1LL)|((id & ( 1 << ( i +( ( j-1 ) * 8 )))) >> ( i + (( j-1) *8 ))); - } - } - //output em id - PrintAndLog("EM TAG ID : %010llx", id); - PrintAndLog("Unique TAG ID: %010llx", id2lo); - PrintAndLog("DEZ 8 : %08lld", id & 0xFFFFFF); - PrintAndLog("DEZ 10 : %010lld", id & 0xFFFFFF); - PrintAndLog("DEZ 5.5 : %05lld.%05lld", (id>>16LL) & 0xFFFF, (id & 0xFFFF)); - PrintAndLog("DEZ 3.5A : %03lld.%05lld", (id>>32ll), (id & 0xFFFF)); - PrintAndLog("DEZ 14/IK2 : %014lld", id); - PrintAndLog("DEZ 15/IK3 : %015lld", id2lo); - PrintAndLog("Other : %05lld_%03lld_%08lld", (id & 0xFFFF), (( id >> 16LL) & 0xFF), (id & 0xFFFFFF)); -} - -int CmdEm410xDecode(const char *Cmd) +//by marshmellow +void printEM410x(uint64_t id) { - uint64_t id = 0; - uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0x00}; - uint32_t len = GetFromGraphBuf(bits); - id = Em410xDecode(bits, len); - printEM410x(id); - if ( id > 0 ) - return 1; - return 0; + if (id !=0){ + uint64_t iii=1; + uint64_t id2lo=0; //id2hi=0, + uint32_t ii=0; + uint32_t i=0; + for (ii=5; ii>0;ii--){ + for (i=0;i<8;i++){ + id2lo=(id2lo<<1LL)|((id & (iii<<(i+((ii-1)*8))))>>(i+((ii-1)*8))); + } + } + //output em id + PrintAndLog("EM TAG ID : %010llx", id); + PrintAndLog("Unique TAG ID: %010llx", id2lo); //id2hi, + PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF); + PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF); + PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF)); + PrintAndLog("DEZ 3.5A : %03lld.%05lld",(id>>32ll),(id & 0xFFFF)); + PrintAndLog("DEZ 14/IK2 : %014lld",id); + PrintAndLog("DEZ 15/IK3 : %015lld",id2lo); + PrintAndLog("Other : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF)); + } + return; } //by marshmellow -//takes 2 arguments - clock and invert both as integers +int CmdEm410xDecode(const char *Cmd) +{ + uint64_t id=0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + uint32_t i=0; + i=getFromGraphBuf(BitStream); + id = Em410xDecode(BitStream,i); + printEM410x(id); + if (id>0) return 1; + return 0; +} + + +//by marshmellow +//takes 2 arguments - clock and invert both as integers //attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands int Cmdaskmandemod(const char *Cmd) { - int invert = 0; - int clk = 0; - - sscanf(Cmd, "%i %i", &clk, &invert); - - if (invert != 0 && invert != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return 0; - } + int invert=0; + int clk=0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + sscanf(Cmd, "%i %i", &clk, &invert); + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + uint32_t BitLen = getFromGraphBuf(BitStream); + // PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); + int errCnt=0; + errCnt = askmandemod(BitStream, &BitLen,&clk,&invert); + if (errCnt<0){ //if fatal error (or -1) + // PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk); + return 0; + } + if (BitLen<16) return 0; + PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen); - uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0x00}; - uint32_t len = GetFromGraphBuf(bits); - - int errCnt = askmandemod(bits, &len, &clk, &invert); - - if (errCnt < 0) return 0; - if (len < 16) return 0; - - PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,len); - - if (errCnt > 0){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - } - - PrintAndLog("ASK/Manchester decoded bitstream:"); - - printBitStream(bits, len); - - uint64_t tagid = Em410xDecode(bits, len); - - if (tagid > 0){ - SetGraphBuf(bits, len); - printEM410x(tagid); - return 1; - } - return 0; + //output + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + } + PrintAndLog("ASK/Manchester decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printBitStream(BitStream,BitLen); + uint64_t lo =0; + lo = Em410xDecode(BitStream,BitLen); + if (lo>0){ + //set GraphBuffer for clone or sim command + setGraphBuf(BitStream,BitLen); + PrintAndLog("EM410x pattern found: "); + printEM410x(lo); + return 1; + } + //if (BitLen>16) return 1; + return 0; } //by marshmellow @@ -237,42 +245,41 @@ int Cmdaskmandemod(const char *Cmd) //stricktly take 10 and 01 and convert to 0 and 1 int Cmdmandecoderaw(const char *Cmd) { - int i = 0; - int errCnt = 0; - int bitnum = 0; - uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0x00}; - int high = 0, low = 0; - - for (; i < GraphTraceLen; ++i){ - if (GraphBuffer[i] > high) high = GraphBuffer[i]; - else if (GraphBuffer[i] < low) low = GraphBuffer[i]; - bits[i] = GraphBuffer[i]; - } - - if (high > 1 || low < 0 ){ - PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode"); - return 0; - } - - bitnum = i; - errCnt = manrawdecode(bits, &bitnum); - - if (errCnt>=20){ - PrintAndLog("Too many errors: %d",errCnt); - return 0; - } - - PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt); - printBitStream(bits,bitnum); - - if (errCnt==0){ - //put back in graphbuffer - SetGraphBuf(bits, bitnum); - - uint64_t id = Em410xDecode(bits,i); - printEM410x(id); - } - return 1; + int i =0; + int errCnt=0; + int bitnum=0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + int high=0,low=0; + for (;ihigh) high=GraphBuffer[i]; + else if(GraphBuffer[i]1 || low <0 ){ + PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode"); + return 0; + } + bitnum=i; + errCnt=manrawdecode(BitStream,&bitnum); + if (errCnt>=20){ + PrintAndLog("Too many errors: %d",errCnt); + return 0; + } + PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt); + printBitStream(BitStream,bitnum); + if (errCnt==0){ + //put back in graphbuffer + ClearGraph(0); + for (i=0; i high) high = GraphBuffer[i]; - else if (GraphBuffer[i] < low) low = GraphBuffer[i]; - bits[i] = GraphBuffer[i]; - } - if (high > 1 || low < 0){ - PrintAndLog("Error: please raw demod the wave first then decode"); - return 0; - } - bitnum = i; - errCnt = BiphaseRawDecode(bits, &bitnum, offset); - if (errCnt >= 20){ - PrintAndLog("Too many errors attempting to decode: %d", errCnt); - return 0; - } - PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:", offset, errCnt); - printBitStream(bits, bitnum); - PrintAndLog("\nif bitstream does not look right try offset=1"); - return 1; + int i = 0; + int errCnt=0; + int bitnum=0; + int offset=0; + int high=0, low=0; + sscanf(Cmd, "%i", &offset); + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + //get graphbuffer & high and low + for (;ihigh)high=GraphBuffer[i]; + else if(GraphBuffer[i]1 || low <0){ + PrintAndLog("Error: please raw demod the wave first then decode"); + return 0; + } + bitnum=i; + errCnt=BiphaseRawDecode(BitStream,&bitnum, offset); + if (errCnt>=20){ + PrintAndLog("Too many errors attempting to decode: %d",errCnt); + return 0; + } + PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt); + printBitStream(BitStream,bitnum); + PrintAndLog("\nif bitstream does not look right try offset=1"); + return 1; } @@ -324,49 +329,38 @@ int CmdBiphaseDecodeRaw(const char *Cmd) //prints binary found and saves in graphbuffer for further commands int Cmdaskrawdemod(const char *Cmd) { - int invert = 0; - int clk = 0; - - sscanf(Cmd, "%i %i", &clk, &invert); - - if (invert != 0 && invert != 1 ) { - PrintAndLog("Invalid argument: %s", Cmd); - return 0; - } + + int invert=0; + int clk=0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + sscanf(Cmd, "%i %i", &clk, &invert); + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + int BitLen = getFromGraphBuf(BitStream); + int errCnt=0; + errCnt = askrawdemod(BitStream, &BitLen, &clk, &invert); + if (errCnt==-1){ //throw away static - allow 1 and -1 (in case of threshold command first) + PrintAndLog("no data found"); + return 0; + } + if (BitLen<16) return 0; + PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); + //move BitStream back to GraphBuffer + setGraphBuf(BitStream, BitLen); - if ( clock < 0 ) { - PrintAndLog("Wrong clock argument"); - return 0; - } + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + } - uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0x00}; - int len = GetFromGraphBuf(bits); - int errCnt = 0; - - errCnt = askrawdemod(bits, &len, &clk, &invert); + PrintAndLog("ASK demoded bitstream:"); - //throw away static - allow 1 and -1 (in case of threshold command first) - if (errCnt == -1) { - PrintAndLog("no data found"); - return 0; - } - - if (len < 16) return 0; - - PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,len); - - //move BitStream back to GraphBuffer - SetGraphBuf(bits, len); - - if (errCnt > 0){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - } - - PrintAndLog("ASK demoded bitstream:"); - - // Now output the bitstream to the scrollback by line of 16 bits - printBitStream(bits,len); - return 1; + // Now output the bitstream to the scrollback by line of 16 bits + printBitStream(BitStream,BitLen); + + return 1; } int CmdAutoCorr(const char *Cmd) @@ -404,7 +398,7 @@ int CmdAutoCorr(const char *Cmd) int CmdBitsamples(const char *Cmd) { int cnt = 0; - uint8_t got[10000]; + uint8_t got[12288]; GetFromBigBuf(got,sizeof(got),0); WaitForResponse(CMD_ACK,NULL); @@ -437,10 +431,16 @@ int CmdBitstream(const char *Cmd) int hithigh, hitlow, first; /* Detect high and lows and clock */ - DetectHighLowInGraph( &high, &low, FALSE); + for (i = 0; i < GraphTraceLen; ++i) + { + if (GraphBuffer[i] > high) + high = GraphBuffer[i]; + else if (GraphBuffer[i] < low) + low = GraphBuffer[i]; + } /* Get our clock */ - clock = GetClock(Cmd, 0); + clock = GetClock(Cmd, high, 1); gtl = ClearGraph(0); bit = 0; @@ -500,7 +500,7 @@ int CmdDec(const char *Cmd) // uses data from graphbuffer int CmdDetectClockRate(const char *Cmd) { - GetClock("",1); + GetClock("",0,0); return 0; } @@ -510,48 +510,43 @@ int CmdDetectClockRate(const char *Cmd) //defaults: clock = 50, invert=0, rchigh=10, rclow=8 (RF/10 RF/8 (fsk2a)) int CmdFSKrawdemod(const char *Cmd) { - //raw fsk demod no manchester decoding no start bit finding just get binary from wave - int rfLen = 50; - int invert = 0; - int fchigh = 10; - int fclow = 8; - - //set options from parameters entered with the command - sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow); + //raw fsk demod no manchester decoding no start bit finding just get binary from wave + //set defaults + int rfLen = 50; + int invert=0; + int fchigh=10; + int fclow=8; + //set options from parameters entered with the command + sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow); - // A lots of checks if chigh, clow is out-of bounds. - - if (strlen(Cmd)>0 && strlen(Cmd)<=2) { - - rfLen = 50; - - //if invert option only is used - if (rfLen == 1){ - invert=1; - } - } - - PrintAndLog("Args invert: %d - Clock:%d - FC high:%d - FC low: %d",invert,rfLen,fchigh, fclow); - - uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0x00}; - uint32_t len = GetFromGraphBuf(bits); - - int size = fskdemod(bits, len,(uint8_t)rfLen, (uint8_t)invert, (uint8_t)fchigh, (uint8_t)fclow); - - if (size > 0) { - PrintAndLog("FSK decoded bitstream:"); - - SetGraphBuf(bits, size); - - // Now output the bitstream to the scrollback by line of 16 bits - // only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size - if(size > (8*32)+2) - size = (8*32)+2; - printBitStream(bits,size); - } else { - PrintAndLog("no FSK data found"); - } - return 0; + if (strlen(Cmd)>0 && strlen(Cmd)<=2) { + //rfLen=param_get8(Cmd, 0); //if rfLen option only is used + if (rfLen==1){ + invert=1; //if invert option only is used + rfLen = 50; + } else if(rfLen==0) rfLen=50; + } + PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow); + uint32_t i=0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + uint32_t BitLen = getFromGraphBuf(BitStream); + int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow); + if (size>0){ + PrintAndLog("FSK decoded bitstream:"); + ClearGraph(0); + for (i=0;i (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size + printBitStream(BitStream,size); + } else{ + PrintAndLog("no FSK data found"); + } + return 0; } //by marshmellow (based on existing demod + holiman's refactor) @@ -559,91 +554,72 @@ int CmdFSKrawdemod(const char *Cmd) //print full HID Prox ID and some bit format details if found int CmdFSKdemodHID(const char *Cmd) { - //raw fsk demod no manchester decoding no start bit finding just get binary from wave - uint32_t hi2=0, hi=0, lo=0; + //raw fsk demod no manchester decoding no start bit finding just get binary from wave + uint32_t hi2=0, hi=0, lo=0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0x00}; - uint32_t BitLen = GetFromGraphBuf(BitStream); - - //get binary from fsk wave - size_t size = HIDdemodFSK(BitStream,BitLen,&hi2,&hi,&lo); - - if (size < 0){ - PrintAndLog("Error demoding fsk"); - return 0; - } - - if (hi2==0 && hi==0 && lo==0) return 0; - - //extra large HID tags - if (hi2 != 0){ - PrintAndLog("TAG ID: %x%08x%08x (%d)", - (unsigned int) hi2, - (unsigned int) hi, - (unsigned int) lo, - (unsigned int) (lo>>1) & 0xFFFF); - SetGraphBuf(BitStream,BitLen); - return 1; - } else { - //standard HID tags <38 bits - uint8_t fmtLen = 0; - uint32_t fc = 0; - uint32_t cardnum = 0; - - //if bit 38 is set then < 37 bit format is used - if (((hi>>5) & 1)==1){ - uint32_t lo2 = 0; - - //get bits 21-37 to check for format len bit - lo2 = (((hi & 15) << 12) | (lo>>20)); - uint8_t idx3 = 1; - - //find last bit set to 1 (format len bit) - while( lo2 > 1){ - lo2=lo2>>1; - idx3++; - } - fmtLen = idx3 + 19; - fc = 0; - cardnum = 0; - - if(fmtLen==26){ - cardnum = (lo>>1)&0xFFFF; - fc = (lo>>17)&0xFF; - } - if(fmtLen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - if(fmtLen==34){ - cardnum = (lo>>1)&0xFFFF; - fc= ((hi&1)<<15)|(lo>>17); - } - if(fmtLen==35){ - cardnum = (lo>>1)&0xFFFFF; - fc = ((hi&1)<<11)|(lo>>21); - } - } else { - //if bit 38 is not set then 37 bit format is used - fmtLen= 37; - fc =0; - cardnum=0; - - if (fmtLen==37){ - cardnum = (lo>>1) & 0x7FFFF; - fc = ((hi&0xF) << 12) | (lo >> 20); - } - } - PrintAndLog("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", - (unsigned int) hi, - (unsigned int) lo, - (unsigned int) (lo>>1) & 0xFFFF, - (unsigned int) fmtLen, - (unsigned int) fc, - (unsigned int) cardnum); - SetGraphBuf(BitStream,BitLen); + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + uint32_t BitLen = getFromGraphBuf(BitStream); + //get binary from fsk wave + size_t size = HIDdemodFSK(BitStream,BitLen,&hi2,&hi,&lo); + if (size<0){ + PrintAndLog("Error demoding fsk"); + return 0; + } + if (hi2==0 && hi==0 && lo==0) return 0; + if (hi2 != 0){ //extra large HID tags + PrintAndLog("TAG ID: %x%08x%08x (%d)", + (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + setGraphBuf(BitStream,BitLen); return 1; - } + } + else { //standard HID tags <38 bits + //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd + uint8_t fmtLen = 0; + uint32_t fc = 0; + uint32_t cardnum = 0; + if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used + uint32_t lo2=0; + lo2=(((hi & 15) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit + uint8_t idx3 = 1; + while(lo2>1){ //find last bit set to 1 (format len bit) + lo2=lo2>>1; + idx3++; + } + fmtLen =idx3+19; + fc =0; + cardnum=0; + if(fmtLen==26){ + cardnum = (lo>>1)&0xFFFF; + fc = (lo>>17)&0xFF; + } + if(fmtLen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + if(fmtLen==34){ + cardnum = (lo>>1)&0xFFFF; + fc= ((hi&1)<<15)|(lo>>17); + } + if(fmtLen==35){ + cardnum = (lo>>1)&0xFFFFF; + fc = ((hi&1)<<11)|(lo>>21); + } + } + else { //if bit 38 is not set then 37 bit format is used + fmtLen= 37; + fc =0; + cardnum=0; + if(fmtLen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + } + PrintAndLog("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, + (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum); + setGraphBuf(BitStream,BitLen); + return 1; + } return 0; } @@ -652,67 +628,54 @@ int CmdFSKdemodHID(const char *Cmd) //print ioprox ID and some format details int CmdFSKdemodIO(const char *Cmd) { - if (GraphTraceLen < 65) { - PrintAndLog("data samples size is too small"); - return 0; - } + //raw fsk demod no manchester decoding no start bit finding just get binary from wave + //set defaults + int idx=0; + //something in graphbuffer + if (GraphTraceLen < 65) return 0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + uint32_t BitLen = getFromGraphBuf(BitStream); + //get binary from fsk wave + // PrintAndLog("DEBUG: got buff"); + idx = IOdemodFSK(BitStream,BitLen); + if (idx<0){ + //PrintAndLog("Error demoding fsk"); + return 0; + } + // PrintAndLog("DEBUG: Got IOdemodFSK"); + if (idx==0){ + //PrintAndLog("IO Prox Data not found - FSK Data:"); + //if (BitLen > 92) printBitStream(BitStream,92); + return 0; + } + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- + //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 + // + //XSF(version)facility:codeone+codetwo (raw) + //Handle the data + if (idx+64>BitLen) return 0; + PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx], BitStream[idx+1], BitStream[idx+2], BitStream[idx+3], BitStream[idx+4], BitStream[idx+5], BitStream[idx+6], BitStream[idx+7], BitStream[idx+8]); + PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx+9], BitStream[idx+10], BitStream[idx+11],BitStream[idx+12],BitStream[idx+13],BitStream[idx+14],BitStream[idx+15],BitStream[idx+16],BitStream[idx+17]); + PrintAndLog("%d%d%d%d%d%d%d%d %d facility",BitStream[idx+18], BitStream[idx+19], BitStream[idx+20],BitStream[idx+21],BitStream[idx+22],BitStream[idx+23],BitStream[idx+24],BitStream[idx+25],BitStream[idx+26]); + PrintAndLog("%d%d%d%d%d%d%d%d %d version",BitStream[idx+27], BitStream[idx+28], BitStream[idx+29],BitStream[idx+30],BitStream[idx+31],BitStream[idx+32],BitStream[idx+33],BitStream[idx+34],BitStream[idx+35]); + PrintAndLog("%d%d%d%d%d%d%d%d %d code1",BitStream[idx+36], BitStream[idx+37], BitStream[idx+38],BitStream[idx+39],BitStream[idx+40],BitStream[idx+41],BitStream[idx+42],BitStream[idx+43],BitStream[idx+44]); + PrintAndLog("%d%d%d%d%d%d%d%d %d code2",BitStream[idx+45], BitStream[idx+46], BitStream[idx+47],BitStream[idx+48],BitStream[idx+49],BitStream[idx+50],BitStream[idx+51],BitStream[idx+52],BitStream[idx+53]); + PrintAndLog("%d%d%d%d%d%d%d%d %d%d checksum",BitStream[idx+54],BitStream[idx+55],BitStream[idx+56],BitStream[idx+57],BitStream[idx+58],BitStream[idx+59],BitStream[idx+60],BitStream[idx+61],BitStream[idx+62],BitStream[idx+63]); - //raw fsk demod no manchester decoding no start bit finding just get binary from wave - //set defaults - int idx = 0; - uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0x00}; - uint32_t bitlen = GetFromGraphBuf(bits); - - //get binary from fsk wave - idx = IOdemodFSK(bits, bitlen); + uint32_t code = bytebits_to_byte(BitStream+idx,32); + uint32_t code2 = bytebits_to_byte(BitStream+idx+32,32); + uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4 + uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ; + uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9 - if (idx == 0) { - return 0; - } - if (idx == -1) { - PrintAndLog("data samples size is too small"); - return 0; - } - if (idx == -2) { - PrintAndLog("Data samples has too much noice"); - return 0; - } - if (idx == -3){ - PrintAndLog("No good demod"); - return 0; - } - - if (idx+64 > bitlen) return 0; - - //Index map - //0 10 20 30 40 50 60 - //| | | | | | | - //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 - //----------------------------------------------------------------------------- - //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 - // - //XSF(version)facility:codeone+codetwo (raw) - //Handle the data - - PrintAndLog("%d%d%d%d%d%d%d%d %d", bits[idx] , bits[idx+1], bits[idx+2], bits[idx+3], bits[idx+4], bits[idx+5], bits[idx+6], bits[idx+7], bits[idx+8]); - PrintAndLog("%d%d%d%d%d%d%d%d %d", bits[idx+9] , bits[idx+10], bits[idx+11], bits[idx+12], bits[idx+13], bits[idx+14], bits[idx+15], bits[idx+16], bits[idx+17]); - PrintAndLog("%d%d%d%d%d%d%d%d %d facility", bits[idx+18], bits[idx+19], bits[idx+20], bits[idx+21], bits[idx+22], bits[idx+23], bits[idx+24], bits[idx+25], bits[idx+26]); - PrintAndLog("%d%d%d%d%d%d%d%d %d version", bits[idx+27], bits[idx+28], bits[idx+29], bits[idx+30], bits[idx+31], bits[idx+32], bits[idx+33], bits[idx+34], bits[idx+35]); - PrintAndLog("%d%d%d%d%d%d%d%d %d code1", bits[idx+36], bits[idx+37], bits[idx+38], bits[idx+39], bits[idx+40], bits[idx+41], bits[idx+42], bits[idx+43], bits[idx+44]); - PrintAndLog("%d%d%d%d%d%d%d%d %d code2", bits[idx+45], bits[idx+46], bits[idx+47], bits[idx+48], bits[idx+49], bits[idx+50], bits[idx+51], bits[idx+52], bits[idx+53]); - PrintAndLog("%d%d%d%d%d%d%d%d %d%d checksum", bits[idx+54], bits[idx+55], bits[idx+56], bits[idx+57], bits[idx+58], bits[idx+59], bits[idx+60], bits[idx+61], bits[idx+62], bits[idx+63]); - - uint32_t code = bytebits_to_byte(bits+idx,32); - uint32_t code2 = bytebits_to_byte(bits+idx+32,32); - uint8_t version = bytebits_to_byte(bits+idx+27,8); //14,4 - uint8_t facilitycode = bytebits_to_byte(bits+idx+18,8) ; - uint16_t number = (bytebits_to_byte(bits+idx+36,8)<<8)|(bytebits_to_byte(bits+idx+45,8)); //36,9 - - PrintAndLog("XSF(%02d)%02x:%05d (%08x%08x)", version, facilitycode, number, code, code2); - SetGraphBuf(bits, bitlen); - return 1; + PrintAndLog("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); + setGraphBuf(BitStream,BitLen); + return 1; } - int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating { static const int LowTone[] = { @@ -733,12 +696,12 @@ int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating int lowLen = sizeof (LowTone) / sizeof (int); int highLen = sizeof (HighTone) / sizeof (int); - int convLen = (highLen > lowLen) ? highLen : lowLen; + int convLen = (highLen > lowLen) ? highLen : lowLen; //if highlen > lowLen then highlen else lowlen uint32_t hi = 0, lo = 0; int i, j; int minMark = 0, maxMark = 0; - + for (i = 0; i < GraphTraceLen - convLen; ++i) { int lowSum = 0, highSum = 0; @@ -916,81 +879,43 @@ int CmdSamples(const char *Cmd) n = sizeof(got); PrintAndLog("Reading %d samples from device memory\n", n); - GetFromBigBuf(got,n,0); - WaitForResponse(CMD_ACK,NULL); + GetFromBigBuf(got,n,0); + WaitForResponse(CMD_ACK,NULL); for (int j = 0; j < n; ++j) { GraphBuffer[j] = ((int)got[j]) - 128; - } - GraphTraceLen = n; - RepaintGraphWindow(); - return 0; + } + GraphTraceLen = n; + RepaintGraphWindow(); + return 0; } int CmdTuneSamples(const char *Cmd) { - int timeout = 0; - printf("\nMeasuring antenna characteristics, please wait..."); + int cnt = 0; + int n = 255; + uint8_t got[255]; - UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING}; - SendCommand(&c); - - UsbCommand resp; - while(!WaitForResponseTimeout(CMD_MEASURED_ANTENNA_TUNING,&resp,1000)) { - timeout++; - printf("."); - if (timeout > 7) { - PrintAndLog("\nNo response from Proxmark. Aborting..."); - return 1; - } - } - - int peakv, peakf; - int vLf125, vLf134, vHf; - vLf125 = resp.arg[0] & 0xffff; - vLf134 = resp.arg[0] >> 16; - vHf = resp.arg[1] & 0xffff;; - peakf = resp.arg[2] & 0xffff; - peakv = resp.arg[2] >> 16; - PrintAndLog(""); - PrintAndLog("# LF antenna: %5.2f V @ 125.00 kHz", vLf125/1000.0); - PrintAndLog("# LF antenna: %5.2f V @ 134.00 kHz", vLf134/1000.0); - PrintAndLog("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1)); - PrintAndLog("# HF antenna: %5.2f V @ 13.56 MHz", vHf/1000.0); - if (peakv<2000) - PrintAndLog("# Your LF antenna is unusable."); - else if (peakv<10000) - PrintAndLog("# Your LF antenna is marginal."); - if (vHf<2000) - PrintAndLog("# Your HF antenna is unusable."); - else if (vHf<5000) - PrintAndLog("# Your HF antenna is marginal."); - - for (int i = 0; i < 256; i++) { - GraphBuffer[i] = resp.d.asBytes[i] - 128; - } + PrintAndLog("Reading %d samples\n", n); + GetFromBigBuf(got,n,7256); // armsrc/apps.h: #define FREE_BUFFER_OFFSET 7256 + WaitForResponse(CMD_ACK,NULL); + for (int j = 0; j < n; j++) { + GraphBuffer[cnt++] = ((int)got[j]) - 128; + } - PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n"); - PrintAndLog("\n"); - GraphTraceLen = 256; - ShowGraphWindow(); - + PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n"); + PrintAndLog("\n"); + GraphTraceLen = n; + RepaintGraphWindow(); return 0; } int CmdLoad(const char *Cmd) { - char filename[FILE_PATH_SIZE] = {0x00}; - int len = 0; - - len = strlen(Cmd); - if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; - memcpy(filename, Cmd, len); - - FILE *f = fopen(filename, "r"); - if (!f) { - PrintAndLog("couldn't open '%s'", filename); - return 0; - } + FILE *f = fopen(Cmd, "r"); + if (!f) { + PrintAndLog("couldn't open '%s'", Cmd); + return 0; + } GraphTraceLen = 0; char line[80]; @@ -1070,13 +995,20 @@ int CmdManchesterDemod(const char *Cmd) /* But it does not work if compiling on WIndows: therefore we just allocate a */ /* large array */ - uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0x00}; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0}; /* Detect high and lows */ - DetectHighLowInGraph( &high, &low, TRUE); - + for (i = 0; i < GraphTraceLen; i++) + { + if (GraphBuffer[i] > high) + high = GraphBuffer[i]; + else if (GraphBuffer[i] < low) + low = GraphBuffer[i]; + } + /* Get our clock */ - clock = GetClock(Cmd, 0); + clock = GetClock(Cmd, high, 1); + int tolerance = clock/4; /* Detect first transition */ @@ -1094,14 +1026,14 @@ int CmdManchesterDemod(const char *Cmd) break; } } - + /* If we're not working with 1/0s, demod based off clock */ if (high != 1) { bit = 0; /* We assume the 1st bit is zero, it may not be * the case: this routine (I think) has an init problem. * Ed. - */ + */ for (; i < (int)(GraphTraceLen / clock); i++) { hithigh = 0; @@ -1144,30 +1076,30 @@ int CmdManchesterDemod(const char *Cmd) { if (GraphBuffer[i-1] != GraphBuffer[i]) { - lc = i-lastval; - lastval = i; + lc = i-lastval; + lastval = i; - // Error check: if bitidx becomes too large, we do not - // have a Manchester encoded bitstream or the clock is really - // wrong! - if (bitidx > (GraphTraceLen*2/clock+8) ) { - PrintAndLog("Error: the clock you gave is probably wrong, aborting."); - return 0; - } - // Then switch depending on lc length: - // Tolerance is 1/4 of clock rate (arbitrary) - if (abs(lc-clock/2) < tolerance) { - // Short pulse : either "1" or "0" - BitStream[bitidx++]=GraphBuffer[i-1]; - } else if (abs(lc-clock) < tolerance) { - // Long pulse: either "11" or "00" - BitStream[bitidx++]=GraphBuffer[i-1]; - BitStream[bitidx++]=GraphBuffer[i-1]; - } else { + // Error check: if bitidx becomes too large, we do not + // have a Manchester encoded bitstream or the clock is really + // wrong! + if (bitidx > (GraphTraceLen*2/clock+8) ) { + PrintAndLog("Error: the clock you gave is probably wrong, aborting."); + return 0; + } + // Then switch depending on lc length: + // Tolerance is 1/4 of clock rate (arbitrary) + if (abs(lc-clock/2) < tolerance) { + // Short pulse : either "1" or "0" + BitStream[bitidx++]=GraphBuffer[i-1]; + } else if (abs(lc-clock) < tolerance) { + // Long pulse: either "11" or "00" + BitStream[bitidx++]=GraphBuffer[i-1]; + BitStream[bitidx++]=GraphBuffer[i-1]; + } else { // Error warnings++; - PrintAndLog("Warning: Manchester decode error for pulse width detection."); - PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)"); + PrintAndLog("Warning: Manchester decode error for pulse width detection."); + PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)"); if (warnings > 10) { @@ -1181,20 +1113,18 @@ int CmdManchesterDemod(const char *Cmd) // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful // to stop output at the final bitidx2 value, not bitidx - - //http://www.proxmark.org/forum/viewtopic.php?id=403 - for (i = 1; i < bitidx; i += 2) { + for (i = 0; i < bitidx; i += 2) { if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) { BitStream[bit2idx++] = 1 ^ invert; - } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) { - BitStream[bit2idx++] = 0 ^ invert; - } else { - // We cannot end up in this state, this means we are unsynchronized, - // move up 1 bit: - i++; - warnings++; - PrintAndLog("Unsynchronized, resync..."); - PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)"); + } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) { + BitStream[bit2idx++] = 0 ^ invert; + } else { + // We cannot end up in this state, this means we are unsynchronized, + // move up 1 bit: + i++; + warnings++; + PrintAndLog("Unsynchronized, resync..."); + PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)"); if (warnings > 10) { @@ -1226,27 +1156,28 @@ int CmdManchesterDemod(const char *Cmd) BitStream[i+14], BitStream[i+15]); } - return bit2idx; + return 0; } /* Modulate our data into manchester */ int CmdManchesterMod(const char *Cmd) { int i, j; + int clock; int bit, lastbit, wave; - int clock = GetClock(Cmd, 0); - - int half = (int)(clock/2); - + + /* Get our clock */ + clock = GetClock(Cmd, 0, 1); + wave = 0; lastbit = 1; for (i = 0; i < (int)(GraphTraceLen / clock); i++) { bit = GraphBuffer[i * clock] ^ 1; - for (j = 0; j < half; ++j) + for (j = 0; j < (int)(clock/2); j++) GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave; - for (j = half; j < clock; ++j) + for (j = (int)(clock/2); j < clock; j++) GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1; /* Keep track of how we start our wave and if we changed or not this time */ @@ -1288,17 +1219,9 @@ int CmdPlot(const char *Cmd) int CmdSave(const char *Cmd) { - char filename[FILE_PATH_SIZE] = {0x00}; - int len = 0; - - len = strlen(Cmd); - if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; - memcpy(filename, Cmd, len); - - - FILE *f = fopen(filename, "w"); + FILE *f = fopen(Cmd, "w"); if(!f) { - PrintAndLog("couldn't open '%s'", filename); + PrintAndLog("couldn't open '%s'", Cmd); return 0; } int i; @@ -1413,8 +1336,6 @@ static command_t CommandTable[] = {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, {"dec", CmdDec, 1, "Decimate samples"}, {"detectaskclock",CmdDetectClockRate, 1, "Detect ASK clock rate"}, - {"dirthreshold", CmdDirectionalThreshold, 1, " -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."}, - {"em4xdecode", CmdEm410xDecode, 1, "decode em4x from graph buffer"}, {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"}, {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"}, @@ -1432,11 +1353,12 @@ static command_t CommandTable[] = {"norm", CmdNorm, 1, "Normalize max/min to +/-500"}, {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"}, + {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"}, {"save", CmdSave, 1, " -- Save trace (from graph window)"}, {"scale", CmdScale, 1, " -- Set cursor display scale"}, {"threshold", CmdThreshold, 1, " -- Maximize/minimize every value in the graph window depending on threshold"}, - {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"}, {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, + {"dirthreshold", CmdDirectionalThreshold, 1, " -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmddata.h b/client/cmddata.h index 59ac43b9..999e6438 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -43,10 +43,11 @@ int CmdManchesterMod(const char *Cmd); int CmdNorm(const char *Cmd); int CmdPlot(const char *Cmd); int CmdSamples(const char *Cmd); +int CmdTuneSamples(const char *Cmd); int CmdSave(const char *Cmd); int CmdScale(const char *Cmd); int CmdThreshold(const char *Cmd); int CmdDirectionalThreshold(const char *Cmd); int CmdZerocrossings(const char *Cmd); -int CmdTuneSamples(const char *Cmd); + #endif diff --git a/client/cmdhf.c b/client/cmdhf.c index 0ed3f013..550f8e86 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -22,9 +22,6 @@ #include "cmdhflegic.h" #include "cmdhficlass.h" #include "cmdhfmf.h" -#include "cmdhfmfu.h" -#include "cmdhfmfdes.h" -#include "cmdhfdes.h" static int CmdHelp(const char *Cmd); @@ -317,13 +314,10 @@ static command_t CommandTable[] = {"epa", CmdHFEPA, 1, "{ German Identification Card... }"}, {"legic", CmdHFLegic, 0, "{ LEGIC RFIDs... }"}, {"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"}, - {"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"}, - {"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"}, - {"mfdes", CmdHFMFDes, 1, "{ MIFARE Desfire RFIDs... }"}, - {"des", CmdHFDES, 0, "{ MIFARE DESfire}"}, + {"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"}, {"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"}, {"list", CmdHFList, 1, "List protocol data in trace buffer"}, - {NULL, NULL, 0, NULL} + {NULL, NULL, 0, NULL} }; int CmdHF(const char *Cmd) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 62d95b4b..673737e2 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -14,150 +14,22 @@ #include #include #include "util.h" -#include "../common/iso14443crc.h" +#include "iso14443crc.h" #include "data.h" #include "proxmark3.h" #include "ui.h" #include "cmdparser.h" #include "cmdhf14a.h" -#include "../include/common.h" +#include "common.h" #include "cmdmain.h" -#include "../include/mifare.h" +#include "mifare.h" static int CmdHelp(const char *Cmd); static void waitCmd(uint8_t iLen); int CmdHF14AList(const char *Cmd) { - bool ShowWaitCycles = false; - char param = param_getchar(Cmd, 0); - - if (param == 'h' || (param != 0 && param != 'f')) { - PrintAndLog("List data in trace buffer."); - PrintAndLog("Usage: hf 14a list [f]"); - PrintAndLog("f - show frame delay times as well"); - PrintAndLog("sample: hf 14a list f"); - return 0; - } - - ShowWaitCycles = (param == 'f'); - -// for the time being. Need better Bigbuf handling. -#define TRACE_SIZE 3000 - - uint8_t trace[TRACE_SIZE]; - GetFromBigBuf(trace, TRACE_SIZE, 0); - WaitForResponse(CMD_ACK,NULL); - - PrintAndLog("Recorded Activity"); - PrintAndLog(""); - PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer"); - PrintAndLog("All times are in carrier periods (1/13.56Mhz)"); - PrintAndLog(""); - PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC "); - PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------------"); - - uint16_t tracepos = 0; - uint16_t duration; - uint16_t data_len; - uint16_t parity_len; - bool isResponse; - uint32_t timestamp; - uint32_t first_timestamp; - uint32_t EndOfTransmissionTimestamp; - - for (;;) { - - if(tracepos >= TRACE_SIZE) break; - - timestamp = *((uint32_t *)(trace + tracepos)); - - // Break and stick with current result if buffer was not completely full - if (timestamp == 0x44444444) break; - - if(tracepos == 0) { - first_timestamp = timestamp; - } - - tracepos += 4; - duration = *((uint16_t *)(trace + tracepos)); - tracepos += 2; - data_len = *((uint16_t *)(trace + tracepos)); - tracepos += 2; - - isResponse = false; - if (data_len & 0x8000) { - data_len &= 0x7fff; - isResponse = true; - } - - parity_len = (data_len-1)/8 + 1; - - if (tracepos + data_len + parity_len >= TRACE_SIZE) break; - - uint8_t *frame = trace + tracepos; - tracepos += data_len; - uint8_t *parityBytes = trace + tracepos; - tracepos += parity_len; - - char line[16][110]; - for (int j = 0; j < data_len; j++) { - int oddparity = 0x01; - int k; - - for (k=0;k<8;k++) { - oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01); - } - - uint8_t parityBits = parityBytes[j>>3]; - if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) { - sprintf(line[j/16]+((j%16)*4), "%02x! ", frame[j]); - } else { - sprintf(line[j/16]+((j%16)*4), "%02x ", frame[j]); - } - } - - char crc[5] = {0x00}; - if (data_len > 2) { - uint8_t b1, b2; - ComputeCrc14443(CRC_14443_A, frame, data_len-2, &b1, &b2); - if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) { - sprintf(crc, (isResponse & (data_len < 6)) ? "" : "!crc"); - } - } - - EndOfTransmissionTimestamp = timestamp + duration; - int num_lines = (data_len - 1)/16 + 1; - - for (int j = 0; j < num_lines; j++) { - if (j == 0) { - PrintAndLog(" %9d | %9d | %s | %-64s| %s", - (timestamp - first_timestamp), - (EndOfTransmissionTimestamp - first_timestamp), - (isResponse ? "Tag" : "Rdr"), - line[j], - (j == num_lines-1)?crc:"" - ); - } else { - PrintAndLog(" | | | %-64s| %s", - line[j], - (j == num_lines-1)?crc:""); - } - } - - bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000; - - if (ShowWaitCycles && !isResponse && next_isResponse) { - uint32_t next_timestamp = *((uint32_t *)(trace + tracepos)); - if (next_timestamp != 0x44444444) { - PrintAndLog(" %9d | %9d | %s | fdt (Frame Delay Time): %d", - (EndOfTransmissionTimestamp - first_timestamp), - (next_timestamp - first_timestamp), - " ", - (next_timestamp - EndOfTransmissionTimestamp)); - } - } - } + PrintAndLog("Deprecated command, use 'hf list 14a' instead"); return 0; } @@ -225,6 +97,13 @@ int CmdHF14AReader(const char *Cmd) memcpy(&card.ats, resp.d.asBytes, resp.arg[0]); card.ats_len = resp.arg[0]; // note: ats_len includes CRC Bytes } + + // disconnect + c.arg[0] = 0; + c.arg[1] = 0; + c.arg[2] = 0; + SendCommand(&c); + if(card.ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes bool ta1 = 0, tb1 = 0, tc1 = 0; @@ -364,24 +243,6 @@ int CmdHF14AReader(const char *Cmd) PrintAndLog("proprietary non iso14443-4 card found, RATS not supported"); } - - // try to see if card responses to "chinese magic backdoor" commands. - c.cmd = CMD_MIFARE_CIDENT; - c.arg[0] = 0; - c.arg[1] = 0; - c.arg[2] = 0; - SendCommand(&c); - WaitForResponse(CMD_ACK,&resp); - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog(" Answers to chinese magic backdoor commands: %s", (isOK ? "YES" : "NO") ); - - // disconnect - c.cmd = CMD_READER_ISO_14443a; - c.arg[0] = 0; - c.arg[1] = 0; - c.arg[2] = 0; - SendCommand(&c); - return select_status; } @@ -536,22 +397,19 @@ int CmdHF14ACmdRaw(const char *cmd) { uint8_t active=0; uint8_t active_select=0; uint16_t numbits=0; - uint16_t timeout=0; - uint8_t bTimeout=0; char buf[5]=""; int i=0; - uint8_t data[USB_CMD_DATA_SIZE]; + uint8_t data[100]; unsigned int datalen=0, temp; if (strlen(cmd)<2) { - PrintAndLog("Usage: hf 14a raw [-r] [-c] [-p] [-f] [-b] [-t] <0A 0B 0C ... hex>"); + PrintAndLog("Usage: hf 14a raw [-r] [-c] [-p] [-f] [-b] <0A 0B 0C ... hex>"); PrintAndLog(" -r do not read response"); PrintAndLog(" -c calculate and append CRC"); PrintAndLog(" -p leave the signal field ON after receive"); PrintAndLog(" -a active signal field ON without select"); PrintAndLog(" -s active signal field ON with select"); PrintAndLog(" -b number of bits to send. Useful for send partial byte"); - PrintAndLog(" -t timeout"); return 0; } @@ -584,14 +442,6 @@ int CmdHF14ACmdRaw(const char *cmd) { while(cmd[i]!=' ' && cmd[i]!='\0') { i++; } i-=2; break; - case 't': - bTimeout=1; - sscanf(cmd+i+2,"%d",&temp); - timeout = temp & 0xFFFF; - i+=3; - while(cmd[i]!=' ' && cmd[i]!='\0') { i++; } - i+=2; - break; default: PrintAndLog("Invalid option"); return 0; @@ -609,19 +459,15 @@ int CmdHF14ACmdRaw(const char *cmd) { if (strlen(buf)>=2) { sscanf(buf,"%x",&temp); data[datalen]=(uint8_t)(temp & 0xff); + datalen++; *buf=0; - if (++datalen>sizeof(data)){ - if (crc) - PrintAndLog("Buffer is full, we can't add CRC to your data"); - break; - } } continue; } PrintAndLog("Invalid char on input"); return 0; } - if(crc && datalen>0 && datalen0) { uint8_t first, second; ComputeCrc14443(CRC_14443_A, data, datalen, &first, &second); @@ -635,22 +481,13 @@ int CmdHF14ACmdRaw(const char *cmd) { if(active) c.arg[0] |= ISO14A_NO_SELECT; } - if(bTimeout){ - #define MAX_TIMEOUT 624*105 // max timeout is 624 ms - c.arg[0] |= ISO14A_SET_TIMEOUT; - c.arg[2] = timeout * 105; // each bit is about 9.4 us - if(c.arg[2]>MAX_TIMEOUT) { - c.arg[2] = MAX_TIMEOUT; - PrintAndLog("Set timeout to 624 ms. The max we can wait for response"); - } - } if(power) c.arg[0] |= ISO14A_NO_DISCONNECT; if(datalen>0) c.arg[0] |= ISO14A_RAW; - // Max buffer is USB_CMD_DATA_SIZE - c.arg[1] = (datalen & 0xFFFF) | (numbits << 16); + c.arg[1] = datalen; + c.arg[2] = numbits; memcpy(c.d.asBytes,data,datalen); SendCommand(&c); @@ -670,7 +507,7 @@ static void waitCmd(uint8_t iSelect) UsbCommand resp; char *hexout; - if (WaitForResponseTimeout(CMD_ACK,&resp,10000)) { + if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) { recv = resp.d.asBytes; uint8_t iLen = iSelect ? resp.arg[1] : resp.arg[0]; PrintAndLog("received %i octets",iLen); diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index 2c4c5949..7e4cbd00 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -13,15 +13,17 @@ #include #include #include -#include "../common/iso14443crc.h" +#include "iso14443crc.h" #include "proxmark3.h" #include "data.h" #include "graph.h" +#include "util.h" #include "ui.h" #include "cmdparser.h" #include "cmdhf14b.h" #include "cmdmain.h" + static int CmdHelp(const char *Cmd); int CmdHF14BDemod(const char *Cmd) @@ -144,7 +146,7 @@ demodError: int CmdHF14BList(const char *Cmd) { - uint8_t got[TRACE_BUFFER_SIZE]; + uint8_t got[960]; GetFromBigBuf(got,sizeof(got),0); WaitForResponse(CMD_ACK,NULL); @@ -156,8 +158,9 @@ int CmdHF14BList(const char *Cmd) int prev = -1; for(;;) { - - if(i >= TRACE_BUFFER_SIZE) { break; } + if(i >= 900) { + break; + } bool isResponse; int timestamp = *((uint32_t *)(got+i)); @@ -174,7 +177,7 @@ int CmdHF14BList(const char *Cmd) if(len > 100) { break; } - if(i + len >= TRACE_BUFFER_SIZE) { + if(i + len >= 900) { break; } @@ -356,7 +359,7 @@ int CmdHF14BCmdRaw (const char *cmd) { SendCommand(&c); if (reply) { - if (WaitForResponseTimeout(CMD_ACK,&resp,10000)) { + if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) { recv = resp.d.asBytes; PrintAndLog("received %i octets",resp.arg[0]); if(!resp.arg[0]) diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 25ae2a82..b1e04e9a 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -31,9 +31,10 @@ #include "data.h" #include "graph.h" #include "ui.h" +#include "util.h" #include "cmdparser.h" #include "cmdhf15.h" -#include "../common/iso15693tools.h" +#include "iso15693tools.h" #include "cmdmain.h" #define FrameSOF Iso15693FrameSOF @@ -44,7 +45,6 @@ #define Crc(data,datalen) Iso15693Crc(data,datalen) #define AddCrc(data,datalen) Iso15693AddCrc(data,datalen) #define sprintUID(target,uid) Iso15693sprintUID(target,uid) -#define TRACE_BUFF_SIZE 12000 // structure and database for uid -> tagtype lookups typedef struct { @@ -255,17 +255,6 @@ int CmdHF15Read(const char *Cmd) { UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693}; SendCommand(&c); - - uint8_t data[TRACE_BUFF_SIZE] = {0x00}; - - GetFromBigBuf(data,TRACE_BUFF_SIZE,3560); //3560 -- should be offset.. - WaitForResponseTimeout(CMD_ACK,NULL, 1500); - - for (int j = 0; j < TRACE_BUFF_SIZE; j++) { - GraphBuffer[j] = ((int)data[j]) ; - } - GraphTraceLen = TRACE_BUFF_SIZE; - RepaintGraphWindow(); return 0; } @@ -274,17 +263,6 @@ int CmdHF15Record(const char *Cmd) { UsbCommand c = {CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693}; SendCommand(&c); - - uint8_t data[TRACE_BUFF_SIZE] = {0x00}; - - GetFromBigBuf(data,TRACE_BUFF_SIZE,3560); //3560 -- should be offset.. - WaitForResponseTimeout(CMD_ACK,NULL, 1500); - - for (int j = 0; j < TRACE_BUFF_SIZE; j++) { - GraphBuffer[j] = ((int)data[j]) ; - } - GraphTraceLen = TRACE_BUFF_SIZE; - RepaintGraphWindow(); return 0; } @@ -582,9 +560,9 @@ int CmdHF15CmdRaw (const char *cmd) { */ int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd[], int iso15cmdlen) { int temp; - uint8_t *req = c->d.asBytes; + uint8_t *req=c->d.asBytes; uint8_t uid[8] = {0x00}; - uint32_t reqlen = 0; + uint32_t reqlen=0; // strip while (**cmd==' ' || **cmd=='\t') (*cmd)++; diff --git a/client/cmdhfdes.c b/client/cmdhfdes.c deleted file mode 100644 index 1876e5c1..00000000 --- a/client/cmdhfdes.c +++ /dev/null @@ -1,69 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2012 nuit -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// High frequency MIFARE DESfire commands -//----------------------------------------------------------------------------- - -#include "cmdhfdes.h" -#include "proxmark3.h" -#include "cmdmain.h" - -static int CmdHelp(const char *Cmd); - -int CmdHFDESReader(const char *Cmd) -{ - UsbCommand c ={CMD_MIFARE_DES_READER, {3, 0x60, 0}}; - SendCommand(&c); - - UsbCommand resp; - WaitForResponseTimeout(CMD_ACK,&resp,2000); - return 0; -} - -int CmdHFDESDbg(const char *Cmd) -{ - int dbgMode = param_get32ex(Cmd, 0, 0, 10); - if (dbgMode > 4) { - PrintAndLog("Max debud mode parameter is 4 \n"); - } - - if (strlen(Cmd) < 1 || !param_getchar(Cmd, 0) || dbgMode > 4) { - PrintAndLog("Usage: hf des dbg "); - PrintAndLog(" 0 - no debug messages"); - PrintAndLog(" 1 - error messages"); - PrintAndLog(" 2 - all messages"); - PrintAndLog(" 4 - extended debug mode"); - return 0; - } - - UsbCommand c = {CMD_MIFARE_SET_DBGMODE, {dbgMode, 0, 0}}; - SendCommand(&c); - - return 0; -} - -static command_t CommandTable[] = -{ - {"help", CmdHelp, 1, "This help"}, - {"dbg", CmdHFDESDbg, 0, "Set default debug mode"}, - {"reader", CmdHFDESReader, 0, "Reader"}, - {NULL, NULL, 0, NULL} -}; - -int CmdHFDES(const char *Cmd) -{ - //flush - WaitForResponseTimeout(CMD_ACK,NULL,100); - CmdsParse(CommandTable, Cmd); - return 0; -} - -int CmdHelp(const char *Cmd) -{ - CmdsHelp(CommandTable); - return 0; -} diff --git a/client/cmdhfdes.h b/client/cmdhfdes.h deleted file mode 100644 index e51797cb..00000000 --- a/client/cmdhfdes.h +++ /dev/null @@ -1,27 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2012 nuit -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// High frequency MIFARE DESfire commands -//----------------------------------------------------------------------------- - -#ifndef CMDHFDES_H__ -#define CMDHFDES_H__ - -#include -#include -#include -#include -#include "proxmark3.h" -#include "data.h" -#include "ui.h" -#include "cmdparser.h" -#include "common.h" -#include "util.h" -int CmdHFDES(const char *Cmd); -int CmdHFDESReader(const char *Cmd); -int CmdHFDESDbg(const char *Cmd); -#endif diff --git a/client/cmdhfepa.c b/client/cmdhfepa.c index afcdb0fa..3286ceb9 100644 --- a/client/cmdhfepa.c +++ b/client/cmdhfepa.c @@ -13,7 +13,7 @@ #include "proxmark3.h" #include "ui.h" #include "cmdparser.h" -#include "../include/common.h" +#include "common.h" #include "cmdmain.h" #include "sleep.h" #include "cmdhfepa.h" diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 38713220..b097eea8 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -20,7 +20,7 @@ #include "ui.h" #include "cmdparser.h" #include "cmdhficlass.h" -#include "../include/common.h" +#include "common.h" #include "util.h" #include "cmdmain.h" #include "loclass/des.h" @@ -34,53 +34,17 @@ static int CmdHelp(const char *Cmd); int xorbits_8(uint8_t val) { - uint8_t res = val ^ (val >> 1); //1st pass - res = res ^ (res >> 1); // 2nd pass - res = res ^ (res >> 2); // 3rd pass - res = res ^ (res >> 4); // 4th pass - return res & 1; -} - -#define ICLASS_CMD_ACTALL 0x0A -#define ICLASS_CMD_IDENTIFY 0x0C -#define ICLASS_CMD_READ 0x0C - -#define ICLASS_CMD_SELECT 0x81 -#define ICLASS_CMD_PAGESEL 0x84 -#define ICLASS_CMD_READCHECK 0x88 -#define ICLASS_CMD_CHECK 0x05 -#define ICLASS_CMD_SOF 0x0F -#define ICLASS_CMD_HALT 0x00 - - -void explain(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize) -{ - - if(cmdsize > 1 && cmd[0] == ICLASS_CMD_READ) - { - snprintf(exp,size,"READ(%d)",cmd[1]); - return; - } - - switch(cmd[0]) - { - case ICLASS_CMD_ACTALL: snprintf(exp,size,"ACTALL"); break; - case ICLASS_CMD_IDENTIFY: snprintf(exp,size,"IDENTIFY"); break; - case ICLASS_CMD_SELECT: snprintf(exp,size,"SELECT"); break; - case ICLASS_CMD_PAGESEL: snprintf(exp,size,"PAGESEL"); break; - case ICLASS_CMD_READCHECK: snprintf(exp,size,"READCHECK"); break; - case ICLASS_CMD_CHECK: snprintf(exp,size,"CHECK"); break; - case ICLASS_CMD_SOF: snprintf(exp,size,"SOF"); break; - case ICLASS_CMD_HALT: snprintf(exp,size,"HALT"); break; - default: snprintf(exp,size,"?"); break; - } - return; + uint8_t res = val ^ (val >> 1); //1st pass + res = res ^ (res >> 1); // 2nd pass + res = res ^ (res >> 2); // 3rd pass + res = res ^ (res >> 4); // 4th pass + return res & 1; } int CmdHFiClassList(const char *Cmd) { PrintAndLog("Deprecated command, use 'hf list iclass' instead"); - return 0; + return 0; } int CmdHFiClassSnoop(const char *Cmd) @@ -140,24 +104,24 @@ int CmdHFiClassSim(const char *Cmd) 0x0c,0x90,0x32,0xf3,0x5d,0xff,0x12,0xe0 }; */ - uint8_t csns[8*NUM_CSNS] = { - 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 }; - - memcpy(c.d.asBytes, csns, 8*NUM_CSNS); + uint8_t csns[8*NUM_CSNS] = { + 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 }; + + memcpy(c.d.asBytes, csns, 8*NUM_CSNS); SendCommand(&c); if (!WaitForResponseTimeout(CMD_ACK, &resp, -1)) { @@ -166,7 +130,7 @@ int CmdHFiClassSim(const char *Cmd) } uint8_t num_mac_responses = resp.arg[1]; - PrintAndLog("Mac responses: %d MACs obtained (should be %d)", num_mac_responses, NUM_CSNS); + PrintAndLog("Mac responses: %d MACs obtained (should be %d)", num_mac_responses,NUM_CSNS); size_t datalen = NUM_CSNS*24; /* @@ -245,7 +209,7 @@ int CmdHFiClassReader_Replay(const char *Cmd) if (strlen(Cmd)<1) { PrintAndLog("Usage: hf iclass replay "); PrintAndLog(" sample: hf iclass replay 00112233"); - return 0; + return 0; } if (param_gethex(Cmd, 0, MAC, 8)) { @@ -323,7 +287,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) UsbCommand c = {CMD_READER_ICLASS, {0}}; c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_GET_CC; if(!fake_dummy_test) - SendCommand(&c); + SendCommand(&c); @@ -469,19 +433,64 @@ int CmdHFiClass_iso14443A_write(const char *Cmd) } return 0; } +int CmdHFiClass_loclass(const char *Cmd) +{ + char opt = param_getchar(Cmd, 0); + if (strlen(Cmd)<1 || opt == 'h') { + PrintAndLog("Usage: hf iclass loclass [options]"); + PrintAndLog("Options:"); + PrintAndLog("h Show this help"); + PrintAndLog("t Perform self-test"); + PrintAndLog("f Bruteforce iclass dumpfile"); + PrintAndLog(" An iclass dumpfile is assumed to consist of an arbitrary number of"); + PrintAndLog(" malicious CSNs, and their protocol responses"); + PrintAndLog(" The the binary format of the file is expected to be as follows: "); + PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>"); + PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>"); + PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>"); + PrintAndLog(" ... totalling N*24 bytes"); + return 0; + } + char fileName[255] = {0}; + if(opt == 'f') + { + if(param_getstr(Cmd, 1, fileName) > 0) + { + return bruteforceFileNoKeys(fileName); + }else + { + PrintAndLog("You must specify a filename"); + } + } + else if(opt == 't') + { + int errors = testCipherUtils(); + errors += testMAC(); + errors += doKeyTests(0); + errors += testElite(); + if(errors) + { + prnlog("OBS! There were errors!!!"); + } + return errors; + } + + return 0; +} static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"list", CmdHFiClassList, 0, "[Deprecated] List iClass history"}, - {"snoop", CmdHFiClassSnoop, 0, "Eavesdrop iClass communication"}, - {"sim", CmdHFiClassSim, 0, "Simulate iClass tag"}, - {"reader",CmdHFiClassReader, 0, "Read an iClass tag"}, - {"replay", CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"}, - {"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"}, - {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"}, - {NULL, NULL, 0, NULL} + {"help", CmdHelp, 1, "This help"}, + {"list", CmdHFiClassList, 0, "[Deprecated] List iClass history"}, + {"snoop", CmdHFiClassSnoop, 0, "Eavesdrop iClass communication"}, + {"sim", CmdHFiClassSim, 0, "Simulate iClass tag"}, + {"reader",CmdHFiClassReader, 0, "Read an iClass tag"}, + {"replay",CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"}, + {"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"}, + {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"}, + {"loclass", CmdHFiClass_loclass, 1, "Use loclass to perform bruteforce of reader attack dump"}, + {NULL, NULL, 0, NULL} }; int CmdHFiClass(const char *Cmd) @@ -493,5 +502,5 @@ int CmdHFiClass(const char *Cmd) int CmdHelp(const char *Cmd) { CmdsHelp(CommandTable); - return 0; + return 0; } diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 35ba1f28..bf874b62 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -218,24 +218,7 @@ int CmdLegicRFRead(const char *Cmd) int CmdLegicLoad(const char *Cmd) { - char filename[FILE_PATH_SIZE] = {0x00}; - int len = 0; - - if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) { - PrintAndLog("It loads datasamples from the file `filename`"); - PrintAndLog("Usage: hf legic load "); - PrintAndLog(" sample: hf legic load filename"); - return 0; - } - - len = strlen(Cmd); - if (len > FILE_PATH_SIZE) { - PrintAndLog("Filepath too long (was %s bytes), max allowed is %s ", len, FILE_PATH_SIZE); - return 0; - } - memcpy(filename, Cmd, len); - - FILE *f = fopen(filename, "r"); + FILE *f = fopen(Cmd, "r"); if(!f) { PrintAndLog("couldn't open '%s'", Cmd); return -1; @@ -268,7 +251,7 @@ int CmdLegicSave(const char *Cmd) int requested = 1024; int offset = 0; int delivered = 0; - char filename[FILE_PATH_SIZE]; + char filename[1024]; uint8_t got[1024]; sscanf(Cmd, " %s %i %i", filename, &requested, &offset); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 49928c9a..121736e9 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -7,7 +7,7 @@ //----------------------------------------------------------------------------- // High frequency MIFARE commands //----------------------------------------------------------------------------- -#include "../include/mifare.h" + #include "cmdhfmf.h" static int CmdHelp(const char *Cmd); @@ -34,7 +34,7 @@ start: SendCommand(&c); //flush queue - while (ukbhit()) getchar(); + while (ukbhit()) getchar(); // wait cycle while (true) { @@ -66,19 +66,20 @@ start: if (isOK != 1) return 1; // execute original function from util nonce2key - if (nonce2key(uid, nt, nr, par_list, ks_list, &r_key)) { + if (nonce2key(uid, nt, nr, par_list, ks_list, &r_key)) + { isOK = 2; PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt); } else { printf("------------------------------------------------------------------\n"); - PrintAndLog("Key found :%012"llx" \n", r_key); + PrintAndLog("Key found:%012"llx" \n", r_key); num_to_bytes(r_key, 6, keyBlock); isOK = mfCheckKeys(0, 0, 1, keyBlock, &r_key); } if (!isOK) - PrintAndLog("Found valid key :%012"llx, r_key); + PrintAndLog("Found valid key:%012"llx, r_key); else { if (isOK != 2) PrintAndLog("Found invalid key. "); @@ -124,10 +125,10 @@ int CmdHF14AMfWrBl(const char *Cmd) PrintAndLog("--block no:%d, key type:%c, key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6)); PrintAndLog("--data: %s", sprint_hex(bldata, 16)); - UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}}; + UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}}; memcpy(c.d.asBytes, key, 6); memcpy(c.d.asBytes + 10, bldata, 16); - SendCommand(&c); + SendCommand(&c); UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { @@ -140,6 +141,117 @@ int CmdHF14AMfWrBl(const char *Cmd) return 0; } +int CmdHF14AMfUWrBl(const char *Cmd) +{ + uint8_t blockNo = 0; + bool chinese_card=0; + uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + UsbCommand resp; + + if (strlen(Cmd)<3) { + PrintAndLog("Usage: hf mf uwrbl "); + PrintAndLog(" sample: hf mf uwrbl 0 01020304"); + return 0; + } + + blockNo = param_get8(Cmd, 0); + if (param_gethex(Cmd, 1, bldata, 8)) { + PrintAndLog("Block data must include 8 HEX symbols"); + return 1; + } + + if (strchr(Cmd,'w') != 0) { + chinese_card=1; + } + + switch(blockNo){ + case 0: + if (!chinese_card){ + PrintAndLog("Access Denied"); + }else{ + PrintAndLog("--specialblock no:%d", blockNo); + PrintAndLog("--data: %s", sprint_hex(bldata, 4)); + UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}}; + memcpy(d.d.asBytes,bldata, 4); + SendCommand(&d); + + if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { + uint8_t isOK = resp.arg[0] & 0xff; + PrintAndLog("isOk:%02x", isOK); + } else { + PrintAndLog("Command execute timeout"); + } + } + break; + case 1: + if (!chinese_card){ + PrintAndLog("Access Denied"); + }else{ + PrintAndLog("--specialblock no:%d", blockNo); + PrintAndLog("--data: %s", sprint_hex(bldata, 4)); + UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}}; + memcpy(d.d.asBytes,bldata, 4); + SendCommand(&d); + + if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { + uint8_t isOK = resp.arg[0] & 0xff; + PrintAndLog("isOk:%02x", isOK); + } else { + PrintAndLog("Command execute timeout"); + } + } + break; + case 2: + if (!chinese_card){ + PrintAndLog("Access Denied"); + }else{ + PrintAndLog("--specialblock no:%d", blockNo); + PrintAndLog("--data: %s", sprint_hex(bldata, 4)); + UsbCommand c = {CMD_MIFAREU_WRITEBL, {blockNo}}; + memcpy(c.d.asBytes, bldata, 4); + SendCommand(&c); + + if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { + uint8_t isOK = resp.arg[0] & 0xff; + PrintAndLog("isOk:%02x", isOK); + } else { + PrintAndLog("Command execute timeout"); + } + } + break; + case 3: + PrintAndLog("--specialblock no:%d", blockNo); + PrintAndLog("--data: %s", sprint_hex(bldata, 4)); + UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}}; + memcpy(d.d.asBytes,bldata, 4); + SendCommand(&d); + + if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { + uint8_t isOK = resp.arg[0] & 0xff; + PrintAndLog("isOk:%02x", isOK); + } else { + PrintAndLog("Command execute timeout"); + } + break; + default: + PrintAndLog("--block no:%d", blockNo); + PrintAndLog("--data: %s", sprint_hex(bldata, 4)); + UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}}; + memcpy(e.d.asBytes,bldata, 4); + SendCommand(&e); + + if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { + uint8_t isOK = resp.arg[0] & 0xff; + PrintAndLog("isOk:%02x", isOK); + } else { + PrintAndLog("Command execute timeout"); + } + break; + } + return 0; +} + + int CmdHF14AMfRdBl(const char *Cmd) { uint8_t blockNo = 0; @@ -168,9 +280,9 @@ int CmdHF14AMfRdBl(const char *Cmd) } PrintAndLog("--block no:%d, key type:%c, key:%s ", blockNo, keyType?'B':'A', sprint_hex(key, 6)); - UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}}; + UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}}; memcpy(c.d.asBytes, key, 6); - SendCommand(&c); + SendCommand(&c); UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { @@ -188,6 +300,87 @@ int CmdHF14AMfRdBl(const char *Cmd) return 0; } +int CmdHF14AMfURdBl(const char *Cmd) +{ + uint8_t blockNo = 0; + + if (strlen(Cmd)<1) { + PrintAndLog("Usage: hf mf urdbl "); + PrintAndLog(" sample: hf mf urdbl 0"); + return 0; + } + + blockNo = param_get8(Cmd, 0); + PrintAndLog("--block no:%d", blockNo); + + UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}}; + SendCommand(&c); + + UsbCommand resp; + if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { + uint8_t isOK = resp.arg[0] & 0xff; + uint8_t *data = resp.d.asBytes; + + if (isOK) + PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4)); + else + PrintAndLog("isOk:%02x", isOK); + } else { + PrintAndLog("Command execute timeout"); + } + + return 0; +} + + +int CmdHF14AMfURdCard(const char *Cmd) +{ + int i; + uint8_t sectorNo = 0; + uint8_t *lockbytes_t=NULL; + uint8_t lockbytes[2]={0,0}; + bool bit[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + + uint8_t isOK = 0; + uint8_t * data = NULL; + + PrintAndLog("Attempting to Read Ultralight... "); + + UsbCommand c = {CMD_MIFAREU_READCARD, {sectorNo}}; + SendCommand(&c); + + UsbCommand resp; + if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { + isOK = resp.arg[0] & 0xff; + data = resp.d.asBytes; + + PrintAndLog("isOk:%02x", isOK); + if (isOK) + { // bit 0 and 1 + PrintAndLog("Block %3d:%s ", 0,sprint_hex(data + 0 * 4, 4)); + PrintAndLog("Block %3d:%s ", 1,sprint_hex(data + 1 * 4, 4)); + // bit 2 + //process lock bytes + lockbytes_t=data+(2*4); + lockbytes[0]=lockbytes_t[2]; + lockbytes[1]=lockbytes_t[3]; + for(int j=0; j<16; j++){ + bit[j]=lockbytes[j/8] & ( 1 <<(7-j%8)); + } + //remaining + for (i = 3; i < 16; i++) { + int bitnum = (23-i) % 16; + PrintAndLog("Block %3d:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[bitnum]); + } + + } + } else { + PrintAndLog("Command execute timeout"); + } + return 0; +} + + int CmdHF14AMfRdSc(const char *Cmd) { int i; @@ -278,14 +471,7 @@ int CmdHF14AMfDump(const char *Cmd) UsbCommand resp; - int size = GetCardSize(); char cmdp = param_getchar(Cmd, 0); - - if ( size > -1) - cmdp = (char)(48+size); - - PrintAndLog("Got %d",cmdp); - switch (cmdp) { case '0' : numSectors = 5; break; case '1' : @@ -305,7 +491,7 @@ int CmdHF14AMfDump(const char *Cmd) } if ((fin = fopen("dumpkeys.bin","rb")) == NULL) { - PrintAndLog("Could not find file dumpkeys.bin"); + PrintAndLog("Could not find file dumpkeys.bin"); return 1; } @@ -326,9 +512,9 @@ int CmdHF14AMfDump(const char *Cmd) return 2; } } - fclose(fin); - + // Read access rights to sectors + PrintAndLog("|-----------------------------------------|"); PrintAndLog("|------ Reading sector access bits...-----|"); PrintAndLog("|-----------------------------------------|"); @@ -358,6 +544,8 @@ int CmdHF14AMfDump(const char *Cmd) } } + // Read blocks and print to file + PrintAndLog("|-----------------------------------------|"); PrintAndLog("|----- Dumping all blocks to file... -----|"); PrintAndLog("|-----------------------------------------|"); @@ -381,12 +569,12 @@ int CmdHF14AMfDump(const char *Cmd) received = WaitForResponseTimeout(CMD_ACK,&resp,1500); } else if (rights[sectorNo][data_area] == 0x07) { // no key would work isOK = false; - PrintAndLog("Access rights do not allow reading of sector %2d block %3d", sectorNo, blockNo); + PrintAndLog("Access rights do not allow reading of sector %2d block %3d", sectorNo, blockNo); } else { // key A would work - UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}}; - memcpy(c.d.asBytes, keyA[sectorNo], 6); - SendCommand(&c); - received = WaitForResponseTimeout(CMD_ACK,&resp,1500); + UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}}; + memcpy(c.d.asBytes, keyA[sectorNo], 6); + SendCommand(&c); + received = WaitForResponseTimeout(CMD_ACK,&resp,1500); } } @@ -433,7 +621,7 @@ int CmdHF14AMfDump(const char *Cmd) fclose(fout); PrintAndLog("Dumped %d blocks (%d bytes) to file dumpdata.bin", numblocks, 16*numblocks); } - + return 0; } @@ -441,8 +629,8 @@ int CmdHF14AMfRestore(const char *Cmd) { uint8_t sectorNo,blockNo; uint8_t keyType = 0; - uint8_t key[6] = {0xFF}; - uint8_t bldata[16] = {0x00}; + uint8_t key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t keyA[40][6]; uint8_t keyB[40][6]; uint8_t numSectors; @@ -460,7 +648,7 @@ int CmdHF14AMfRestore(const char *Cmd) default: numSectors = 16; } - if (cmdp == 'h' || cmdp == 'H') { + if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { PrintAndLog("Usage: hf mf restore [card memory]"); PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); PrintAndLog(""); @@ -468,15 +656,22 @@ int CmdHF14AMfRestore(const char *Cmd) PrintAndLog(" hf mf restore 4"); return 0; } - + + if ((fdump = fopen("dumpdata.bin","rb")) == NULL) { + PrintAndLog("Could not find file dumpdata.bin"); + return 1; + } if ((fkeys = fopen("dumpkeys.bin","rb")) == NULL) { PrintAndLog("Could not find file dumpkeys.bin"); + fclose(fdump); return 1; } for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { if (fread(keyA[sectorNo], 1, 6, fkeys) == 0) { PrintAndLog("File reading error (dumpkeys.bin)."); + fclose(fdump); + fclose(fkeys); return 2; } } @@ -484,16 +679,13 @@ int CmdHF14AMfRestore(const char *Cmd) for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { if (fread(keyB[sectorNo], 1, 6, fkeys) == 0) { PrintAndLog("File reading error (dumpkeys.bin)."); + fclose(fdump); + fclose(fkeys); return 2; } } - fclose(fkeys); - - if ((fdump = fopen("dumpdata.bin","rb")) == NULL) { - PrintAndLog("Could not find file dumpdata.bin"); - return 1; - } + PrintAndLog("Restoring dumpdata.bin to card"); for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { @@ -551,7 +743,7 @@ int CmdHF14AMfNested(const char *Cmd) uint8_t trgKeyType = 0; uint8_t SectorsCnt = 0; uint8_t key[6] = {0, 0, 0, 0, 0, 0}; - uint8_t keyBlock[13*6]; + uint8_t keyBlock[6*6]; uint64_t key64 = 0; bool transferToEml = false; @@ -581,15 +773,11 @@ int CmdHF14AMfNested(const char *Cmd) cmdp = param_getchar(Cmd, 0); blockNo = param_get8(Cmd, 1); ctmp = param_getchar(Cmd, 2); - if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') { PrintAndLog("Key type must be A or B"); return 1; } - - if (ctmp != 'A' && ctmp != 'a') - keyType = 1; - + if (ctmp != 'A' && ctmp != 'a') keyType = 1; if (param_gethex(Cmd, 3, key, 12)) { PrintAndLog("Key must include 12 HEX symbols"); return 1; @@ -603,10 +791,8 @@ int CmdHF14AMfNested(const char *Cmd) PrintAndLog("Target key type must be A or B"); return 1; } - if (ctmp != 'A' && ctmp != 'a') - trgKeyType = 1; + if (ctmp != 'A' && ctmp != 'a') trgKeyType = 1; } else { - switch (cmdp) { case '0': SectorsCnt = 05; break; case '1': SectorsCnt = 16; break; @@ -668,14 +854,6 @@ int CmdHF14AMfNested(const char *Cmd) num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock + 3 * 6)); num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock + 4 * 6)); num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock + 5 * 6)); - num_to_bytes(0x4d3a99c351dd, 6, (uint8_t*)(keyBlock + 6 * 6)); - num_to_bytes(0x1a982c7e459a, 6, (uint8_t*)(keyBlock + 7 * 6)); - num_to_bytes(0xd3f7d3f7d3f7, 6, (uint8_t*)(keyBlock + 8 * 6)); - num_to_bytes(0x714c5c886e97, 6, (uint8_t*)(keyBlock + 9 * 6)); - num_to_bytes(0x587ee5f9350f, 6, (uint8_t*)(keyBlock + 10 * 6)); - num_to_bytes(0xa0478cc39091, 6, (uint8_t*)(keyBlock + 11 * 6)); - num_to_bytes(0x533cb6c723f6, 6, (uint8_t*)(keyBlock + 12 * 6)); - num_to_bytes(0x8fd0a4f256e9, 6, (uint8_t*)(keyBlock + 13 * 6)); PrintAndLog("Testing known keys. Sector count=%d", SectorsCnt); for (i = 0; i < SectorsCnt; i++) { @@ -691,26 +869,21 @@ int CmdHF14AMfNested(const char *Cmd) } } + // nested sectors iterations = 0; PrintAndLog("nested..."); bool calibrate = true; for (i = 0; i < NESTED_SECTOR_RETRY; i++) { for (uint8_t sectorNo = 0; sectorNo < SectorsCnt; sectorNo++) { - - if (ukbhit()) { - printf("\naborted via keyboard!\n"); - free(e_sector); - return 2; - } - for (trgKeyType = 0; trgKeyType < 2; trgKeyType++) { if (e_sector[sectorNo].foundKey[trgKeyType]) continue; PrintAndLog("-----------------------------------------------"); if(mfnested(blockNo, keyType, key, FirstBlockOfSector(sectorNo), trgKeyType, keyBlock, calibrate)) { PrintAndLog("Nested error.\n"); free(e_sector); - return 2; } + return 2; + } else { calibrate = false; } @@ -780,7 +953,7 @@ int CmdHF14AMfNested(const char *Cmd) } fclose(fkeys); } - + free(e_sector); } return 0; @@ -789,19 +962,17 @@ int CmdHF14AMfNested(const char *Cmd) int CmdHF14AMfChk(const char *Cmd) { if (strlen(Cmd)<3) { - PrintAndLog("Usage: hf mf chk |<*card memory> [t|d] [] []"); + PrintAndLog("Usage: hf mf chk |<*card memory> [t] [] []"); PrintAndLog(" * - all sectors"); PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K"); PrintAndLog("d - write keys to binary file\n"); - PrintAndLog("t - write keys to emulator memory"); PrintAndLog(" sample: hf mf chk 0 A 1234567890ab keys.dic"); PrintAndLog(" hf mf chk *1 ? t"); - PrintAndLog(" hf mf chk *1 ? d"); return 0; - } - + } + FILE * f; - char filename[FILE_PATH_SIZE]={0}; + char filename[256]={0}; char buf[13]; uint8_t *keyBlock = NULL, *p; uint8_t stKeyBlock = 20; @@ -893,7 +1064,7 @@ int CmdHF14AMfChk(const char *Cmd) keycnt++; } else { // May be a dic file - if ( param_getstr(Cmd, 2 + i,filename) >= FILE_PATH_SIZE ) { + if ( param_getstr(Cmd, 2 + i,filename) > 255 ) { PrintAndLog("File name too long"); free(keyBlock); return 2; @@ -944,8 +1115,8 @@ int CmdHF14AMfChk(const char *Cmd) PrintAndLog("No key specified, trying default keys"); for (;keycnt < defaultKeysSize; keycnt++) PrintAndLog("chk default key[%2d] %02x%02x%02x%02x%02x%02x", keycnt, - (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2], - (keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4], (keyBlock + 6*keycnt)[5], 6); + (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2], + (keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4], (keyBlock + 6*keycnt)[5], 6); } // initialize storage for found keys @@ -990,13 +1161,13 @@ int CmdHF14AMfChk(const char *Cmd) for (uint16_t t = 0; t < 2; t++) { if (validKey[t][sectorNo]) { memcpy(block + t*10, foundKey[t][sectorNo], 6); - } - } + } + } mfEmlSetMem(block, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); } } PrintAndLog("Found keys have been transferred to the emulator memory"); - } + } if (createDumpFile) { FILE *fkeys = fopen("dumpkeys.bin","wb"); @@ -1004,7 +1175,7 @@ int CmdHF14AMfChk(const char *Cmd) PrintAndLog("Could not create file dumpkeys.bin"); free(keyBlock); return 1; - } + } for (uint16_t t = 0; t < 2; t++) { fwrite(foundKey[t], 1, 6*SectorsCnt, fkeys); } @@ -1014,7 +1185,7 @@ int CmdHF14AMfChk(const char *Cmd) free(keyBlock); PrintAndLog(""); - return 0; + return 0; } int CmdHF14AMf1kSim(const char *Cmd) @@ -1174,44 +1345,26 @@ int CmdHF14AMfESet(const char *Cmd) int CmdHF14AMfELoad(const char *Cmd) { FILE * f; - char filename[FILE_PATH_SIZE]; + char filename[20]; char *fnameptr = filename; char buf[64]; uint8_t buf8[64]; - int i, len, blockNum, numBlocks; - int nameParamNo = 1; + int i, len, blockNum; memset(filename, 0, sizeof(filename)); memset(buf, 0, sizeof(buf)); - char ctmp = param_getchar(Cmd, 0); - - if ( ctmp == 'h' || ctmp == 0x00) { + if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) { PrintAndLog("It loads emul dump from the file `filename.eml`"); - PrintAndLog("Usage: hf mf eload [card memory] "); - PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); - PrintAndLog(""); + PrintAndLog("Usage: hf mf eload "); PrintAndLog(" sample: hf mf eload filename"); - PrintAndLog(" hf mf eload 4 filename"); return 0; } - switch (ctmp) { - case '0' : numBlocks = 5*4; break; - case '1' : - case '\0': numBlocks = 16*4; break; - case '2' : numBlocks = 32*4; break; - case '4' : numBlocks = 256; break; - default: { - numBlocks = 16*4; - nameParamNo = 0; - } - } - - len = param_getstr(Cmd,nameParamNo,filename); - - if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; + len = strlen(Cmd); + if (len > 14) len = 14; + memcpy(filename, Cmd, len); fnameptr += len; sprintf(fnameptr, ".eml"); @@ -1226,16 +1379,14 @@ int CmdHF14AMfELoad(const char *Cmd) blockNum = 0; while(!feof(f)){ memset(buf, 0, sizeof(buf)); - if (fgets(buf, sizeof(buf), f) == NULL) { - - if (blockNum >= numBlocks) break; - + if((blockNum == 16*4) || (blockNum == 32*4 + 8*16)) { // supports both old (1K) and new (4K) .eml files) + break; + } PrintAndLog("File reading error."); fclose(f); return 2; } - if (strlen(buf) < 32){ if(strlen(buf) && feof(f)) break; @@ -1243,7 +1394,6 @@ int CmdHF14AMfELoad(const char *Cmd) fclose(f); return 2; } - for (i = 0; i < 32; i += 2) { sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]); } @@ -1255,12 +1405,12 @@ int CmdHF14AMfELoad(const char *Cmd) } blockNum++; - if (blockNum >= numBlocks) break; + if (blockNum >= 32*4 + 8*16) break; } fclose(f); - if ((blockNum != numBlocks)) { - PrintAndLog("File content error. Got %d must be %d blocks.",blockNum, numBlocks); + if ((blockNum != 16*4) && (blockNum != 32*4 + 8*16)) { + PrintAndLog("File content error. There must be 64 or 256 blocks."); return 4; } PrintAndLog("Loaded %d blocks from file: %s", blockNum, filename); @@ -1271,65 +1421,45 @@ int CmdHF14AMfELoad(const char *Cmd) int CmdHF14AMfESave(const char *Cmd) { FILE * f; - char filename[FILE_PATH_SIZE]; + char filename[20]; char * fnameptr = filename; uint8_t buf[64]; - int i, j, len, numBlocks; - int nameParamNo = 1; + int i, j, len; memset(filename, 0, sizeof(filename)); memset(buf, 0, sizeof(buf)); - char ctmp = param_getchar(Cmd, 0); - - if ( ctmp == 'h') { - PrintAndLog("It saves emul dump into the file `filename.eml` or `cardID.eml`"); - PrintAndLog(" Usage: hf mf esave [card memory] [file name w/o `.eml`]"); - PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); - PrintAndLog(""); + if (param_getchar(Cmd, 0) == 'h') { + PrintAndLog("It saves emul dump into the file `filename.eml` or `cardID.eml`"); + PrintAndLog("Usage: hf mf esave [file name w/o `.eml`]"); PrintAndLog(" sample: hf mf esave "); - PrintAndLog(" hf mf esave 4"); - PrintAndLog(" hf mf esave 4 filename"); + PrintAndLog(" hf mf esave filename"); return 0; } - - switch (ctmp) { - case '0' : numBlocks = 5*4; break; - case '1' : - case '\0': numBlocks = 16*4; break; - case '2' : numBlocks = 32*4; break; - case '4' : numBlocks = 256; break; - default: { - numBlocks = 16*4; - nameParamNo = 0; - } - } - len = param_getstr(Cmd,nameParamNo,filename); + len = strlen(Cmd); + if (len > 14) len = 14; - if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; - - // user supplied filename? if (len < 1) { - // get filename (UID from memory) + // get filename if (mfEmlGetMem(buf, 0, 1)) { - PrintAndLog("Can\'t get UID from block: %d", 0); - sprintf(filename, "dump.eml"); + PrintAndLog("Cant get block: %d", 0); + return 1; } for (j = 0; j < 7; j++, fnameptr += 2) - sprintf(fnameptr, "%02X", buf[j]); + sprintf(fnameptr, "%02x", buf[j]); } else { + memcpy(filename, Cmd, len); fnameptr += len; } - // add file extension sprintf(fnameptr, ".eml"); // open file f = fopen(filename, "w+"); // put hex - for (i = 0; i < numBlocks; i++) { + for (i = 0; i < 32*4 + 8*16; i++) { if (mfEmlGetMem(buf, i, 1)) { PrintAndLog("Cant get block: %d", i); break; @@ -1340,7 +1470,7 @@ int CmdHF14AMfESave(const char *Cmd) } fclose(f); - PrintAndLog("Saved %d blocks to file: %s", numBlocks, filename); + PrintAndLog("Saved to file: %s", filename); return 0; } @@ -1389,34 +1519,13 @@ int CmdHF14AMfECFill(const char *Cmd) int CmdHF14AMfEKeyPrn(const char *Cmd) { int i; - uint8_t numSectors; uint8_t data[16]; uint64_t keyA, keyB; - if (param_getchar(Cmd, 0) == 'h') { - PrintAndLog("It prints the keys loaded in the emulator memory"); - PrintAndLog("Usage: hf mf ekeyprn [card memory]"); - PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); - PrintAndLog(""); - PrintAndLog(" sample: hf mf ekeyprn 1"); - return 0; - } - - char cmdp = param_getchar(Cmd, 0); - - switch (cmdp) { - case '0' : numSectors = 5; break; - case '1' : - case '\0': numSectors = 16; break; - case '2' : numSectors = 32; break; - case '4' : numSectors = 40; break; - default: numSectors = 16; - } - PrintAndLog("|---|----------------|----------------|"); PrintAndLog("|sec|key A |key B |"); PrintAndLog("|---|----------------|----------------|"); - for (i = 0; i < numSectors; i++) { + for (i = 0; i < 40; i++) { if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1)) { PrintAndLog("error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); break; @@ -1458,9 +1567,9 @@ int CmdHF14AMfCSetUID(const char *Cmd) res = mfCSetUID(uid, oldUid, wipeCard); if (res) { - PrintAndLog("Can't set UID. error=%d", res); - return 1; - } + PrintAndLog("Can't set UID. error=%d", res); + return 1; + } PrintAndLog("old UID:%s", sprint_hex(oldUid, 4)); PrintAndLog("new UID:%s", sprint_hex(uid, 4)); @@ -1506,7 +1615,7 @@ int CmdHF14AMfCSetBlk(const char *Cmd) int CmdHF14AMfCLoad(const char *Cmd) { FILE * f; - char filename[FILE_PATH_SIZE]; + char filename[20]; char * fnameptr = filename; char buf[64]; uint8_t buf8[64]; @@ -1547,7 +1656,7 @@ int CmdHF14AMfCLoad(const char *Cmd) return 0; } else { len = strlen(Cmd); - if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; + if (len > 14) len = 14; memcpy(filename, Cmd, len); fnameptr += len; @@ -1592,7 +1701,7 @@ int CmdHF14AMfCLoad(const char *Cmd) } fclose(f); - if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){ + if (blockNum != 16 * 4){ PrintAndLog("File content error. There must be 64 blocks"); return 4; } @@ -1670,7 +1779,7 @@ int CmdHF14AMfCGetSc(const char *Cmd) { int CmdHF14AMfCSave(const char *Cmd) { FILE * f; - char filename[FILE_PATH_SIZE]; + char filename[20]; char * fnameptr = filename; uint8_t fillFromEmulator = 0; uint8_t buf[64]; @@ -1712,7 +1821,7 @@ int CmdHF14AMfCSave(const char *Cmd) { return 0; } else { len = strlen(Cmd); - if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; + if (len > 14) len = 14; if (len < 1) { // get filename @@ -1876,7 +1985,7 @@ int CmdHF14AMfSniff(const char *Cmd){ mfTraceDecode(bufPtr, len, wantSaveToEmlFile); } bufPtr += len; - bufPtr += ((len-1)/8+1); // ignore parity + bufPtr += ((len-1)/8+1); // ignore parity num++; } } @@ -1886,106 +1995,14 @@ int CmdHF14AMfSniff(const char *Cmd){ return 0; } -// Tries to identify cardsize. -// Returns where num is: -// -1 unidentified -// 0 - MINI (320bytes) -// 1 - 1K -// 2 - 2K -// 4 - 4K -int GetCardSize() -{ - UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}}; - SendCommand(&c); - - UsbCommand resp; - WaitForResponse(CMD_ACK,&resp); - - if(resp.arg[0] == 0) { - PrintAndLog("iso14443a card select failed"); - return -1; - } - - iso14a_card_select_t *card = (iso14a_card_select_t *)resp.d.asBytes; - - PrintAndLog("Trying to detect card size."); - - uint16_t atqa = 0; - uint8_t sak = 0; - atqa = (card->atqa[1] & 0xff) << 8; - atqa += card->atqa[0] & 0xff; - sak = card->sak; - - // https://code.google.com/p/libnfc/source/browse/libnfc/target-subr.c - - PrintAndLog("found ATAQ: %04X SAK: %02X", atqa, sak); - - - // NXP MIFARE Mini 0.3k - if ( ( (atqa & 0xff0f) == 0x0004) && (sak == 0x09) ) return 0; - - // MIFARE Classic 1K - if ( ((atqa & 0xff0f) == 0x0004) && (sak == 0x08) ) return 1; - - // MIFARE Classik 4K - if ( ((atqa & 0xff0f) == 0x0002) && (sak == 0x18) ) return 4; - - // SmartMX with MIFARE 1K emulation - if ( ((atqa & 0xf0ff) == 0x0004) ) return 1; - - // SmartMX with MIFARE 4K emulation - if ( ((atqa & 0xf0ff) == 0x0002) ) return 4; - - // Infineon MIFARE CLASSIC 1K - if ( ((atqa & 0xffff) == 0x0004) && (sak == 0x88) ) return 1; - - // MFC 4K emulated by Nokia 6212 Classic - if ( ((atqa & 0xffff) == 0x0002) && (sak == 0x38) ) return 4; - - // MFC 4K emulated by Nokia 6131 NFC - if ( ((atqa & 0xffff) == 0x0008) && (sak == 0x38) ) return 4; - - - PrintAndLog("BEFOOO 1K %02X", (atqa & 0xff0f)); - - // MIFARE Plus (4 Byte UID or 4 Byte RID) - // MIFARE Plus (7 Byte UID) - if ( - ((atqa & 0xffff) == 0x0002) | - ((atqa & 0xffff) == 0x0004) | - ((atqa & 0xffff) == 0x0042) | - ((atqa & 0xffff) == 0x0044) - ) - { - switch(sak){ - case 0x08: - case 0x10: { - //case 0x20: - PrintAndLog("2"); - return 2; - break; - } - case 0x11: - case 0x18:{ - //case 0x20: - PrintAndLog("4"); - return 4; - break; - } - } - } - - return -1; -} - static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"}, {"rdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"}, - //{"urdbl", CmdHF14AMfURdBl, 0, "Read MIFARE Ultralight block"}, - //{"urdcard", CmdHF14AMfURdCard, 0,"Read MIFARE Ultralight Card"}, - //{"uwrbl", CmdHF14AMfUWrBl, 0,"Write MIFARE Ultralight block"}, + {"urdbl", CmdHF14AMfURdBl, 0, "Read MIFARE Ultralight block"}, + {"urdcard", CmdHF14AMfURdCard, 0,"Read MIFARE Ultralight Card"}, + {"uwrbl", CmdHF14AMfUWrBl, 0,"Write MIFARE Ultralight block"}, {"rdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"}, {"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"}, {"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"}, diff --git a/client/cmdhfmf.h b/client/cmdhfmf.h index 45ba7cb1..22dfd4de 100644 --- a/client/cmdhfmf.h +++ b/client/cmdhfmf.h @@ -16,11 +16,11 @@ #include #include #include "proxmark3.h" -#include "../common/iso14443crc.h" +#include "iso14443crc.h" #include "data.h" #include "ui.h" #include "cmdparser.h" -#include "../include/common.h" +#include "common.h" #include "util.h" #include "mifarehost.h" @@ -53,5 +53,5 @@ int CmdHF14AMfCGetBlk(const char* cmd); int CmdHF14AMfCGetSc(const char* cmd); int CmdHF14AMfCLoad(const char* cmd); int CmdHF14AMfCSave(const char* cmd); -int GetCardSize(); + #endif diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c deleted file mode 100644 index 75aaa084..00000000 --- a/client/cmdhfmfdes.c +++ /dev/null @@ -1,685 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2014 Iceman -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// High frequency MIFARE Desfire commands -//----------------------------------------------------------------------------- - -#include -#include -#include -#include -#include -#include "cmdmain.h" -#include "proxmark3.h" -#include "../include/common.h" -#include "../include/mifare.h" -#include "../common/iso14443crc.h" -#include "data.h" -#include "ui.h" -#include "cmdparser.h" -#include "util.h" -#include "cmdhfmfdes.h" - -uint8_t CMDPOS = 0; -uint8_t LENPOS = 1; - -uint8_t key_zero_data[16] = { 0x00 }; -uint8_t key_ones_data[16] = { 0x01 }; -uint8_t key_defa_data[16] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }; -uint8_t key_picc_data[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f }; - -static int CmdHelp(const char *Cmd); -static void xor(unsigned char * dst, unsigned char * src, size_t len); -static int32_t le24toh (uint8_t data[3]); - - -int CmdHF14ADesWb(const char *Cmd) -{ -/* uint8_t blockNo = 0; - uint8_t keyType = 0; - uint8_t key[6] = {0, 0, 0, 0, 0, 0}; - uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - - char cmdp = 0x00; - - if (strlen(Cmd)<3) { - PrintAndLog("Usage: hf mf wrbl "); - PrintAndLog(" sample: hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F"); - return 0; - } - - blockNo = param_get8(Cmd, 0); - cmdp = param_getchar(Cmd, 1); - if (cmdp == 0x00) { - PrintAndLog("Key type must be A or B"); - return 1; - } - if (cmdp != 'A' && cmdp != 'a') keyType = 1; - if (param_gethex(Cmd, 2, key, 12)) { - PrintAndLog("Key must include 12 HEX symbols"); - return 1; - } - if (param_gethex(Cmd, 3, bldata, 32)) { - PrintAndLog("Block data must include 32 HEX symbols"); - return 1; - } - PrintAndLog("--block no:%02x key type:%02x key:%s", blockNo, keyType, sprint_hex(key, 6)); - PrintAndLog("--data: %s", sprint_hex(bldata, 16)); - - UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}}; - memcpy(c.d.asBytes, key, 6); - memcpy(c.d.asBytes + 10, bldata, 16); - SendCommand(&c); - - UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - */ - return 0; -} - -int CmdHF14ADesRb(const char *Cmd) -{ - // uint8_t blockNo = 0; - // uint8_t keyType = 0; - // uint8_t key[6] = {0, 0, 0, 0, 0, 0}; - - // char cmdp = 0x00; - - - // if (strlen(Cmd)<3) { - // PrintAndLog("Usage: hf mf rdbl "); - // PrintAndLog(" sample: hf mf rdbl 0 A FFFFFFFFFFFF "); - // return 0; - // } - - // blockNo = param_get8(Cmd, 0); - // cmdp = param_getchar(Cmd, 1); - // if (cmdp == 0x00) { - // PrintAndLog("Key type must be A or B"); - // return 1; - // } - // if (cmdp != 'A' && cmdp != 'a') keyType = 1; - // if (param_gethex(Cmd, 2, key, 12)) { - // PrintAndLog("Key must include 12 HEX symbols"); - // return 1; - // } - // PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo, keyType, sprint_hex(key, 6)); - - // UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}}; - // memcpy(c.d.asBytes, key, 6); - // SendCommand(&c); - - // UsbCommand resp; - // if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - // uint8_t isOK = resp.arg[0] & 0xff; - // uint8_t * data = resp.d.asBytes; - - // if (isOK) - // PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 16)); - // else - // PrintAndLog("isOk:%02x", isOK); - // } else { - // PrintAndLog("Command execute timeout"); - // } - - return 0; -} - -int CmdHF14ADesInfo(const char *Cmd){ - - UsbCommand c = {CMD_MIFARE_DESFIRE_INFO}; - SendCommand(&c); - UsbCommand resp; - - if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) { - PrintAndLog("Command execute timeout"); - return 0; - } - uint8_t isOK = resp.arg[0] & 0xff; - if ( !isOK ){ - PrintAndLog("Command unsuccessful"); - return 0; - } - PrintAndLog(""); - PrintAndLog("-- Desfire Information --------------------------------------"); - PrintAndLog("-------------------------------------------------------------"); - PrintAndLog(" UID : %s",sprint_hex(resp.d.asBytes, 7)); - PrintAndLog(" Batch number : %s",sprint_hex(resp.d.asBytes+28,5)); - PrintAndLog(" Production date : week %02x, 20%02x",resp.d.asBytes[33], resp.d.asBytes[34]); - PrintAndLog(" -----------------------------------------------------------"); - PrintAndLog(" Hardware Information"); - PrintAndLog(" Vendor Id : %s", GetVendorStr(resp.d.asBytes[7])); - PrintAndLog(" Type : 0x%02X",resp.d.asBytes[8]); - PrintAndLog(" Subtype : 0x%02X",resp.d.asBytes[9]); - PrintAndLog(" Version : %d.%d",resp.d.asBytes[10], resp.d.asBytes[11]); - PrintAndLog(" Storage size : %s",GetCardSizeStr(resp.d.asBytes[12])); - PrintAndLog(" Protocol : %s",GetProtocolStr(resp.d.asBytes[13])); - PrintAndLog(" -----------------------------------------------------------"); - PrintAndLog(" Software Information"); - PrintAndLog(" Vendor Id : %s",GetVendorStr(resp.d.asBytes[14])); - PrintAndLog(" Type : 0x%02X",resp.d.asBytes[15]); - PrintAndLog(" Subtype : 0x%02X",resp.d.asBytes[16]); - PrintAndLog(" Version : %d.%d",resp.d.asBytes[17], resp.d.asBytes[18]); - PrintAndLog(" storage size : %s", GetCardSizeStr(resp.d.asBytes[19])); - PrintAndLog(" Protocol : %s", GetProtocolStr(resp.d.asBytes[20])); - PrintAndLog("-------------------------------------------------------------"); - - // Master Key settings - GetKeySettings(NULL); - - // Free memory on card - c.cmd = CMD_MIFARE_DESFIRE; - c.arg[0] = (INIT | DISCONNECT); - c.arg[1] = 0x01; - c.d.asBytes[0] = GET_FREE_MEMORY; - SendCommand(&c); - if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - return 0; - } - - uint8_t tmp[3]; - memcpy(tmp, resp.d.asBytes+3,3); - - PrintAndLog(" Available free memory on card : %d bytes", le24toh( tmp )); - PrintAndLog("-------------------------------------------------------------"); - - /* - Card Master key (CMK) 0x00 AID = 00 00 00 (card level) - Application Master Key (AMK) 0x00 AID != 00 00 00 - Application keys (APK) 0x01-0x0D - Application free 0x0E - Application never 0x0F - - ACCESS RIGHTS: - keys 0,1,2,3 C - keys 4,5,6,7 RW - keys 8,9,10,11 W - keys 12,13,14,15 R - - */ - - return 1; -} - -char * GetVendorStr( uint8_t id){ - static char buf[30]; - char *retStr = buf; - - if ( id == 0x04 ) - sprintf(retStr, "0x%02X (NXP)",id); - else - sprintf(retStr,"0x%02X (Unknown)",id); - return buf; -} - -/* - The 7 MSBits (= n) code the storage size itself based on 2^n, - the LSBit is set to '0' if the size is exactly 2^n - and set to '1' if the storage size is between 2^n and 2^(n+1). - For this version of DESFire the 7 MSBits are set to 0x0C (2^12 = 4096) and the LSBit is '0'. -*/ -char * GetCardSizeStr( uint8_t fsize ){ - - static char buf[30]; - char *retStr = buf; - - uint16_t usize = 1 << ((fsize >>1) + 1); - uint16_t lsize = 1 << (fsize >>1); - - // is LSB set? - if ( fsize & (1 << 0 ) ) - sprintf(retStr, "0x%02X (%d - %d bytes)",fsize, usize, lsize); - else - sprintf(retStr, "0x%02X (%d bytes)", fsize, lsize); - return buf; -} - -char * GetProtocolStr(uint8_t id){ - - static char buf[30]; - char *retStr = buf; - - if ( id == 0x05) - sprintf(retStr,"0x%02X (ISO 14443-3, 14443-4)", id); - else - sprintf(retStr,"0x%02X", id); - return buf; -} - -void GetKeySettings( uint8_t *aid){ - - char messStr[512] = {0x00}; - char *str = messStr; - uint8_t isOK = 0; - uint32_t options = NONE; - UsbCommand c; - UsbCommand resp; - - //memset(messStr, 0x00, 512); - - c.cmd = CMD_MIFARE_DESFIRE; - - if ( aid == NULL ){ - PrintAndLog(" CMK - PICC, Card Master Key settings "); - PrintAndLog(""); - c.arg[CMDPOS] = (INIT | DISCONNECT); - c.arg[LENPOS] = 0x01; - c.d.asBytes[0] = GET_KEY_SETTINGS; // 0x45 - SendCommand(&c); - if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;} - isOK = resp.arg[0] & 0xff; - if ( !isOK ){ - PrintAndLog(" Can't select master application"); - return; - } - - str = (resp.d.asBytes[3] & (1 << 3 )) ? "YES":"NO"; - PrintAndLog(" [0x08] Configuration changeable : %s", str); - str = (resp.d.asBytes[3] & (1 << 2 )) ? "NO":"YES"; - PrintAndLog(" [0x04] CMK required for create/delete : %s",str); - str = (resp.d.asBytes[3] & (1 << 1 )) ? "NO":"YES"; - PrintAndLog(" [0x02] Directory list access with CMK : %s",str); - str = (resp.d.asBytes[3] & (1 << 0 )) ? "YES" : "NO"; - PrintAndLog(" [0x01] CMK is changeable : %s", str); - - c.arg[LENPOS] = 0x02; //LEN - c.d.asBytes[0] = GET_KEY_VERSION; //0x64 - c.d.asBytes[1] = 0x00; - SendCommand(&c); - if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) { - return; - } - isOK = resp.arg[0] & 0xff; - if ( !isOK ){ - PrintAndLog(" Can't read key-version"); - return; - } - PrintAndLog(""); - PrintAndLog(" Max number of keys : %d", resp.d.asBytes[4]); - PrintAndLog(" Master key Version : %d (0x%02x)", resp.d.asBytes[3], resp.d.asBytes[3]); - PrintAndLog(" ----------------------------------------------------------"); - - c.arg[LENPOS] = 0x02; //LEN - c.d.asBytes[0] = AUTHENTICATE; //0x0A - c.d.asBytes[1] = 0x00; // KEY 0 - SendCommand(&c); - if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;} - isOK = resp.d.asBytes[2] & 0xff; - PrintAndLog(" [0x0A] Authenticate : %s", ( isOK==0xAE ) ? "NO":"YES"); - - c.d.asBytes[0] = AUTHENTICATE_ISO; //0x1A - SendCommand(&c); - if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;} - isOK = resp.d.asBytes[2] & 0xff; - PrintAndLog(" [0x1A] Authenticate ISO : %s", ( isOK==0xAE ) ? "NO":"YES"); - - c.d.asBytes[0] = AUTHENTICATE_AES; //0xAA - SendCommand(&c); - if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;} - isOK = resp.d.asBytes[2] & 0xff; - PrintAndLog(" [0xAA] Authenticate AES : %s", ( isOK==0xAE ) ? "NO":"YES"); - PrintAndLog(""); - PrintAndLog(" ----------------------------------------------------------"); - - } else { - PrintAndLog(" AMK - Application Master Key settings"); - - // SELECT AID - c.arg[0] = (INIT | CLEARTRACE); - c.arg[LENPOS] = 0x04; - c.d.asBytes[0] = SELECT_APPLICATION; // 0x5a - memcpy(c.d.asBytes+1, aid, 3); - SendCommand(&c); - - if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) { - PrintAndLog(" Timed-out"); - return; - } - isOK = resp.arg[0] & 0xff; - if ( !isOK ){ - PrintAndLog(" Can't select AID: %s",sprint_hex(aid,3)); - return; - } - - // KEY SETTINGS - options = NONE; - c.arg[0] = options; - c.arg[LENPOS] = 0x01; - c.d.asBytes[0] = GET_KEY_SETTINGS; // 0x45 - SendCommand(&c); - if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) { - return; - } - isOK = resp.arg[0] & 0xff; - if ( !isOK ){ - PrintAndLog(" Can't read Application Master key settings"); - } else { - // Access rights. - uint8_t rights = (resp.d.asBytes[3] >> 4 && 0xff); - switch (rights){ - case 0x00: - str = "AMK authentication is necessary to change any key (default)"; - break; - case 0x0e: - str = "Authentication with the key to be changed (same KeyNo) is necessary to change a key"; - break; - case 0x0f: - str = "All keys (except AMK,see Bit0) within this application are frozen"; - break; - default: - str = "Authentication with the specified key is necessary to change any ley. A change key and a PICC master key (CMK) can only be changed after authentication with the master key. For keys other then the master or change key, an authentication with the same key is needed."; - break; - } - PrintAndLog("Changekey Access rights"); - PrintAndLog("-- %s",str); - PrintAndLog(""); - // same as CMK - str = (resp.d.asBytes[3] & (1 << 3 )) ? "YES":"NO"; - PrintAndLog(" 0x08 Configuration changeable : %s", str); - str = (resp.d.asBytes[3] & (1 << 2 )) ? "NO":"YES"; - PrintAndLog(" 0x04 AMK required for create/delete : %s",str); - str = (resp.d.asBytes[3] & (1 << 1 )) ? "NO":"YES"; - PrintAndLog(" 0x02 Directory list access with AMK : %s",str); - str = (resp.d.asBytes[3] & (1 << 0 )) ? "YES" : "NO"; - PrintAndLog(" 0x01 AMK is changeable : %s", str); - } - - // KEY VERSION - AMK - c.arg[0] = NONE; - c.arg[LENPOS] = 0x02; - c.d.asBytes[0] = GET_KEY_VERSION; //0x64 - c.d.asBytes[1] = 0x00; - SendCommand(&c); - if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) { - PrintAndLog(" Timed-out"); - return; - } - - int numOfKeys; - - isOK = resp.arg[0] & 0xff; - if ( !isOK ){ - PrintAndLog(" Can't read Application Master key version. Trying all keys"); - numOfKeys = MAX_NUM_KEYS; - } - else{ - numOfKeys = resp.d.asBytes[4]; - PrintAndLog(""); - PrintAndLog(" Max number of keys : %d", numOfKeys ); - PrintAndLog(" Application Master key Version : %d (0x%02x)", resp.d.asBytes[3], resp.d.asBytes[3]); - PrintAndLog("-------------------------------------------------------------"); - } - - // LOOP over numOfKeys that we got before. - // From 0x01 to numOfKeys. We already got 0x00. (AMK) - for(int i=0x01; i<=0x0f; ++i){ - - } - - - } -} - -int CmdHF14ADesEnumApplications(const char *Cmd){ - - uint8_t isOK = 0x00; - uint8_t aid[3]; - uint32_t options = (INIT | DISCONNECT); - - UsbCommand c = {CMD_MIFARE_DESFIRE, {options , 0x01 }}; - c.d.asBytes[0] = GET_APPLICATION_IDS; //0x6a - - SendCommand(&c); - UsbCommand resp; - - if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) { - return 0; - } - isOK = resp.arg[0] & 0xff; - if ( !isOK ){ - PrintAndLog("Command unsuccessful"); - return 0; - } - PrintAndLog(""); - PrintAndLog("-- Desfire Enumerate Applications ---------------------------"); - PrintAndLog("-------------------------------------------------------------"); - - UsbCommand respAid; - UsbCommand respFiles; - - uint8_t num = 0; - int max = resp.arg[1] -3 -2; - - for(int i=3; i<=max; i+=3){ - PrintAndLog(" Aid %d : %02X %02X %02X ",num ,resp.d.asBytes[i],resp.d.asBytes[i+1],resp.d.asBytes[i+2]); - num++; - - aid[0] = resp.d.asBytes[i]; - aid[1] = resp.d.asBytes[i+1]; - aid[2] = resp.d.asBytes[i+2]; - GetKeySettings(aid); - - // Select Application - c.arg[CMDPOS] = INIT; - c.arg[LENPOS] = 0x04; - c.d.asBytes[0] = SELECT_APPLICATION; // 0x5a - c.d.asBytes[1] = resp.d.asBytes[i]; - c.d.asBytes[2] = resp.d.asBytes[i+1]; - c.d.asBytes[3] = resp.d.asBytes[i+2]; - SendCommand(&c); - - if (!WaitForResponseTimeout(CMD_ACK,&respAid,1500) ) { - PrintAndLog(" Timed-out"); - continue; - } - isOK = respAid.d.asBytes[2] & 0xff; - if ( isOK != 0x00 ){ - PrintAndLog(" Can't select AID: %s",sprint_hex(resp.d.asBytes+i,3)); - continue; - } - - // Get File IDs - c.arg[CMDPOS] = NONE; - c.arg[LENPOS] = 0x01; - c.d.asBytes[0] = GET_FILE_IDS; // 0x6f - SendCommand(&c); - - if ( !WaitForResponseTimeout(CMD_ACK,&respFiles,1500) ) { - PrintAndLog(" Timed-out"); - continue; - } else { - isOK = respFiles.d.asBytes[2] & 0xff; - if ( !isOK ){ - PrintAndLog(" Can't get file ids "); - } else { - int respfileLen = resp.arg[1]-3-2; - for (int j=0; j< respfileLen; ++j){ - PrintAndLog(" Fileid %d :", resp.d.asBytes[j+3]); - } - } - } - - // Get ISO File IDs - c.arg[CMDPOS] = DISCONNECT; - c.arg[LENPOS] = 0x01; - c.d.asBytes[0] = GET_ISOFILE_IDS; // 0x61 - SendCommand(&c); - - if ( !WaitForResponseTimeout(CMD_ACK,&respFiles,1500) ) { - PrintAndLog(" Timed-out"); - continue; - } else { - isOK = respFiles.d.asBytes[2] & 0xff; - if ( !isOK ){ - PrintAndLog(" Can't get ISO file ids "); - } else { - int respfileLen = resp.arg[1]-3-2; - for (int j=0; j< respfileLen; ++j){ - PrintAndLog(" ISO Fileid %d :", resp.d.asBytes[j+3]); - } - } - } - - - } - PrintAndLog("-------------------------------------------------------------"); - - - return 1; -} - -// MIAFRE DesFire Authentication -// -#define BUFSIZE 256 -int CmdHF14ADesAuth(const char *Cmd){ - - // NR DESC KEYLENGHT - // ------------------------ - // 1 = DES 8 - // 2 = 3DES 16 - // 3 = 3K 3DES 24 - // 4 = AES 16 - - uint8_t keylength = 8; - unsigned char key[24]; - - if (strlen(Cmd)<3) { - PrintAndLog("Usage: hf mfdes auth <1|2|3> <1|2|3|4> "); - PrintAndLog(" Auth modes"); - PrintAndLog(" 1 = normal, 2 = iso, 3 = aes"); - PrintAndLog(" Crypto"); - PrintAndLog(" 1 = DES 2 = 3DES 3 = 3K3DES 4 = AES"); - PrintAndLog(""); - PrintAndLog(" sample: hf mfdes auth 1 1 0 11223344"); - PrintAndLog(" sample: hf mfdes auth 3 4 0 404142434445464748494a4b4c4d4e4f"); - return 0; - } - uint8_t cmdAuthMode = param_get8(Cmd,0); - uint8_t cmdAuthAlgo = param_get8(Cmd,1); - uint8_t cmdKeyNo = param_get8(Cmd,2); - - switch (cmdAuthMode) - { - case 1: - if ( cmdAuthAlgo != 1 && cmdAuthAlgo != 2) { - PrintAndLog("Crypto algo not valid for the auth mode"); - return 1; - } - break; - case 2: - if ( cmdAuthAlgo != 1 && cmdAuthAlgo != 2 && cmdAuthAlgo != 3) { - PrintAndLog("Crypto algo not valid for the auth mode"); - return 1; - } - break; - case 3: - if ( cmdAuthAlgo != 4) { - PrintAndLog("Crypto algo not valid for the auth mode"); - return 1; - } - break; - default: - PrintAndLog("Wrong Auth mode"); - return 1; - break; - } - - switch (cmdAuthAlgo){ - case 2: - keylength = 16; - PrintAndLog("3DES selected"); - break; - case 3: - keylength = 24; - PrintAndLog("3 key 3DES selected"); - break; - case 4: - keylength = 16; - PrintAndLog("AES selected"); - break; - default: - cmdAuthAlgo = 1; - keylength = 8; - PrintAndLog("DES selected"); - break; - } - - // key - if (param_gethex(Cmd, 3, key, keylength*2)) { - PrintAndLog("Key must include %d HEX symbols", keylength); - return 1; - } - // algo, nyckellängd, - UsbCommand c = {CMD_MIFARE_DESFIRE_AUTH1, { cmdAuthMode, cmdAuthAlgo, cmdKeyNo }}; - - c.d.asBytes[0] = keylength; - memcpy(c.d.asBytes+1, key, keylength); - - SendCommand(&c); - UsbCommand resp; - - if (!WaitForResponseTimeout(CMD_ACK,&resp,3000)) { - PrintAndLog("Client command execute timeout"); - return 0; - } - - uint8_t isOK = resp.arg[0] & 0xff; - if ( isOK) { - uint8_t * data= resp.d.asBytes; - - PrintAndLog(" Key :%s",sprint_hex(key, keylength)); - PrintAndLog(" SESSION :%s",sprint_hex(data, keylength)); - PrintAndLog("-------------------------------------------------------------"); - //PrintAndLog(" Expected :B5 21 9E E8 1A A7 49 9D 21 96 68 7E 13 97 38 56"); - } else{ - PrintAndLog("Client command failed."); - } - PrintAndLog("-------------------------------------------------------------"); - return 1; -} - - -static void xor(unsigned char * dst, unsigned char * src, size_t len) { - for( ; len > 0; len--,dst++,src++) - *dst ^= *src; -} - -static int32_t le24toh (uint8_t data[3]) { - return (data[2] << 16) | (data[1] << 8) | data[0]; -} - -static command_t CommandTable[] = -{ - {"help", CmdHelp, 1, "This help"}, - {"auth", CmdHF14ADesAuth, 0, "Tries a MIFARE DesFire Authentication"}, - {"rb", CmdHF14ADesRb, 0, "Read MIFARE DesFire block"}, - {"wb", CmdHF14ADesWb, 0, "write MIFARE DesFire block"}, - {"info", CmdHF14ADesInfo, 0, "Get MIFARE DesFire information"}, - {"enum", CmdHF14ADesEnumApplications,0, "Tries enumerate all applications"}, - {NULL, NULL, 0, NULL} -}; - -int CmdHFMFDes(const char *Cmd) -{ - // flush - WaitForResponseTimeout(CMD_ACK,NULL,100); - CmdsParse(CommandTable, Cmd); - return 0; -} - -int CmdHelp(const char *Cmd) -{ - CmdsHelp(CommandTable); - return 0; -} - - diff --git a/client/cmdhfmfdes.h b/client/cmdhfmfdes.h deleted file mode 100644 index 6ebc98ae..00000000 --- a/client/cmdhfmfdes.h +++ /dev/null @@ -1,75 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2014 Iceman -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// High frequency MIFARE Desfire commands -//----------------------------------------------------------------------------- - -int CmdHFMFDes(const char *Cmd); -int CmdHF14ADesAuth(const char* cmd); -int CmdHF14ADesRb(const char* cmd); -int CmdHF14ADesWb(const char* cmd); -int CmdHF14ADesInfo(const char *Cmd); -int CmdHF14ADesEnumApplications(const char *Cmd); - -char * GetCardSizeStr( uint8_t fsize ); -char * GetVendorStr( uint8_t id); -char * GetProtocolStr(uint8_t id); -void GetKeySettings( uint8_t * aid); - -// Command options for Desfire behavior. -enum { - NONE = 0x00, - INIT = 0x01, - DISCONNECT = 0x02, - CLEARTRACE = 0x04, - BAR = 0x08, -} CmdOptions ; - - -#define CREATE_APPLICATION 0xca -#define DELETE_APPLICATION 0xda -#define GET_APPLICATION_IDS 0x6a -#define SELECT_APPLICATION 0x5a -#define FORMAT_PICC 0xfc -#define GET_VERSION 0x60 -#define READ_DATA 0xbd -#define WRITE_DATA 0x3d -#define GET_VALUE 0x6c -#define CREDIT 0x0c -#define DEBIT 0xdc -#define LIMITED_CREDIT 0x1c -#define WRITE_RECORD 0x3b -#define READ_RECORDS 0xbb -#define CLEAR_RECORD_FILE 0xeb -#define COMMIT_TRANSACTION 0xc7 -#define ABORT_TRANSACTION 0xa7 -#define GET_FREE_MEMORY 0x6e -#define GET_FILE_IDS 0x6f -#define GET_ISOFILE_IDS 0x61 -#define GET_FILE_SETTINGS 0xf5 -#define CHANGE_FILE_SETTINGS 0x5f -#define CREATE_STD_DATA_FILE 0xcd -#define CREATE_BACKUP_DATA_FILE 0xcb -#define CREATE_VALUE_FILE 0xcc -#define CREATE_LINEAR_RECORD_FILE 0xc1 -#define CREATE_CYCLIC_RECORD_FILE 0xc0 -#define DELETE_FILE 0xdf -#define AUTHENTICATE 0x0a // AUTHENTICATE_NATIVE -#define AUTHENTICATE_ISO 0x1a // AUTHENTICATE_STANDARD -#define AUTHENTICATE_AES 0xaa -#define CHANGE_KEY_SETTINGS 0x54 -#define GET_KEY_SETTINGS 0x45 -#define CHANGE_KEY 0xc4 -#define GET_KEY_VERSION 0x64 -#define AUTHENTICATION_FRAME 0xAF - -#define MAX_NUM_KEYS 0x0F -#define MAX_APPLICATION_COUNT 28 -#define MAX_FILE_COUNT 32 -#define MAX_FRAME_SIZE 60 -#define NOT_YET_AUTHENTICATED 255 -#define FRAME_PAYLOAD_SIZE (MAX_FRAME_SIZE - 5) \ No newline at end of file diff --git a/client/cmdhfmfdesfire.c b/client/cmdhfmfdesfire.c deleted file mode 100644 index f2c53dbf..00000000 --- a/client/cmdhfmfdesfire.c +++ /dev/null @@ -1,250 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2014 Andy Davies -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// High frequency MIFARE commands -//----------------------------------------------------------------------------- - -#include "cmdhfmf.h" -#include "util.h" -#include -#include - -static int CmdHelp(const char *Cmd); - -//DESFIRE -// Reader 2 Card : 020A, key (1 byte), CRC1 CRC2 ; auth (020a00) -// Card 2 Reader : 02AF, 8 Bytes(b0), CRC1 CRC2 -// Reader 2 Card : 03AF, 8 Bytes(b1),8 bytes(b2), CRC1 CRC2 -// Card 2 Reader : 0300, 8 bytes(b3), CRC1 CRC2 ; success - -//send 020A00, receive enc(nc) - -//02AE = error -//receive b3=enc(r4) -//r5=dec(b3) -//n'r=rol(r5) -//verify n'r=nr - -int CmdHF14AMfDESAuth(const char *Cmd){ - - uint8_t blockNo = 0; - //keyNo=0; - uint32_t cuid=0; - uint8_t reply[16]; - //DES_cblock r1_b1; - uint8_t b1[8]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t b2[8]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - DES_cblock nr, b0, r1, r0; - - - uint8_t key[8]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - //DES_cblock iv={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - DES_key_schedule ks1; - DES_cblock key1; - - if (strlen(Cmd)<1) { - PrintAndLog("Usage: hf desfire des-auth k "); - PrintAndLog(" sample: hf desfire des-auth k 0"); - return 0; - } - - //Change key to user defined one - - memcpy(key1,key,8); - //memcpy(key2,key+8,8); - DES_set_key((DES_cblock *)key1,&ks1); - //DES_set_key((DES_cblock *)key2,&ks2); - - //Auth1 - UsbCommand c = {CMD_MIFARE_DES_AUTH1, {blockNo}}; - SendCommand(&c); - UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - cuid = resp.arg[1]; - uint8_t * data= resp.d.asBytes; - - if (isOK){ - PrintAndLog("enc(nc)/b0:%s", sprint_hex(data+2,8)); - memcpy(b0,data+2,8); - } - } else { - PrintAndLog("Command execute timeout"); - } - - //Do crypto magic - DES_random_key(&nr); - //b1=dec(nr) - //r0=dec(b0) - DES_ecb_encrypt(&nr,&b1,&ks1,0); - DES_ecb_encrypt(&b0,&r0,&ks1,0); - //PrintAndLog("b1:%s",sprint_hex(b1, 8)); - PrintAndLog("r0:%s",sprint_hex(r0, 8)); - //r1=rol(r0) - memcpy(r1,r0,8); - rol(r1,8); - PrintAndLog("r1:%s",sprint_hex(r1, 8)); - for(int i=0;i<8;i++){ - b2[i]=(r1[i] ^ b1[i]); - } - DES_ecb_encrypt(&b2,&b2,&ks1,0); - //PrintAndLog("b1:%s",sprint_hex(b1, 8)); - PrintAndLog("b2:%s",sprint_hex(b2, 8)); - - //Auth2 - UsbCommand d = {CMD_MIFARE_DES_AUTH2, {cuid}}; - memcpy(reply,b1,8); - memcpy(reply+8,b2,8); - memcpy(d.d.asBytes,reply, 16); - SendCommand(&d); - - UsbCommand respb; - if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) { - uint8_t isOK = respb.arg[0] & 0xff; - uint8_t * data2= respb.d.asBytes; - - if (isOK){ - PrintAndLog("b3:%s", sprint_hex(data2+2, 8)); - } - - } else { - PrintAndLog("Command execute timeout"); - } - return 1; -} - -//EV1 -// Reader 2 Card : 02AA, key (1 byte), CRC1 CRC2 ; auth -// Card 2 Reader : 02AF, 16 Bytes(b0), CRC1 CRC2 -// Reader 2 Card : 03AF, 16 Bytes(b1),16Bytes(b2) CRC1 CRC2 -// Card 2 Reader : 0300, 16 bytes(b3), CRC1 CRC2 ; success -int CmdHF14AMfAESAuth(const char *Cmd){ - - uint8_t blockNo = 0; - //keyNo=0; - uint32_t cuid=0; - uint8_t reply[32]; - //DES_cblock r1_b1; - //unsigned char * b1, b2, nr, b0, r0, r1; - - uint8_t b1[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t b2[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t nr[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t b0[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t r0[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t r1[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - // - uint8_t key[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t iv[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - AES_KEY key_e; - AES_KEY key_d; - - if (strlen(Cmd)<1) { - PrintAndLog("Usage: hf desfire aes-auth k "); - PrintAndLog(" sample: hf desfire aes-auth k 0"); - return 0; - } - - //Change key to user defined one - // - // int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,AES_KEY *key); - //int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,AES_KEY *key); - // - //memcpy(key1,key,16); - //memcpy(key2,key+8,8); - AES_set_encrypt_key(key,128,&key_e); - AES_set_decrypt_key(key,128,&key_d); - - //Auth1 - UsbCommand c = {CMD_MIFARE_DES_AUTH1, {blockNo}}; - SendCommand(&c); - UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - cuid = resp.arg[1]; - uint8_t * data= resp.d.asBytes; - - if (isOK){ - PrintAndLog("enc(nc)/b0:%s", sprint_hex(data+2,16)); - memcpy(b0,data+2,16); - } - } else { - PrintAndLog("Command execute timeout"); - } - // - // void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, - //size_t length, const AES_KEY *key, - //unsigned char *ivec, const int enc); - - //Do crypto magic - //DES_random_key(&nr); - //b1=dec(nr) - //r0=dec(b0) - //AES_cbc_encrypt(&nr,&b1,16,&key,0); - AES_cbc_encrypt(&b0,&r0,16,&key_d,iv,0); - //PrintAndLog("b1:%s",sprint_hex(b1, 8)); - PrintAndLog("r0:%s",sprint_hex(r0, 16)); - //r1=rol(r0) - memcpy(r1,r0,16); - rol(r1,8); - PrintAndLog("r1:%s",sprint_hex(r1, 16)); - for(int i=0;i<16;i++){ - b1[i]=(nr[i] ^ b0[i]); - b2[i]=(r1[i] ^ b1[i]); - } - PrintAndLog("nr:%s",sprint_hex(nr, 16)); - AES_cbc_encrypt(&b1,&b1,16,&key_e,iv,1); - AES_cbc_encrypt(&b2,&b2,16,&key_e,iv,1); - PrintAndLog("b1:%s",sprint_hex(b1, 16)); - PrintAndLog("b2:%s",sprint_hex(b2, 16)); - - //Auth2 - UsbCommand d = {CMD_MIFARE_DES_AUTH2, {cuid}}; - memcpy(reply,b1,16); - memcpy(reply+16,b2,16); - memcpy(d.d.asBytes,reply, 32); - SendCommand(&d); - - UsbCommand respb; - if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) { - uint8_t isOK = respb.arg[0] & 0xff; - uint8_t * data2= respb.d.asBytes; - - if (isOK){ - PrintAndLog("b3:%s", sprint_hex(data2+2, 16)); - } - - } else { - PrintAndLog("Command execute timeout"); - } - return 1; -} - - -//------------------------------------ -// Menu Stuff -//------------------------------------ -static command_t CommandTable[] = -{ - {"help", CmdHelp, 1,"This help"}, - {"dbg", CmdHF14AMfDbg, 0,"Set default debug mode"}, - {"des-auth",CmdHF14AMfDESAuth, 0,"Desfire Authentication"}, - {"ev1-auth",CmdHF14AMfAESAuth, 0,"EV1 Authentication"}, - {NULL, NULL, 0, NULL} -}; - -int CmdHFMFDesfire(const char *Cmd){ - // flush - WaitForResponseTimeout(CMD_ACK,NULL,100); - CmdsParse(CommandTable, Cmd); - return 0; -} - -int CmdHelp(const char *Cmd){ - CmdsHelp(CommandTable); - return 0; -} diff --git a/client/cmdhfmfdesfire.h b/client/cmdhfmfdesfire.h deleted file mode 100644 index c29fd262..00000000 --- a/client/cmdhfmfdesfire.h +++ /dev/null @@ -1,5 +0,0 @@ - -static int CmdHelp(const char *Cmd); -int CmdHF14AMfDESAuth(const char *Cmd); -int CmdHFMFDesfire(const char *Cmd); -int CmdHelp(const char *Cmd); \ No newline at end of file diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c deleted file mode 100644 index 52b7ad14..00000000 --- a/client/cmdhfmfu.c +++ /dev/null @@ -1,1157 +0,0 @@ -//----------------------------------------------------------------------------- -// Ultralight Code (c) 2013,2014 Midnitesnake & Andy Davies of Pentura -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// High frequency MIFARE ULTRALIGHT (C) commands -//----------------------------------------------------------------------------- -#include -#include "cmdhfmf.h" - -uint8_t MAX_ULTRA_BLOCKS= 0x0f; -uint8_t MAX_ULTRAC_BLOCKS= 0x2c; -uint8_t key1_blnk_data[16] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -uint8_t key2_defa_data[16] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }; -uint8_t key3_3des_data[16] = { 0x49,0x45,0x4D,0x4B,0x41,0x45,0x52,0x42,0x21,0x4E,0x41,0x43,0x55,0x4F,0x59,0x46 }; -uint8_t key4_nfc_data[16] = { 0x42,0x52,0x45,0x41,0x4b,0x4d,0x45,0x49,0x46,0x59,0x4f,0x55,0x43,0x41,0x4e,0x21 }; -uint8_t key5_ones_data[16] = { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }; - -static int CmdHelp(const char *Cmd); - -// -// Mifare Ultralight Write Single Block -// -int CmdHF14AMfUWrBl(const char *Cmd){ - uint8_t blockNo = 0; - bool chinese_card = 0; - uint8_t bldata[16] = {0x00}; - UsbCommand resp; - - if (strlen(Cmd)<3) { - PrintAndLog("Usage: hf mfu uwrbl [w]"); - PrintAndLog(" sample: hf mfu uwrbl 0 01020304"); - return 0; - } - blockNo = param_get8(Cmd, 0); - if (blockNo>MAX_ULTRA_BLOCKS){ - PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!"); - return 1; - } - if (param_gethex(Cmd, 1, bldata, 8)) { - PrintAndLog("Block data must include 8 HEX symbols"); - return 1; - } - if (strchr(Cmd,'w') != 0) { - chinese_card=1; - } - switch(blockNo){ - case 0: - if (!chinese_card){ - PrintAndLog("Access Denied"); - }else{ - PrintAndLog("--specialblock no:%02x", blockNo); - PrintAndLog("--data: %s", sprint_hex(bldata, 4)); - UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}}; - memcpy(d.d.asBytes,bldata, 4); - SendCommand(&d); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - } - break; - case 1: - if (!chinese_card){ - PrintAndLog("Access Denied"); - }else{ - PrintAndLog("--specialblock no:%02x", blockNo); - PrintAndLog("--data: %s", sprint_hex(bldata, 4)); - UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}}; - memcpy(d.d.asBytes,bldata, 4); - SendCommand(&d); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - } - break; - case 2: - if (!chinese_card){ - PrintAndLog("Access Denied"); - }else{ - PrintAndLog("--specialblock no:%02x", blockNo); - PrintAndLog("--data: %s", sprint_hex(bldata, 4)); - UsbCommand c = {CMD_MIFAREU_WRITEBL, {blockNo}}; - memcpy(c.d.asBytes, bldata, 4); - SendCommand(&c); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - } - break; - case 3: - PrintAndLog("--specialblock no:%02x", blockNo); - PrintAndLog("--data: %s", sprint_hex(bldata, 4)); - UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}}; - memcpy(d.d.asBytes,bldata, 4); - SendCommand(&d); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - break; - default: - PrintAndLog("--block no:%02x", blockNo); - PrintAndLog("--data: %s", sprint_hex(bldata, 4)); - UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}}; - memcpy(e.d.asBytes,bldata, 4); - SendCommand(&e); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - break; - } - return 0; -} - -// -// Mifare Ultralight Read Single Block -// -int CmdHF14AMfURdBl(const char *Cmd){ - - uint8_t blockNo = 0; - - if (strlen(Cmd)<1) { - PrintAndLog("Usage: hf mfu urdbl "); - PrintAndLog(" sample: hfu mfu urdbl 0"); - return 0; - } - - blockNo = param_get8(Cmd, 0); - // if (blockNo>MAX_ULTRA_BLOCKS){ - // PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!"); - // return 1; - // } - PrintAndLog("--block no:%02x", (int)blockNo); - UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}}; - SendCommand(&c); - - UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - uint8_t * data = resp.d.asBytes; - - if (isOK) - PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4)); - else - PrintAndLog("isOk:%02x", isOK); - } - else { - PrintAndLog("Command execute timeout"); - } - return 0; -} - -// -// Mifare Ultralight Read (Dump) Card Contents -// -int CmdHF14AMfURdCard(const char *Cmd){ - int i; - uint8_t BlockNo = 0; - int pages=16; - uint8_t *lockbytes_t=NULL; - uint8_t lockbytes[2]={0x00}; - bool bit[16]={0x00}; - bool dump=false; - uint8_t datatemp[7]= {0x00}; - - uint8_t isOK = 0; - uint8_t * data = NULL; - FILE *fout = NULL; - - if (strchr(Cmd,'x') != 0){ - dump=true; - if ((fout = fopen("dump_ultralight_data.bin","wb")) == NULL) { - PrintAndLog("Could not create file name dumpdata.bin"); - return 1; - } - PrintAndLog("Dumping Ultralight Card Data..."); - } - PrintAndLog("Attempting to Read Ultralight... "); - UsbCommand c = {CMD_MIFAREU_READCARD, {BlockNo, pages}}; - SendCommand(&c); - UsbCommand resp; - - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - isOK = resp.arg[0] & 0xff; - data = resp.d.asBytes; - PrintAndLog("isOk:%02x", isOK); - if (isOK) { - - // UID - memcpy( datatemp, data,3); - memcpy( datatemp+3, data+4, 4); - PrintAndLog(" UID :%s ", sprint_hex(datatemp, 7)); - // BBC - // CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2 - int crc0 = 0x88 ^ data[0] ^ data[1] ^data[2]; - if ( data[3] == crc0 ) { - PrintAndLog(" BCC0 :%02x - Ok", data[3]); - } - else{ - PrintAndLog(" BCC0 :%02x - crc should be %02x", data[3], crc0); - } - - int crc1 = data[4] ^ data[5] ^ data[6] ^data[7]; - if ( data[8] == crc1 ){ - PrintAndLog(" BCC1 :%02x - Ok", data[8]); - } - else{ - PrintAndLog(" BCC1 :%02x - crc should be %02x", data[8], crc1 ); - } - - PrintAndLog(" Internal :%s ", sprint_hex(data + 9, 1)); - - memcpy(datatemp, data+10, 2); - PrintAndLog(" Lock :%s - %s", sprint_hex(datatemp, 2),printBits( 2, &datatemp) ); - - PrintAndLog(" OneTimePad :%s ", sprint_hex(data + 3*4, 4)); - PrintAndLog(""); - - for (i = 0; i < pages; i++) { - switch(i){ - case 2: - //process lock bytes - lockbytes_t=data+(i*4); - lockbytes[0]=lockbytes_t[2]; - lockbytes[1]=lockbytes_t[3]; - for(int j=0; j<16; j++){ - bit[j]=lockbytes[j/8] & ( 1 <<(7-j%8)); - } - PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4)); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 3: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[4]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 4: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[3]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 5: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[2]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 6: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[1]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 7: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[0]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 8: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[15]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 9: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[14]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 10: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[13]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 11: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[12]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 12: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[11]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 13: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[10]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 14: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[9]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 15: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[8]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - default: - PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4)); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - } - } - } - } else { - PrintAndLog("Command1 execute timeout"); - } - if (dump) fclose(fout); - return 0; -} - -int CmdHF14AMfUDump(const char *Cmd){ - int i; - uint8_t BlockNo = 0; - int Pages = 16; - uint8_t *lockbytes_t = NULL; - uint8_t lockbytes[2] = {0x00}; - bool bit[16] = {0x00}; - uint8_t datatemp[5] = {0x00}; - bool dump = true; - uint8_t isOK = 0; - uint8_t * data = NULL; - FILE *fout; - - if ((fout = fopen("dump_ultralight_data.bin","wb")) == NULL) { - PrintAndLog("Could not create file name dumpdata.bin"); - return 1; - } - PrintAndLog("Dumping Ultralight Card Data..."); - - PrintAndLog("Attempting to Read Ultralight... "); - UsbCommand c = {CMD_MIFAREU_READCARD, {BlockNo,Pages}}; - SendCommand(&c); - UsbCommand resp; - - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - isOK = resp.arg[0] & 0xff; - data = resp.d.asBytes; - PrintAndLog("isOk:%02x", isOK); - if (isOK) - for (i = 0; i < Pages; i++) { - switch(i){ - case 2: - //process lock bytes - lockbytes_t=data+(i*4); - lockbytes[0]=lockbytes_t[2]; - lockbytes[1]=lockbytes_t[3]; - for(int j=0; j<16; j++){ - bit[j]=lockbytes[j/8] & ( 1 <<(7-j%8)); - } - PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4)); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 3: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[4]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 4: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[3]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 5: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[2]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 6: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[1]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 7: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[0]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 8: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[15]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 9: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[14]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 10: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[13]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 11: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[12]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 12: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[11]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 13: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[10]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 14: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[9]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 15: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[8]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - default: - PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4)); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - } - } - } else { - PrintAndLog("Command1 execute timeout"); - } - if (dump) fclose(fout); - return 0; -} - -// Needed to Authenticate to Ultralight C tags -void rol (uint8_t *data, const size_t len){ - uint8_t first = data[0]; - for (size_t i = 0; i < len-1; i++) { - data[i] = data[i+1]; - } - data[len-1] = first; -} - -//------------------------------------------------------------------------------- -// Ultralight C Methods -//------------------------------------------------------------------------------- - -// -// Ultralight C Authentication Demo {currently uses hard-coded key} -// -int CmdHF14AMfucAuth(const char *Cmd){ - - uint8_t blockNo = 0, keyNo=0; - uint8_t e_RndB[8] = {0x00}; - uint32_t cuid=0; - unsigned char RndARndB[16] = {0x00}; - uint8_t key[16] = {0x00}; - DES_cblock RndA, RndB; - DES_cblock iv; - DES_key_schedule ks1,ks2; - DES_cblock key1,key2; - - // - memset(iv, 0, 8); - - if (strlen(Cmd)<1) { - PrintAndLog("Usage: hf mfu auth k "); - PrintAndLog(" sample: hf mfu auth k 0"); - return 0; - } - - //Change key to user defined one - if (strchr(Cmd,'k') != 0){ - //choose a key - keyNo = param_get8(Cmd, 1); - switch(keyNo){ - case 0: - memcpy(key,key1_blnk_data,16); - break; - case 1: - memcpy(key,key2_defa_data,16); - break; - case 2: - memcpy(key,key4_nfc_data,16); - break; - case 3: - memcpy(key,key5_ones_data,16); - break; - default: - memcpy(key,key3_3des_data,16); - break; - } - }else{ - memcpy(key,key3_3des_data,16); - } - memcpy(key1,key,8); - memcpy(key2,key+8,8); - DES_set_key((DES_cblock *)key1,&ks1); - DES_set_key((DES_cblock *)key2,&ks2); - - //Auth1 - UsbCommand c = {CMD_MIFAREUC_AUTH1, {blockNo}}; - SendCommand(&c); - UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - cuid = resp.arg[1]; - uint8_t * data= resp.d.asBytes; - - if (isOK){ - PrintAndLog("enc(RndB):%s", sprint_hex(data+1, 8)); - memcpy(e_RndB,data+1,8); - } - } else { - PrintAndLog("Command execute timeout"); - } - - //Do crypto magic - DES_random_key(&RndA); - DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0); - PrintAndLog(" RndB:%s",sprint_hex(RndB, 8)); - PrintAndLog(" RndA:%s",sprint_hex(RndA, 8)); - rol(RndB,8); - memcpy(RndARndB,RndA,8); - memcpy(RndARndB+8,RndB,8); - PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16)); - DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1); - PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16)); - - //Auth2 - UsbCommand d = {CMD_MIFAREUC_AUTH2, {cuid}}; - memcpy(d.d.asBytes,RndARndB, 16); - SendCommand(&d); - - UsbCommand respb; - if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) { - uint8_t isOK = respb.arg[0] & 0xff; - uint8_t * data2= respb.d.asBytes; - - if (isOK){ - PrintAndLog("enc(RndA'):%s", sprint_hex(data2+1, 8)); - } - - } else { - PrintAndLog("Command execute timeout"); - } - return 1; -} - -// -// Ultralight C Read Single Block -// -int CmdHF14AMfUCRdBl(const char *Cmd) -{ - uint8_t blockNo = 0; - - if (strlen(Cmd)<1) { - PrintAndLog("Usage: hf mfu ucrdbl "); - PrintAndLog(" sample: hf mfu ucrdbl 0"); - return 0; - } - - blockNo = param_get8(Cmd, 0); - if (blockNo>MAX_ULTRAC_BLOCKS){ - PrintAndLog("Error: Maximum number of readable blocks is 44 for Ultralight Cards!"); - return 1; - } - PrintAndLog("--block no:%02x", (int)blockNo); - - //Read Block - UsbCommand e = {CMD_MIFAREU_READBL, {blockNo}}; - SendCommand(&e); - UsbCommand resp_c; - if (WaitForResponseTimeout(CMD_ACK,&resp_c,1500)) { - uint8_t isOK = resp_c.arg[0] & 0xff; - uint8_t * data = resp_c.d.asBytes; - if (isOK) - PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4)); - else - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - return 0; -} - -// -// Ultralight C Read (or Dump) Card Contents -// -int CmdHF14AMfUCRdCard(const char *Cmd){ - int i; - uint8_t BlockNo = 0; - int Pages=44; - uint8_t *lockbytes_t=NULL; - uint8_t lockbytes[2]={0x00}; - uint8_t *lockbytes_t2=NULL; - uint8_t lockbytes2[2]={0x00}; - bool bit[16]={0x00}; - bool bit2[16]={0x00}; - bool dump=false; - uint8_t datatemp[5]={0x00}; - uint8_t isOK = 0; - uint8_t * data = NULL; - FILE *fout = NULL; - - if (strchr(Cmd,'x') != 0){ - dump=true; - if ((fout = fopen("dump_ultralightc_data.bin","wb")) == NULL) { - PrintAndLog("Could not create file name dumpdata.bin"); - return 1; - } - PrintAndLog("Dumping Ultralight C Card Data..."); - } - PrintAndLog("Attempting to Read Ultralight C... "); - UsbCommand c = {CMD_MIFAREUC_READCARD, {BlockNo, Pages}}; - SendCommand(&c); - UsbCommand resp; - - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - isOK = resp.arg[0] & 0xff; - data = resp.d.asBytes; - - PrintAndLog("isOk:%02x", isOK); - if (isOK) - for (i = 0; i < Pages; i++) { - switch(i){ - case 2: - //process lock bytes - lockbytes_t=data+(i*4); - lockbytes[0]=lockbytes_t[2]; - lockbytes[1]=lockbytes_t[3]; - for(int j=0; j<16; j++){ - bit[j]=lockbytes[j/8] & ( 1 <<(7-j%8)); - } - //might as well read bottom lockbytes too - lockbytes_t2=data+(40*4); - lockbytes2[0]=lockbytes_t2[2]; - lockbytes2[1]=lockbytes_t2[3]; - for(int j=0; j<16; j++){ - bit2[j]=lockbytes2[j/8] & ( 1 <<(7-j%8)); - } - PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4)); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 3: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[4]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 4: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[3]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 5: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[2]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 6: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[1]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 7: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[0]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 8: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[15]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 9: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[14]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 10: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[13]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 11: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[12]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 12: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[11]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 13: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[10]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 14: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[9]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 15: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[8]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 16: - case 17: - case 18: - case 19: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[6]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 20: - case 21: - case 22: - case 23: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[5]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 24: - case 25: - case 26: - case 27: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[4]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 28: - case 29: - case 30: - case 31: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[2]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 32: - case 33: - case 34: - case 35: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[1]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 36: - case 37: - case 38: - case 39: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[0]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 40: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[12]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 41: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[11]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 42: - //auth0 - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[10]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 43: - //auth1 - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[9]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - default: - PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4)); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - } - } - - } else { - PrintAndLog("Command1 execute timeout"); - } - if (dump) fclose(fout); - return 0; -} - -// -// Ultralight C Dump Card Contents to file -// -int CmdHF14AMfUCDump(const char *Cmd){ - int i; - uint8_t BlockNo = 0; - int Pages=44; - uint8_t *lockbytes_t=NULL; - uint8_t lockbytes[2]={0x00}; - uint8_t *lockbytes_t2=NULL; - uint8_t lockbytes2[2]={0x00}; - bool bit[16]={0x00}; - bool bit2[16]={0x00}; - bool dump=true; - uint8_t datatemp[5]={0x00}; - - uint8_t isOK = 0; - uint8_t * data = NULL; - FILE *fout; - - if ((fout = fopen("dump_ultralightc_data.bin","wb")) == NULL) { - PrintAndLog("Could not create file name dumpdata.bin"); - return 1; - } - PrintAndLog("Dumping Ultralight C Card Data..."); - PrintAndLog("Attempting to Read Ultralight C... "); - UsbCommand c = {CMD_MIFAREU_READCARD, {BlockNo,Pages}}; - SendCommand(&c); - UsbCommand resp; - - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - isOK = resp.arg[0] & 0xff; - data = resp.d.asBytes; - PrintAndLog("isOk:%02x", isOK); - if (isOK) - for (i = 0; i < Pages; i++) { - switch(i){ - case 2: - //process lock bytes - lockbytes_t=data+(i*4); - lockbytes[0]=lockbytes_t[2]; - lockbytes[1]=lockbytes_t[3]; - for(int j=0; j<16; j++){ - bit[j]=lockbytes[j/8] & ( 1 <<(7-j%8)); - - } - //might as well read bottom lockbytes too - lockbytes_t2=data+(40*4); - lockbytes2[0]=lockbytes_t2[2]; - lockbytes2[1]=lockbytes_t2[3]; - for(int j=0; j<16; j++){ - bit2[j]=lockbytes2[j/8] & ( 1 <<(7-j%8)); - } - - PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4)); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 3: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[4]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 4: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[3]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 5: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[2]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 6: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[1]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 7: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[0]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 8: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[15]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 9: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[14]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 10: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[13]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 11: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[12]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 12: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[11]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 13: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[10]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 14: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[9]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 15: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[8]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 16: - case 17: - case 18: - case 19: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[6]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 20: - case 21: - case 22: - case 23: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[5]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 24: - case 25: - case 26: - case 27: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[4]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 28: - case 29: - case 30: - case 31: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[2]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 32: - case 33: - case 34: - case 35: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[1]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 36: - case 37: - case 38: - case 39: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[0]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 40: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[12]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 41: - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[11]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 42: - //auth0 - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[10]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - case 43: - //auth1 - PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit2[9]); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - default: - PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4)); - memcpy(datatemp,data + i * 4,4); - if (dump) fwrite ( datatemp, 1, 4, fout ); - break; - } - } - - } else { - PrintAndLog("Command1 execute timeout"); - } - if (dump) fclose(fout); - return 0; -} - -// -// Mifare Ultralight C Write Single Block -// -int CmdHF14AMfUCWrBl(const char *Cmd){ - - uint8_t blockNo = 0; - bool chinese_card = 0; - uint8_t bldata[16] = {0x00}; - UsbCommand resp; - - if (strlen(Cmd)<3) { - PrintAndLog("Usage: hf mfu ucwrbl [w]"); - PrintAndLog(" sample: hf mfu uwrbl 0 01020304"); - return 0; - } - blockNo = param_get8(Cmd, 0); - if (blockNo>(MAX_ULTRAC_BLOCKS+4)){ - PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight Cards!"); - return 1; - } - if (param_gethex(Cmd, 1, bldata, 8)) { - PrintAndLog("Block data must include 8 HEX symbols"); - return 1; - } - if (strchr(Cmd,'w') != 0) { - chinese_card=1; - } - switch(blockNo){ - case 0: - if (!chinese_card){ - PrintAndLog("Access Denied"); - }else{ - PrintAndLog("--specialblock no:%02x", blockNo); - PrintAndLog("--data: %s", sprint_hex(bldata, 4)); - UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}}; - memcpy(d.d.asBytes,bldata, 4); - SendCommand(&d); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - } - break; - case 1: - if (!chinese_card){ - PrintAndLog("Access Denied"); - }else{ - PrintAndLog("--specialblock no:%02x", blockNo); - PrintAndLog("--data: %s", sprint_hex(bldata, 4)); - UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}}; - memcpy(d.d.asBytes,bldata, 4); - SendCommand(&d); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - } - break; - case 2: - if (!chinese_card){ - PrintAndLog("Access Denied"); - }else{ - PrintAndLog("--specialblock no:%02x", blockNo); - PrintAndLog("--data: %s", sprint_hex(bldata, 4)); - UsbCommand c = {CMD_MIFAREU_WRITEBL, {blockNo}}; - memcpy(c.d.asBytes, bldata, 4); - SendCommand(&c); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - } - break; - case 3: - PrintAndLog("--specialblock no:%02x", blockNo); - PrintAndLog("--data: %s", sprint_hex(bldata, 4)); - UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}}; - memcpy(d.d.asBytes,bldata, 4); - SendCommand(&d); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - break; - default: - PrintAndLog("--block no:%02x", blockNo); - PrintAndLog("--data: %s", sprint_hex(bldata, 4)); - UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}}; - memcpy(e.d.asBytes,bldata, 4); - SendCommand(&e); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - break; - } - return 0; -} - -//------------------------------------ -// Menu Stuff -//------------------------------------ -static command_t CommandTable[] = -{ - {"help", CmdHelp, 1,"This help"}, - {"dbg", CmdHF14AMfDbg, 0,"Set default debug mode"}, - {"urdbl", CmdHF14AMfURdBl, 0,"Read MIFARE Ultralight block"}, - {"urdcard", CmdHF14AMfURdCard, 0,"Read MIFARE Ultralight Card"}, - {"udump", CmdHF14AMfUDump, 0,"Dump MIFARE Ultralight tag to binary file"}, - {"uwrbl", CmdHF14AMfUWrBl, 0,"Write MIFARE Ultralight block"}, - {"ucrdbl", CmdHF14AMfUCRdBl, 0,"Read MIFARE Ultralight C block"}, - {"ucrdcard",CmdHF14AMfUCRdCard, 0,"Read MIFARE Ultralight C Card"}, - {"ucdump", CmdHF14AMfUCDump, 0,"Dump MIFARE Ultralight C tag to binary file"}, - {"ucwrbl", CmdHF14AMfUCWrBl, 0,"Write MIFARE Ultralight C block"}, - {"auth", CmdHF14AMfucAuth, 0,"Ultralight C Authentication"}, - {NULL, NULL, 0, NULL} -}; - -int CmdHFMFUltra(const char *Cmd){ - WaitForResponseTimeout(CMD_ACK,NULL,100); - CmdsParse(CommandTable, Cmd); - return 0; -} - -int CmdHelp(const char *Cmd){ - CmdsHelp(CommandTable); - return 0; -} \ No newline at end of file diff --git a/client/cmdhfmfu.h b/client/cmdhfmfu.h deleted file mode 100644 index 20f25d1d..00000000 --- a/client/cmdhfmfu.h +++ /dev/null @@ -1,16 +0,0 @@ -#include "cmdhfmf.h" - -//standard ultralight -int CmdHF14AMfUWrBl(const char *Cmd); -int CmdHF14AMfURdBl(const char *Cmd); -int CmdHF14AMfURdCard(const char *Cmd); -int CmdHF14AMfUDump(const char *Cmd); -//Crypto Cards -int CmdHF14AMfUCRdBl(const char *Cmd); -int CmdHF14AMfUCRdCard(const char *Cmd); -int CmdHF14AMfUCDump(const char *Cmd); -int CmdHF14AMfucAuth(const char *Cmd); -void rol (uint8_t *data, const size_t len); - -//general stuff -int CmdHFMFUltra(const char *Cmd); diff --git a/client/cmdhw.c b/client/cmdhw.c index 642f63c5..443973b8 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -13,11 +13,12 @@ #include #include #include "ui.h" +//#include "proxusb.h" #include "proxmark3.h" #include "cmdparser.h" -#include "cmddata.h" #include "cmdhw.h" #include "cmdmain.h" +#include "cmddata.h" /* low-level hardware control */ @@ -417,7 +418,7 @@ static command_t CommandTable[] = {"setlfdivisor", CmdSetDivisor, 0, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"}, {"setmux", CmdSetMux, 0, " -- Set the ADC mux to a specific value"}, {"tune", CmdTune, 0, "Measure antenna tuning"}, - {"version", CmdVersion, 0, "Show version information about the connected Proxmark"}, + {"version", CmdVersion, 0, "Show version inforation about the connected Proxmark"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdlf.c b/client/cmdlf.c index e38eee51..18bcf747 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -20,7 +20,6 @@ #include "cmdmain.h" #include "cmddata.h" #include "cmdlf.h" -#include "cmdlfawid26.h" #include "cmdlfhid.h" #include "cmdlfti.h" #include "cmdlfem4x.h" @@ -48,377 +47,374 @@ int CmdLFCommandRead(const char *Cmd) int CmdFlexdemod(const char *Cmd) { - int i; - for (i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] < 0) { - GraphBuffer[i] = -1; - } else { - GraphBuffer[i] = 1; - } - } + int i; + for (i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] < 0) { + GraphBuffer[i] = -1; + } else { + GraphBuffer[i] = 1; + } + } - #define LONG_WAIT 100 - int start; - for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) { - int first = GraphBuffer[start]; - for (i = start; i < start + LONG_WAIT; i++) { - if (GraphBuffer[i] != first) { - break; - } - } - if (i == (start + LONG_WAIT)) { - break; - } - } - if (start == GraphTraceLen - LONG_WAIT) { - //PrintAndLog("nothing to wait for"); - return 0; - } +#define LONG_WAIT 100 + int start; + for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) { + int first = GraphBuffer[start]; + for (i = start; i < start + LONG_WAIT; i++) { + if (GraphBuffer[i] != first) { + break; + } + } + if (i == (start + LONG_WAIT)) { + break; + } + } + if (start == GraphTraceLen - LONG_WAIT) { + PrintAndLog("nothing to wait for"); + return 0; + } - GraphBuffer[start] = 2; - GraphBuffer[start+1] = -2; + GraphBuffer[start] = 2; + GraphBuffer[start+1] = -2; uint8_t bits[64] = {0x00}; int bit, sum; - i = start; - for (bit = 0; bit < 64; bit++) { + i = start; + for (bit = 0; bit < 64; bit++) { sum = 0; for (int j = 0; j < 16; j++) { - sum += GraphBuffer[i++]; - } + sum += GraphBuffer[i++]; + } bits[bit] = (sum > 0) ? 1 : 0; - PrintAndLog("bit %d sum %d", bit, sum); - } + PrintAndLog("bit %d sum %d", bit, sum); + } - for (bit = 0; bit < 64; bit++) { - int j; - int sum = 0; - for (j = 0; j < 16; j++) { - sum += GraphBuffer[i++]; - } - if (sum > 0 && bits[bit] != 1) { - PrintAndLog("oops1 at %d", bit); - } - if (sum < 0 && bits[bit] != 0) { - PrintAndLog("oops2 at %d", bit); - } - } + for (bit = 0; bit < 64; bit++) { + int j; + int sum = 0; + for (j = 0; j < 16; j++) { + sum += GraphBuffer[i++]; + } + if (sum > 0 && bits[bit] != 1) { + PrintAndLog("oops1 at %d", bit); + } + if (sum < 0 && bits[bit] != 0) { + PrintAndLog("oops2 at %d", bit); + } + } // HACK writing back to graphbuffer. - GraphTraceLen = 32*64; - i = 0; - int phase = 0; - for (bit = 0; bit < 64; bit++) { + GraphTraceLen = 32*64; + i = 0; + int phase = 0; + for (bit = 0; bit < 64; bit++) { phase = (bits[bit] == 0) ? 0 : 1; - int j; - for (j = 0; j < 32; j++) { - GraphBuffer[i++] = phase; - phase = !phase; - } - } + int j; + for (j = 0; j < 32; j++) { + GraphBuffer[i++] = phase; + phase = !phase; + } + } - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } int CmdIndalaDemod(const char *Cmd) { - // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID + // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID - int state = -1; - int count = 0; - int i, j; + int state = -1; + int count = 0; + int i, j; - // worst case with GraphTraceLen=64000 is < 4096 - // under normal conditions it's < 2048 + // worst case with GraphTraceLen=64000 is < 4096 + // under normal conditions it's < 2048 - uint8_t rawbits[4096]; - int rawbit = 0; - int worst = 0, worstPos = 0; + uint8_t rawbits[4096]; + int rawbit = 0; + int worst = 0, worstPos = 0; // PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32); - for (i = 0; i < GraphTraceLen-1; i += 2) { - count += 1; - if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) { - if (state == 0) { - for (j = 0; j < count - 8; j += 16) { - rawbits[rawbit++] = 0; - } - if ((abs(count - j)) > worst) { - worst = abs(count - j); - worstPos = i; - } - } - state = 1; - count = 0; - } else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) { - if (state == 1) { - for (j = 0; j < count - 8; j += 16) { - rawbits[rawbit++] = 1; - } - if ((abs(count - j)) > worst) { - worst = abs(count - j); - worstPos = i; - } - } - state = 0; - count = 0; - } - } + for (i = 0; i < GraphTraceLen-1; i += 2) { + count += 1; + if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) { + if (state == 0) { + for (j = 0; j < count - 8; j += 16) { + rawbits[rawbit++] = 0; + } + if ((abs(count - j)) > worst) { + worst = abs(count - j); + worstPos = i; + } + } + state = 1; + count = 0; + } else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) { + if (state == 1) { + for (j = 0; j < count - 8; j += 16) { + rawbits[rawbit++] = 1; + } + if ((abs(count - j)) > worst) { + worst = abs(count - j); + worstPos = i; + } + } + state = 0; + count = 0; + } + } - if (rawbit>0){ - PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32); - PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); + if (rawbit>0){ + PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32); + PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); } else { return 0; } - // Finding the start of a UID - int uidlen, long_wait; - if (strcmp(Cmd, "224") == 0) { - uidlen = 224; - long_wait = 30; - } else { - uidlen = 64; - long_wait = 29; - } + // Finding the start of a UID + int uidlen, long_wait; + if (strcmp(Cmd, "224") == 0) { + uidlen = 224; + long_wait = 30; + } else { + uidlen = 64; + long_wait = 29; + } - int start; - int first = 0; - for (start = 0; start <= rawbit - uidlen; start++) { - first = rawbits[start]; - for (i = start; i < start + long_wait; i++) { - if (rawbits[i] != first) { - break; - } - } - if (i == (start + long_wait)) { - break; - } - } + int start; + int first = 0; + for (start = 0; start <= rawbit - uidlen; start++) { + first = rawbits[start]; + for (i = start; i < start + long_wait; i++) { + if (rawbits[i] != first) { + break; + } + } + if (i == (start + long_wait)) { + break; + } + } - if (start == rawbit - uidlen + 1) { - //PrintAndLog("nothing to wait for"); - return 0; - } + if (start == rawbit - uidlen + 1) { + PrintAndLog("nothing to wait for"); + return 0; + } - // Inverting signal if needed - if (first == 1) { - for (i = start; i < rawbit; i++) { - rawbits[i] = !rawbits[i]; - } - } + // Inverting signal if needed + if (first == 1) { + for (i = start; i < rawbit; i++) { + rawbits[i] = !rawbits[i]; + } + } - // Dumping UID + // Dumping UID uint8_t bits[224] = {0x00}; char showbits[225] = {0x00}; - int bit; - i = start; - int times = 0; + int bit; + i = start; + int times = 0; - if (uidlen > rawbit) { - PrintAndLog("Warning: not enough raw bits to get a full UID"); - for (bit = 0; bit < rawbit; bit++) { - bits[bit] = rawbits[i++]; - // As we cannot know the parity, let's use "." and "/" - showbits[bit] = '.' + bits[bit]; - } - showbits[bit+1]='\0'; - PrintAndLog("Partial UID=%s", showbits); - return 0; - } else { - for (bit = 0; bit < uidlen; bit++) { - bits[bit] = rawbits[i++]; - showbits[bit] = '0' + bits[bit]; - } - times = 1; - } + if (uidlen > rawbit) { + PrintAndLog("Warning: not enough raw bits to get a full UID"); + for (bit = 0; bit < rawbit; bit++) { + bits[bit] = rawbits[i++]; + // As we cannot know the parity, let's use "." and "/" + showbits[bit] = '.' + bits[bit]; + } + showbits[bit+1]='\0'; + PrintAndLog("Partial UID=%s", showbits); + return 0; + } else { + for (bit = 0; bit < uidlen; bit++) { + bits[bit] = rawbits[i++]; + showbits[bit] = '0' + bits[bit]; + } + times = 1; + } - //convert UID to HEX - uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; - int idx; + //convert UID to HEX + uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; + int idx; uid1 = uid2 = 0; - if (uidlen == 64){ - for( idx=0; idx<64; idx++) { - if (showbits[idx] == '0') { - uid1 = (uid1<<1) | (uid2>>31); - uid2 = (uid2<<1) | 0; - } else { - uid1 = (uid1<<1) | (uid2>>31); - uid2 = (uid2<<1) | 1; - } - } - PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2); - } - else { + if (uidlen==64){ + for( idx=0; idx<64; idx++) { + if (showbits[idx] == '0') { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|0; + } else { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|1; + } + } + PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2); + } + else { uid3 = uid4 = uid5 = uid6 = uid7 = 0; - for( idx=0; idx<224; idx++) { - uid1 = (uid1<<1) | (uid2>>31); - uid2 = (uid2<<1) | (uid3>>31); - uid3 = (uid3<<1) | (uid4>>31); - uid4 = (uid4<<1) | (uid5>>31); - uid5 = (uid5<<1) | (uid6>>31); - uid6 = (uid6<<1) | (uid7>>31); + for( idx=0; idx<224; idx++) { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|(uid3>>31); + uid3=(uid3<<1)|(uid4>>31); + uid4=(uid4<<1)|(uid5>>31); + uid5=(uid5<<1)|(uid6>>31); + uid6=(uid6<<1)|(uid7>>31); if (showbits[idx] == '0') uid7 = (uid7<<1) | 0; else uid7 = (uid7<<1) | 1; - } - PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); - } + } + PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); + } - // Checking UID against next occurrences - int failed = 0; + // Checking UID against next occurrences + int failed = 0; for (; i + uidlen <= rawbit;) { failed = 0; - for (bit = 0; bit < uidlen; bit++) { - if (bits[bit] != rawbits[i++]) { - failed = 1; - break; - } - } - if (failed == 1) { - break; - } - times += 1; - } + for (bit = 0; bit < uidlen; bit++) { + if (bits[bit] != rawbits[i++]) { + failed = 1; + break; + } + } + if (failed == 1) { + break; + } + times += 1; + } - PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); + PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); - // Remodulating for tag cloning + // Remodulating for tag cloning // HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod) // since this changes graphbuffer data. - GraphTraceLen = 32 * uidlen; - i = 0; - int phase = 0; - for (bit = 0; bit < uidlen; bit++) { - if (bits[bit] == 0) { - phase = 0; - } else { - phase = 1; - } - int j; - for (j = 0; j < 32; j++) { - GraphBuffer[i++] = phase; - phase = !phase; - } - } + GraphTraceLen = 32*uidlen; + i = 0; + int phase = 0; + for (bit = 0; bit < uidlen; bit++) { + if (bits[bit] == 0) { + phase = 0; + } else { + phase = 1; + } + int j; + for (j = 0; j < 32; j++) { + GraphBuffer[i++] = phase; + phase = !phase; + } + } - RepaintGraphWindow(); - return 1; + RepaintGraphWindow(); + return 1; } int CmdIndalaClone(const char *Cmd) { - UsbCommand c; + UsbCommand c; unsigned int uid1, uid2, uid3, uid4, uid5, uid6, uid7; uid1 = uid2 = uid3 = uid4 = uid5 = uid6 = uid7 = 0; - int n = 0, i = 0; + int n = 0, i = 0; - if (strchr(Cmd,'l') != 0) { - while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { - uid1 = (uid1 << 4) | (uid2 >> 28); - uid2 = (uid2 << 4) | (uid3 >> 28); - uid3 = (uid3 << 4) | (uid4 >> 28); - uid4 = (uid4 << 4) | (uid5 >> 28); - uid5 = (uid5 << 4) | (uid6 >> 28); - uid6 = (uid6 << 4) | (uid7 >> 28); - uid7 = (uid7 << 4) | (n & 0xf); - } - PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7); - c.cmd = CMD_INDALA_CLONE_TAG_L; - c.d.asDwords[0] = uid1; - c.d.asDwords[1] = uid2; - c.d.asDwords[2] = uid3; - c.d.asDwords[3] = uid4; - c.d.asDwords[4] = uid5; - c.d.asDwords[5] = uid6; - c.d.asDwords[6] = uid7; + if (strchr(Cmd,'l') != 0) { + while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { + uid1 = (uid1 << 4) | (uid2 >> 28); + uid2 = (uid2 << 4) | (uid3 >> 28); + uid3 = (uid3 << 4) | (uid4 >> 28); + uid4 = (uid4 << 4) | (uid5 >> 28); + uid5 = (uid5 << 4) | (uid6 >> 28); + uid6 = (uid6 << 4) | (uid7 >> 28); + uid7 = (uid7 << 4) | (n & 0xf); + } + PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7); + c.cmd = CMD_INDALA_CLONE_TAG_L; + c.d.asDwords[0] = uid1; + c.d.asDwords[1] = uid2; + c.d.asDwords[2] = uid3; + c.d.asDwords[3] = uid4; + c.d.asDwords[4] = uid5; + c.d.asDwords[5] = uid6; + c.d.asDwords[6] = uid7; } else { - while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { - uid1 = (uid1 << 4) | (uid2 >> 28); - uid2 = (uid2 << 4) | (n & 0xf); - } - PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1, uid2); - c.cmd = CMD_INDALA_CLONE_TAG; - c.arg[0] = uid1; - c.arg[1] = uid2; - } + while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { + uid1 = (uid1 << 4) | (uid2 >> 28); + uid2 = (uid2 << 4) | (n & 0xf); + } + PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1, uid2); + c.cmd = CMD_INDALA_CLONE_TAG; + c.arg[0] = uid1; + c.arg[1] = uid2; + } - SendCommand(&c); - return 0; + SendCommand(&c); + return 0; } int CmdLFRead(const char *Cmd) { - UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K}; + UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K}; - // 'h' means higher-low-frequency, 134 kHz - if(*Cmd == 'h') { - c.arg[0] = 1; - } else if (*Cmd == '\0') { - c.arg[0] = 0; - } else if (sscanf(Cmd, "%"lli, &c.arg[0]) != 1) { + // 'h' means higher-low-frequency, 134 kHz + if(*Cmd == 'h') { + c.arg[0] = 1; + } else if (*Cmd == '\0') { + c.arg[0] = 0; + } else if (sscanf(Cmd, "%"lli, &c.arg[0]) != 1) { PrintAndLog("Samples 1: 'lf read'"); PrintAndLog(" 2: 'lf read h'"); PrintAndLog(" 3: 'lf read '"); - return 0; - } - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - - CmdSamples(""); - ShowGraphWindow(); - return 0; + return 0; + } + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + return 0; } static void ChkBitstream(const char *str) { - int i; + int i; - /* convert to bitstream if necessary */ - for (i = 0; i < (int)(GraphTraceLen / 2); i++){ - if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) { - CmdBitstream(str); - break; - } - } + /* convert to bitstream if necessary */ + for (i = 0; i < (int)(GraphTraceLen / 2); i++) + { + if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) + { + CmdBitstream(str); + break; + } + } } int CmdLFSim(const char *Cmd) { - int i,j; - static int gap; + int i; + static int gap; - sscanf(Cmd, "%i", &gap); + sscanf(Cmd, "%i", &gap); - /* convert to bitstream if necessary */ - ChkBitstream(Cmd); + /* convert to bitstream if necessary */ + ChkBitstream(Cmd); - printf("Sending [%d bytes]", GraphTraceLen); - for (i = 0; i < GraphTraceLen; i += USB_CMD_DATA_SIZE) { - UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}}; + PrintAndLog("Sending data, please wait..."); + for (i = 0; i < GraphTraceLen; i += 48) { + UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}}; + int j; + for (j = 0; j < 48; j++) { + c.d.asBytes[j] = GraphBuffer[i+j]; + } + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + } - for (j = 0; j < USB_CMD_DATA_SIZE; j++) { - c.d.asBytes[j] = GraphBuffer[i+j]; - } - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - printf("."); - } - - printf("\n"); - PrintAndLog("Starting to simulate"); - UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}}; - SendCommand(&c); - return 0; + PrintAndLog("Starting simulator..."); + UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}}; + SendCommand(&c); + return 0; } int CmdLFSimBidir(const char *Cmd) @@ -434,57 +430,48 @@ int CmdLFSimBidir(const char *Cmd) /* simulate an LF Manchester encoded tag with specified bitstream, clock rate and inter-id gap */ int CmdLFSimManchester(const char *Cmd) { - static int clock, gap; - static char data[1024], gapstring[8]; + static int clock, gap; + static char data[1024], gapstring[8]; - sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap); + sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap); - ClearGraph(0); + ClearGraph(0); - for (int i = 0; i < strlen(data) ; ++i) - AppendGraph(0, clock, data[i]- '0'); + for (int i = 0; i < strlen(data) ; ++i) + AppendGraph(0, clock, data[i]- '0'); - CmdManchesterMod(""); + CmdManchesterMod(""); - RepaintGraphWindow(); + RepaintGraphWindow(); - sprintf(&gapstring[0], "%i", gap); - CmdLFSim(gapstring); - return 0; + sprintf(&gapstring[0], "%i", gap); + CmdLFSim(gapstring); + return 0; } int CmdLFSnoop(const char *Cmd) { - UsbCommand c = {CMD_LF_SNOOP_RAW_ADC_SAMPLES}; + UsbCommand c = {CMD_LF_SNOOP_RAW_ADC_SAMPLES}; - // 'h' means higher-low-frequency, 134 kHz - c.arg[0] = 0; - c.arg[1] = -1; + // 'h' means higher-low-frequency, 134 kHz + c.arg[0] = 0; + c.arg[1] = -1; if (*Cmd == 'l') { - sscanf(Cmd, "l %"lli, &c.arg[1]); - } else if (*Cmd == 'h') { - c.arg[0] = 1; - sscanf(Cmd, "h %"lli, &c.arg[1]); - } else if (sscanf(Cmd, "%"lli" %"lli, &c.arg[0], &c.arg[1]) < 1) { + sscanf(Cmd, "l %"lli, &c.arg[1]); + } else if(*Cmd == 'h') { + c.arg[0] = 1; + sscanf(Cmd, "h %"lli, &c.arg[1]); + } else if (sscanf(Cmd, "%"lli" %"lli, &c.arg[0], &c.arg[1]) < 1) { PrintAndLog("usage 1: snoop"); PrintAndLog(" 2: snoop {l,h} [trigger threshold]"); PrintAndLog(" 3: snoop [trigger threshold]"); - return 0; - } + return 0; + } - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - - #define BUFF_SIZE 8000 - uint8_t data[BUFF_SIZE] = {0x00}; - - GetFromBigBuf(data,BUFF_SIZE,0); - WaitForResponseTimeout(CMD_ACK,NULL, 1500); - - SetGraphBuf(data, BUFF_SIZE); - - return 0; + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + return 0; } int CmdVchDemod(const char *Cmd) @@ -566,81 +553,49 @@ int CmdVchDemod(const char *Cmd) //by marshmellow int CmdLFfind(const char *Cmd) { - int ans = 0; - char cmdp = param_getchar(Cmd, 0); - - if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: lf search <0|1>"); - PrintAndLog(" , if not set, try reading data from tag."); - PrintAndLog(""); - PrintAndLog(" sample: lf search"); - PrintAndLog(" : lf search 1"); - return 0; - } - - if (!offline || (cmdp != '1') ){ - ans = CmdLFRead(""); - } else if (GraphTraceLen < 1000) { - PrintAndLog("Data in Graphbuffer was too small."); - return 0; - } - - PrintAndLog("Checking for known tags:"); - - ans = Cmdaskmandemod(""); - PrintAndLog("ASK_MAN: %s", (ans) ? "YES":"NO" ); - - ans = CmdFSKdemodHID(""); - PrintAndLog("HID: %s", (ans) ? "YES":"NO" ); - - ans = CmdFSKdemodIO(""); - PrintAndLog("IO prox: %s", (ans) ? "YES":"NO" ); - - ans = CmdIndalaDemod(""); - PrintAndLog("Indala (64): %s", (ans) ? "YES":"NO" ); - - ans = CmdIndalaDemod("224"); - PrintAndLog("Indala (224): %s", (ans) ? "YES":"NO" ); - - // ans = CmdVchDemod(""); - // PrintAndLog("VeriChip: %s", (ans) ? "YES":"NO" ); - - // ans = CmdFlexdemod(""); - // PrintAndLog("FlexPass: %s", (ans) ? "YES":"NO" ); - - if (!ans) - PrintAndLog("No Known Tags Found!\n"); - - return 0; + int ans=0; + if (!offline){ + ans=CmdLFRead(""); + ans=CmdSamples("20000"); + } + if (GraphTraceLen<1000) return 0; + PrintAndLog("Checking for known tags:"); + ans=Cmdaskmandemod(""); + if (ans>0) return 1; + ans=CmdFSKdemodHID(""); + if (ans>0) return 1; + ans=CmdFSKdemodIO(""); + if (ans>0) return 1; + //add psk and indala + ans=CmdIndalaDemod(""); + if (ans>0) return 1; + ans=CmdIndalaDemod("224"); + if (ans>0) return 1; + PrintAndLog("No Known Tags Found!\n"); + return 0; } static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"cmdread", CmdLFCommandRead, 0, " <'0' period> <'1' period> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, - + {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"}, {"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"}, + {"hid", CmdLFHID, 1, "{ HID RFIDs... }"}, + {"io", CmdLFIO, 1, "{ ioProx tags... }"}, {"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, - {"indalaclone", CmdIndalaClone, 0, " ['l']-- Clone Indala to T55x7 (UID in HEX)(option 'l' for 224 UID"}, - {"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"}, - - + {"indalaclone", CmdIndalaClone, 0, " ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, {"read", CmdLFRead, 0, "['h' or ] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134, alternatively: f=12MHz/(divisor+1))"}, {"search", CmdLFfind, 1, "Read and Search for valid known tag (in offline mode it you can load first then search)"}, {"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, {"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, {"simman", CmdLFSimManchester, 0, " [GAP] Simulate arbitrary Manchester LF tag"}, {"snoop", CmdLFSnoop, 0, "['l'|'h'|] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"}, - - {"awid26", CmdLFAWID26, 1, "{ AWID26 tags }"}, - {"em4x", CmdLFEM4X, 1, "{ EM4X tags }"}, - {"hid", CmdLFHID, 1, "{ HID tags }"}, - {"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders }"}, - {"io", CmdLFIO, 1, "{ ioProx tags }"}, - {"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 tags }"}, - {"ti", CmdLFTI, 1, "{ TI tags }"}, - {"t55xx", CmdLFT55XX, 1, "{ T55xx tags }"}, - + {"ti", CmdLFTI, 1, "{ TI RFIDs... }"}, + {"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"}, + {"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"}, + {"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"}, + {"pcf7931", CmdLFPCF7931, 1, "{PCF7931 RFIDs...}"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdlfawid26.c b/client/cmdlfawid26.c deleted file mode 100644 index 48e599db..00000000 --- a/client/cmdlfawid26.c +++ /dev/null @@ -1,208 +0,0 @@ -//----------------------------------------------------------------------------- -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// Low frequency AWID26 commands -//----------------------------------------------------------------------------- - -#include -#include -#include -#include -#include "proxmark3.h" -#include "ui.h" -//#include "graph.h" -#include "cmdmain.h" -#include "cmdparser.h" -//#include "cmddata.h" -#include "cmdlf.h" -#include "cmdlfawid26.h" -#include "util.h" -//#include "data.h" - - -static int CmdHelp(const char *Cmd); - -int CmdClone(const char *Cmd) -{ - char cmdp = param_getchar(Cmd, 0); - - if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: lf awid26 clone "); - PrintAndLog(" [], "); - PrintAndLog(""); - PrintAndLog(" sample: lf awid26 clone 15 2233"); - return 0; - } - - //sscanf(Cmd, "%d %d", &facilitycode, &cardno); - - // char block0 = "00107060"; - // char block1 = "00107060"; - // char block2 = "00107060"; - // char block3 = "00107060"; - - unsigned char buf[10] = {0x00}; - unsigned char *resp = buf; - - - awid26_hex_to_uid(resp, ""); - // PrintAndLog("Writing block %d with data %08X", Block, Data); - return 0; -} - - -// convert 96 bit AWID FSK data to 8 digit BCD UID -bool awid26_hex_to_uid(unsigned char *response, char *awid26) -{ - //uint8_t i, tmp[96], tmp1[7]; - //uint8_t tmp[96] = {0x00}; - //int site; - //int id; - - //if(!hextobinarray(tmp, awid26)) - return false; - - // // data is in blocks of 4 bits - every 4th bit is parity, except the first - // // block which is all zeros - // for(i= 0 ; i < 4 ; ++i) - // if(tmp[i] != 0x00) - // return false; - - // // discard 1st block - // memcpy(tmp, tmp + 4, 92); - - // // check and strip parity on the rest - // for(i= 1 ; i < 23 ; ++i) - // if(tmp[(i * 4) - 1] != GetParity(tmp + (i - 1) * 4, ODD, 3)) - // return false; - // else - // memcpy((tmp + (i - 1) * 3), tmp + (i - 1) * 4, 3); - - // // discard the rest of the header - 1 more 3 bit block - // memcpy(tmp, tmp + 3, 66); - - // // next 8 bits is data length - should be 26: 0x1A - // binarraytohex(tmp1, tmp, 8); - // if(strcmp(tmp1, "1A") != 0) - // return false; - // memcpy(tmp, tmp +8, 58); - - // // standard wiegand parity check - even for 1st 12 bits, odd for 2nd 12 - // if(tmp[0] != GetParity(tmp + 1, EVEN, 12)) - // return false; - // if(tmp[25] != GetParity(tmp + 13, ODD, 12)) - // return false; - - // // convert to hex, ignoring parity bits - // if(!binarraytohex(tmp1, tmp + 1, 24)) - // return false; - - // // convert hex to site/id - // sscanf(tmp1,"%2X%4X", &site, &id); - - // // final output 8 byte BCD - // sprintf(response,"%03d%05d", site, id); - - return true; -} - -// convert null-terminated BCD UID (8 digits) to 96 bit awid26 encoded binary array -bool bcd_to_awid26_bin(unsigned char *awid26, unsigned char *bcd) -{ - // char i, p, tmp1[8], tmp2[26]; - // int tmpint; - - // if(strlen(bcd) != 8) - // return false; - - // // convert BCD site code to HEX - // sscanf(bcd, "%03d", &tmpint); - // sprintf(tmp2, "%02x", tmpint); - // memcpy(tmp1, tmp2, 2); - - // // convert BCD ID to HEX - // sscanf(bcd + 3, "%05d", &tmpint);; - // sprintf(tmp2, "%04x", tmpint); - - // // copy with trailing NULL - // memcpy(tmp1 + 2, tmp2, 5); - - // // convert full HEX to binary, leaving room for parity prefix - // hextobinarray(tmp2 + 1, tmp1); - - // wiegand_add_parity(tmp2, tmp2 + 1, 24); - - // memset(awid26, '\x0', 96); - - // // magic 18 bit awid26 header (we will overwrite the last two bits) - // hextobinarray(awid26, "011D8"); - - // // copy to target leaving space for parity bits - // for(i= 0, p= 18 ; i < 26 ; ++i, ++p) - // { - // // skip target bit if this is a parity location - // if(!((p + 1) % 4)) - // p += 1; - // awid26[p]= tmp2[i]; - // } - - // // add parity bits - // for(i= 1 ; i < 24 ; ++i) - // awid26[((i + 1) * 4) - 1]= GetParity(&awid26[i * 4], ODD, 3); - - return false; -} - -// int CmdReadTrace(const char *Cmd) -// { - - // uint8_t bits[LF_BITSSTREAM_LEN] = {0x00}; - // uint8_t * bitstream = bits; - - // uint8_t si = 5; - // uint32_t bl0 = PackBits(si, 32, bitstream); - // uint32_t bl1 = PackBits(si+32, 32, bitstream); - - // uint32_t acl = PackBits(si, 8, bitstream); si += 8; - // uint32_t mfc = PackBits(si, 8, bitstream); si += 8; - // uint32_t cid = PackBits(si, 5, bitstream); si += 5; - // uint32_t icr = PackBits(si, 3, bitstream); si += 3; - // uint32_t year = PackBits(si, 4, bitstream); si += 4; - // uint32_t quarter = PackBits(si, 2, bitstream); si += 2; - // uint32_t lotid = PackBits(si, 12, bitstream); si += 12; - // uint32_t wafer = PackBits(si, 5, bitstream); si += 5; - // uint32_t dw = PackBits(si, 15, bitstream); - - // PrintAndLog(""); - // PrintAndLog("-- T55xx Trace Information ----------------------------------"); - // PrintAndLog("-------------------------------------------------------------"); - // PrintAndLog(" ACL Allocation class (ISO/IEC 15963-1) : 0x%02X (%d)", acl, acl); - // PrintAndLog(" MFC Manufacturer ID (ISO/IEC 7816-6) : 0x%02X (%d)", mfc, mfc); - // PrintAndLog(" CID : 0x%02X (%d)", cid, cid); - // PrintAndLog(" ICR IC Revision : %d",icr ); - - - // return 0; -// } - -static command_t CommandTable[] = -{ - {"help", CmdHelp, 1, "This help"}, - {"clone", CmdClone, 1, " -- clone AWID26 to t55xx tag"}, - {NULL, NULL, 0, NULL} -}; - -int CmdLFAWID26(const char *Cmd) -{ - CmdsParse(CommandTable, Cmd); - return 0; -} - -int CmdHelp(const char *Cmd) -{ - CmdsHelp(CommandTable); - return 0; -} diff --git a/client/cmdlfawid26.h b/client/cmdlfawid26.h deleted file mode 100644 index 7c23d567..00000000 --- a/client/cmdlfawid26.h +++ /dev/null @@ -1,18 +0,0 @@ -//----------------------------------------------------------------------------- -// -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// Low frequency AWID 26 commands -//----------------------------------------------------------------------------- - -#ifndef CMDLFAWID26_H__ -#define CMDLFAWID26_H__ - -int CmdLFAWID26(const char *Cmd); - -int CmdClone(const char *Cmd); -bool awid26_hex_to_uid(unsigned char *response, char *awid26); -bool bcd_to_awid26_bin(unsigned char *awid26, unsigned char *bcd); -#endif diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index a0cd87ca..32a0ff7c 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -1,4 +1,4 @@ - //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- // Copyright (C) 2010 iZsh // // This code is licensed to you under the terms of the GNU GPL, version 2 or, @@ -13,18 +13,12 @@ #include #include "proxmark3.h" #include "ui.h" +#include "util.h" #include "graph.h" -#include "cmdmain.h" #include "cmdparser.h" #include "cmddata.h" #include "cmdlf.h" #include "cmdlfem4x.h" -#include "util.h" -#include "data.h" -#define LF_TRACE_BUFF_SIZE 12000 -#define LF_BITSSTREAM_LEN 1000 - -char *global_em410xId; static int CmdHelp(const char *Cmd); @@ -32,10 +26,10 @@ int CmdEMdemodASK(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); int findone = (cmdp == '1') ? 1 : 0; - UsbCommand c = { CMD_EM410X_DEMOD }; - c.arg[0] = findone; - SendCommand(&c); - return 0; + UsbCommand c={CMD_EM410X_DEMOD}; + c.arg[0]=findone; + SendCommand(&c); + return 0; } /* Read the ID of an EM410x tag. @@ -56,19 +50,23 @@ int CmdEM410xRead(const char *Cmd) uint8_t BitStream[MAX_GRAPH_TRACE_LEN]; high = low = 0; - // get clock - clock = GetClock(Cmd, 0); - - // Detect high and lows and clock - DetectHighLowInGraph( &high, &low, TRUE); + /* Detect high and lows and clock */ + for (i = 0; i < GraphTraceLen; i++) + { + if (GraphBuffer[i] > high) + high = GraphBuffer[i]; + else if (GraphBuffer[i] < low) + low = GraphBuffer[i]; + } - PrintAndLog("NUMNUM"); - - // parity for our 4 columns + /* get clock */ + clock = GetClock(Cmd, high, 0); + + /* parity for our 4 columns */ parity[0] = parity[1] = parity[2] = parity[3] = 0; header = rows = 0; - // manchester demodulate + /* manchester demodulate */ bit = bit2idx = 0; for (i = 0; i < (int)(GraphTraceLen / clock); i++) { @@ -79,9 +77,9 @@ int CmdEM410xRead(const char *Cmd) /* Find out if we hit both high and low peaks */ for (j = 0; j < clock; j++) { - if (GraphBuffer[(i * clock) + j] >= high) + if (GraphBuffer[(i * clock) + j] == high) hithigh = 1; - else if (GraphBuffer[(i * clock) + j] <= low) + else if (GraphBuffer[(i * clock) + j] == low) hitlow = 1; /* it doesn't count if it's the first part of our read @@ -101,10 +99,10 @@ int CmdEM410xRead(const char *Cmd) BitStream[bit2idx++] = bit; } - + retest: /* We go till 5 before the graph ends because we'll get that far below */ - for (i = 0; i < bit2idx - 5; i++) + for (i = 1; i < bit2idx - 5; i++) { /* Step 2: We have our header but need our tag ID */ if (header == 9 && rows < 10) @@ -133,7 +131,7 @@ retest: PrintAndLog("Thought we had a valid tag but failed at word %d (i=%d)", rows + 1, i); /* Start back rows * 5 + 9 header bits, -1 to not start at same place */ - i -= 9 + (5 * rows) -5; + i -= 9 + (5 * rows) - 5; rows = header = 0; } @@ -151,8 +149,6 @@ retest: PrintAndLog("EM410x Tag ID: %s", id); PrintAndLog("Unique Tag ID: %s", id2); - global_em410xId = id; - /* Stop any loops */ return 1; } @@ -181,14 +177,12 @@ retest: } /* if we've already retested after flipping bits, return */ - if (retested++){ - PrintAndLog("Failed to decode"); - return 0; - } + if (retested++) + return 0; /* if this didn't work, try flipping bits */ - for (i = 0; i < bit2idx; i++) - BitStream[i] ^= 1; + for (i = 0; i < bit2idx; i++) + BitStream[i] ^= 1; goto retest; } @@ -202,7 +196,7 @@ retest: * 0 <-- stop bit, end of tag */ int CmdEM410xSim(const char *Cmd) -{ +{ int i, n, j, binary[4], parity[4]; char cmdp = param_getchar(Cmd, 0); @@ -222,13 +216,13 @@ int CmdEM410xSim(const char *Cmd) PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X", uid[0],uid[1],uid[2],uid[3],uid[4]); PrintAndLog("Press pm3-button to about simulation"); - + /* clock is 64 in EM410x tags */ int clock = 64; /* clear our graph */ ClearGraph(0); - + /* write 9 start bits */ for (i = 0; i < 9; i++) AppendGraph(0, clock, 1); @@ -264,7 +258,7 @@ int CmdEM410xSim(const char *Cmd) AppendGraph(0, clock, parity[2]); AppendGraph(0, clock, parity[3]); - /* stop bit */ + /* stop bit */ AppendGraph(1, clock, 0); CmdLFSim("240"); //240 start_gap. @@ -285,30 +279,20 @@ int CmdEM410xWatch(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); int read_h = (cmdp == 'h'); - do - { + do { if (ukbhit()) { printf("\naborted via keyboard!\n"); break; } CmdLFRead(read_h ? "h" : ""); - CmdSamples("6000"); - + CmdSamples("6000"); } while ( !CmdEM410xRead("") ); return 0; } -int CmdEM410xWatchnSpoof(const char *Cmd) -{ - CmdEM410xWatch(Cmd); - PrintAndLog("# Replaying : %s",global_em410xId); - CmdEM410xSim(global_em410xId); - return 0; -} - /* Read the transmitted data of an EM4x50 tag * Format: * @@ -523,80 +507,48 @@ int CmdEM410xWrite(const char *Cmd) int CmdReadWord(const char *Cmd) { - int Word = -1; //default to invalid word - UsbCommand c; + int Word = 16; //default to invalid word + UsbCommand c; - sscanf(Cmd, "%d", &Word); + sscanf(Cmd, "%d", &Word); - if ( (Word > 15) | (Word < 0) ) { - PrintAndLog("Word must be between 0 and 15"); - return 1; - } + if (Word > 15) { + PrintAndLog("Word must be between 0 and 15"); + return 1; + } - PrintAndLog("Reading word %d", Word); + PrintAndLog("Reading word %d", Word); - c.cmd = CMD_EM4X_READ_WORD; - c.d.asBytes[0] = 0x0; //Normal mode - c.arg[0] = 0; - c.arg[1] = Word; - c.arg[2] = 0; - SendCommand(&c); - WaitForResponse(CMD_ACK, NULL); - - uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00}; - - GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,0); //3560 -- should be offset.. - WaitForResponseTimeout(CMD_ACK,NULL, 1500); - - for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) { - GraphBuffer[j] = ((int)data[j]); - } - GraphTraceLen = LF_TRACE_BUFF_SIZE; - - uint8_t bits[LF_BITSSTREAM_LEN] = {0x00}; - uint8_t * bitstream = bits; - manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream,LF_BITSSTREAM_LEN); - RepaintGraphWindow(); + c.cmd = CMD_EM4X_READ_WORD; + c.d.asBytes[0] = 0x0; //Normal mode + c.arg[0] = 0; + c.arg[1] = Word; + c.arg[2] = 0; + SendCommand(&c); return 0; } int CmdReadWordPWD(const char *Cmd) { - int Word = -1; //default to invalid word - int Password = 0xFFFFFFFF; //default to blank password - UsbCommand c; - - sscanf(Cmd, "%d %x", &Word, &Password); - - if ( (Word > 15) | (Word < 0) ) { - PrintAndLog("Word must be between 0 and 15"); - return 1; - } + int Word = 16; //default to invalid word + int Password = 0xFFFFFFFF; //default to blank password + UsbCommand c; - PrintAndLog("Reading word %d with password %08X", Word, Password); - - c.cmd = CMD_EM4X_READ_WORD; - c.d.asBytes[0] = 0x1; //Password mode - c.arg[0] = 0; - c.arg[1] = Word; - c.arg[2] = Password; - SendCommand(&c); - WaitForResponse(CMD_ACK, NULL); - - uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00}; - - GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,0); //3560 -- should be offset.. - WaitForResponseTimeout(CMD_ACK,NULL, 1500); - - for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) { - GraphBuffer[j] = ((int)data[j]); - } - GraphTraceLen = LF_TRACE_BUFF_SIZE; - - uint8_t bits[LF_BITSSTREAM_LEN] = {0x00}; - uint8_t * bitstream = bits; - manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream, LF_BITSSTREAM_LEN); - RepaintGraphWindow(); + sscanf(Cmd, "%d %x", &Word, &Password); + + if (Word > 15) { + PrintAndLog("Word must be between 0 and 15"); + return 1; + } + + PrintAndLog("Reading word %d with password %08X", Word, Password); + + c.cmd = CMD_EM4X_READ_WORD; + c.d.asBytes[0] = 0x1; //Password mode + c.arg[0] = 0; + c.arg[1] = Word; + c.arg[2] = Password; + SendCommand(&c); return 0; } @@ -613,7 +565,7 @@ int CmdWriteWord(const char *Cmd) return 1; } - PrintAndLog("Writing word %d with data %08X", Word, Data); + PrintAndLog("Writting word %d with data %08X", Word, Data); c.cmd = CMD_EM4X_WRITE_WORD; c.d.asBytes[0] = 0x0; //Normal mode @@ -626,7 +578,7 @@ int CmdWriteWord(const char *Cmd) int CmdWriteWordPWD(const char *Cmd) { - int Word = 16; //default to invalid word + int Word = 8; //default to invalid word int Data = 0xFFFFFFFF; //default to blank data int Password = 0xFFFFFFFF; //default to blank password UsbCommand c; @@ -638,7 +590,7 @@ int CmdWriteWordPWD(const char *Cmd) return 1; } - PrintAndLog("Writing word %d with data %08X and password %08X", Word, Data, Password); + PrintAndLog("Writting word %d with data %08X and password %08X", Word, Data, Password); c.cmd = CMD_EM4X_WRITE_WORD; c.d.asBytes[0] = 0x1; //Password mode @@ -649,283 +601,24 @@ int CmdWriteWordPWD(const char *Cmd) return 0; } + + static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, - {"410xdemod", CmdEMdemodASK, 0, "[clock rate] -- Extract ID from EM410x tag"}, - {"410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"}, - {"410xsim", CmdEM410xSim, 0, " -- Simulate EM410x tag"}, - {"replay", MWRem4xReplay, 0, "Watches for tag and simulates manchester encoded em4x tag"}, - {"410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"}, - {"410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" }, - {"410xwrite", CmdEM410xWrite, 1, " <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"}, - {"4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"}, - {"rd", CmdReadWord, 1, " -- Read EM4xxx word data"}, - {"rdpwd", CmdReadWordPWD, 1, " -- Read EM4xxx word data in password mode "}, - {"wr", CmdWriteWord, 1, " -- Write EM4xxx word data"}, - {"wrpwd", CmdWriteWordPWD, 1, " -- Write EM4xxx word data in password mode"}, + {"em410xdemod", CmdEMdemodASK, 0, "[clock rate] -- Extract ID from EM410x tag"}, + {"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"}, + {"em410xsim", CmdEM410xSim, 0, " -- Simulate EM410x tag"}, + {"em410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"}, + {"em410xwrite", CmdEM410xWrite, 1, " <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"}, + {"em4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"}, + {"readword", CmdReadWord, 1, " -- Read EM4xxx word data"}, + {"readwordPWD", CmdReadWordPWD, 1, " -- Read EM4xxx word data in password mode"}, + {"writeword", CmdWriteWord, 1, " -- Write EM4xxx word data"}, + {"writewordPWD", CmdWriteWordPWD, 1, " -- Write EM4xxx word data in password mode"}, {NULL, NULL, 0, NULL} }; - -//Confirms the parity of a bitstream as well as obtaining the data (TagID) from within the appropriate memory space. -//Arguments: -// Pointer to a string containing the desired bitsream -// Pointer to a string that will receive the decoded tag ID -// Length of the bitsream pointed at in the first argument, char* _strBitStream -//Retuns: -//1 Parity confirmed -//0 Parity not confirmed -int ConfirmEm410xTagParity( char* _strBitStream, char* pID, int LengthOfBitstream ) -{ - int i = 0; - int rows = 0; - int Parity[4] = {0x00}; - char ID[11] = {0x00}; - int k = 0; - int BitStream[70] = {0x00}; - int counter = 0; - //prepare variables - for ( i = 0; i <= LengthOfBitstream; i++) - { - if (_strBitStream[i] == '1') - { - k =1; - memcpy(&BitStream[i], &k,4); - } - else if (_strBitStream[i] == '0') - { - k = 0; - memcpy(&BitStream[i], &k,4); - } - } - while ( counter < 2 ) - { - //set/reset variables and counters - memset(ID,0x00,sizeof(ID)); - memset(Parity,0x00,sizeof(Parity)); - rows = 0; - for ( i = 9; i <= LengthOfBitstream; i++) - { - if ( rows < 10 ) - { - if ((BitStream[i] ^ BitStream[i+1] ^ BitStream[i+2] ^ BitStream[i+3]) == BitStream[i+4]) - { - sprintf(ID+rows, "%x", (8 * BitStream[i]) + (4 * BitStream[i+1]) + (2 * BitStream[i+2]) + (1 * BitStream[i+3])); - rows++; - /* Keep parity info and move four bits ahead*/ - Parity[0] ^= BitStream[i]; - Parity[1] ^= BitStream[i+1]; - Parity[2] ^= BitStream[i+2]; - Parity[3] ^= BitStream[i+3]; - i += 4; - } - } - if ( rows == 10 ) - { - if ( BitStream[i] == Parity[0] && BitStream[i+1] == Parity[1] && - BitStream[i+2] == Parity[2] && BitStream[i+3] == Parity[3] && - BitStream[i+4] == 0) - { - memcpy(pID,ID,strlen(ID)); - return 1; - } - } - } - printf("[PARITY ->]Failed. Flipping Bits, and rechecking parity for bitstream:\n[PARITY ->]"); - for (k = 0; k < LengthOfBitstream; k++) - { - BitStream[k] ^= 1; - printf("%i", BitStream[k]); - } - puts(" "); - counter++; - } - return 0; -} -//Reads and demodulates an em410x RFID tag. It further allows slight modification to the decoded bitstream -//Once a suitable bitstream has been identified, and if needed, modified, it is replayed. Allowing emulation of the -//"stolen" rfid tag. -//No meaningful returns or arguments. -int MWRem4xReplay(const char* Cmd) -{ - // //header traces - // static char ArrayTraceZero[] = { '0','0','0','0','0','0','0','0','0' }; - // static char ArrayTraceOne[] = { '1','1','1','1','1','1','1','1','1' }; - // //local string variables - // char strClockRate[10] = {0x00}; - // char strAnswer[4] = {0x00}; - // char strTempBufferMini[2] = {0x00}; - // //our outbound bit-stream - // char strSimulateBitStream[65] = {0x00}; - // //integers - // int iClockRate = 0; - // int needle = 0; - // int j = 0; - // int iFirstHeaderOffset = 0x00000000; - // int numManchesterDemodBits=0; - // //boolean values - // bool bInverted = false; - // //pointers to strings. memory will be allocated. - // char* pstrInvertBitStream = 0x00000000; - // char* pTempBuffer = 0x00000000; - // char* pID = 0x00000000; - // char* strBitStreamBuffer = 0x00000000; - - - // puts("###################################"); - // puts("#### Em4x Replay ##"); - // puts("#### R.A.M. June 2013 ##"); - // puts("###################################"); - // //initialize - // CmdLFRead(""); - // //Collect ourselves 10,000 samples - // CmdSamples("10000"); - // puts("[->]preforming ASK demodulation\n"); - // //demodulate ask - // Cmdaskdemod("0"); - // iClockRate = DetectClock(0); - // sprintf(strClockRate, "%i\n",iClockRate); - // printf("[->]Detected ClockRate: %s\n", strClockRate); - - // //If detected clock rate is something completely unreasonable, dont go ahead - // if ( iClockRate < 0xFFFE ) - // { - // pTempBuffer = (char*)malloc(MAX_GRAPH_TRACE_LEN); - // if (pTempBuffer == 0x00000000) - // return 0; - // memset(pTempBuffer,0x00,MAX_GRAPH_TRACE_LEN); - // //Preform manchester de-modulation and display in a single line. - // numManchesterDemodBits = CmdManchesterDemod( strClockRate ); - // //note: numManchesterDemodBits is set above in CmdManchesterDemod() - // if ( numManchesterDemodBits == 0 ) - // return 0; - // strBitStreamBuffer = malloc(numManchesterDemodBits+1); - // if ( strBitStreamBuffer == 0x00000000 ) - // return 0; - // memset(strBitStreamBuffer, 0x00, (numManchesterDemodBits+1)); - // //fill strBitStreamBuffer with demodulated, string formatted bits. - // for ( j = 0; j <= numManchesterDemodBits; j++ ) - // { - // sprintf(strTempBufferMini, "%i",BitStream[j]); - // strcat(strBitStreamBuffer,strTempBufferMini); - // } - // printf("[->]Demodulated Bitstream: \n%s\n", strBitStreamBuffer); - // //Reset counter and select most probable bit stream - // j = 0; - // while ( j < numManchesterDemodBits ) - // { - // memset(strSimulateBitStream,0x00,64); - // //search for header of nine (9) 0's : 000000000 or nine (9) 1's : 1111 1111 1 - // if ( ( strncmp(strBitStreamBuffer+j, ArrayTraceZero, sizeof(ArrayTraceZero)) == 0 ) || - // ( strncmp(strBitStreamBuffer+j, ArrayTraceOne, sizeof(ArrayTraceOne)) == 0 ) ) - // { - // iFirstHeaderOffset = j; - // memcpy(strSimulateBitStream, strBitStreamBuffer+j,64); - // printf("[->]Offset of Header"); - // if ( strncmp(strBitStreamBuffer+iFirstHeaderOffset, "0", 1) == 0 ) - // printf("'%s'", ArrayTraceZero ); - // else - // printf("'%s'", ArrayTraceOne ); - // printf(": %i\nHighlighted string : %s\n",iFirstHeaderOffset,strSimulateBitStream); - // //allow us to escape loop or choose another frame - // puts("[<-]Are we happy with this sample? [Y]es/[N]o"); - // gets(strAnswer); - // if ( ( strncmp(strAnswer,"y",1) == 0 ) || ( strncmp(strAnswer,"Y",1) == 0 ) ) - // { - // j = numManchesterDemodBits+1; - // break; - // } - // } - // j++; - // } - // } - // else return 0; - - // //Do we want the buffer inverted? - // memset(strAnswer, 0x00, sizeof(strAnswer)); - // printf("[<-]Do you wish to invert the highlighted bitstream? [Y]es/[N]o\n"); - // gets(strAnswer); - // if ( ( strncmp("y", strAnswer,1) == 0 ) || ( strncmp("Y", strAnswer, 1 ) == 0 ) ) - // { - // //allocate heap memory - // pstrInvertBitStream = (char*)malloc(numManchesterDemodBits); - // if ( pstrInvertBitStream != 0x00000000 ) - // { - // memset(pstrInvertBitStream,0x00,numManchesterDemodBits); - // bInverted = true; - // //Invert Bitstream - // for ( needle = 0; needle <= numManchesterDemodBits; needle++ ) - // { - // if (strSimulateBitStream[needle] == '0') - // strcat(pstrInvertBitStream,"1"); - // else if (strSimulateBitStream[needle] == '1') - // strcat(pstrInvertBitStream,"0"); - // } - // printf("[->]Inverted bitstream: %s\n", pstrInvertBitStream); - // } - // } - // //Confirm parity of selected string - // pID = (char*)malloc(11); - // if (pID != 0x00000000) - // { - // memset(pID, 0x00, 11); - // if (ConfirmEm410xTagParity(strSimulateBitStream,pID, 64) == 1) - // { - // printf("[->]Parity confirmed for selected bitstream!\n"); - // printf("[->]Tag ID was detected as: [hex]:%s\n",pID ); - // } - // else - // printf("[->]Parity check failed for the selected bitstream!\n"); - // } - - // //Spoof - // memset(strAnswer, 0x00, sizeof(strAnswer)); - // printf("[<-]Do you wish to continue with the EM4x simulation? [Y]es/[N]o\n"); - // gets(strAnswer); - // if ( ( strncmp(strAnswer,"y",1) == 0 ) || ( strncmp(strAnswer,"Y",1) == 0 ) ) - // { - // strcat(pTempBuffer, strClockRate); - // strcat(pTempBuffer, " "); - // if (bInverted == true) - // strcat(pTempBuffer,pstrInvertBitStream); - // if (bInverted == false) - // strcat(pTempBuffer,strSimulateBitStream); - // //inform the user - // puts("[->]Starting simulation now: \n"); - // //Simulate tag with prepared buffer. - // CmdLFSimManchester(pTempBuffer); - // } - // else if ( ( strcmp("n", strAnswer) == 0 ) || ( strcmp("N", strAnswer ) == 0 ) ) - // printf("[->]Exiting procedure now...\n"); - // else - // printf("[->]Erroneous selection\nExiting procedure now....\n"); - - // //Clean up -- Exit function - // //clear memory, then release pointer. - // if ( pstrInvertBitStream != 0x00000000 ) - // { - // memset(pstrInvertBitStream,0x00,numManchesterDemodBits); - // free(pstrInvertBitStream); - // } - // if ( pTempBuffer != 0x00000000 ) - // { - // memset(pTempBuffer,0x00,MAX_GRAPH_TRACE_LEN); - // free(pTempBuffer); - // } - // if ( pID != 0x00000000 ) - // { - // memset(pID,0x00,11); - // free(pID); - // } - // if ( strBitStreamBuffer != 0x00000000 ) - // { - // memset(strBitStreamBuffer,0x00,numManchesterDemodBits); - // free(strBitStreamBuffer); - // } - return 0; -} - int CmdLFEM4X(const char *Cmd) { CmdsParse(CommandTable, Cmd); diff --git a/client/cmdlfem4x.h b/client/cmdlfem4x.h index 2282f64e..6363e347 100644 --- a/client/cmdlfem4x.h +++ b/client/cmdlfem4x.h @@ -22,6 +22,5 @@ int CmdReadWord(const char *Cmd); int CmdReadWordPWD(const char *Cmd); int CmdWriteWord(const char *Cmd); int CmdWriteWordPWD(const char *Cmd); -int MWRem4xReplay(const char* Cmd); #endif diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 93d06406..c6d54e78 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -39,12 +39,12 @@ int CmdHIDDemod(const char *Cmd) int CmdHIDDemodFSK(const char *Cmd) { - int findone = 0; + int findone=0; if(Cmd[0]=='1') findone=1; - UsbCommand c = {CMD_HID_DEMOD_FSK}; - c.arg[0]=findone; - SendCommand(&c); - return 0; + UsbCommand c={CMD_HID_DEMOD_FSK}; + c.arg[0]=findone; + SendCommand(&c); + return 0; } int CmdHIDSim(const char *Cmd) diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 74578eea..ab4a2609 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -15,9 +15,9 @@ #include "proxmark3.h" #include "ui.h" #include "cmdparser.h" -#include "../include/common.h" +#include "common.h" #include "util.h" -#include "../include/hitag2.h" +#include "hitag2.h" #include "sleep.h" #include "cmdmain.h" @@ -29,7 +29,7 @@ size_t nbytes(size_t nbits) { int CmdLFHitagList(const char *Cmd) { - uint8_t got[TRACE_BUFFER_SIZE]; + uint8_t got[3000]; GetFromBigBuf(got,sizeof(got),0); WaitForResponse(CMD_ACK,NULL); @@ -39,25 +39,11 @@ int CmdLFHitagList(const char *Cmd) int i = 0; int prev = -1; - int len = strlen(Cmd); - char filename[FILE_PATH_SIZE] = { 0x00 }; - FILE* pf = NULL; - - if (len > FILE_PATH_SIZE) - len = FILE_PATH_SIZE; - memcpy(filename, Cmd, len); - - if (strlen(filename) > 0) { - if ((pf = fopen(filename,"wb")) == NULL) { - PrintAndLog("Error: Could not open file [%s]",filename); - return 1; - } - } - for (;;) { - - if(i >= TRACE_BUFFER_SIZE) { break; } + if(i >= 1900) { + break; + } bool isResponse; int timestamp = *((uint32_t *)(got+i)); @@ -82,7 +68,9 @@ int CmdLFHitagList(const char *Cmd) if (len > 100) { break; } - if (i + len >= TRACE_BUFFER_SIZE) { break;} + if (i + len >= 1900) { + break; + } uint8_t *frame = (got+i+9); @@ -115,23 +103,19 @@ int CmdLFHitagList(const char *Cmd) line); - if (pf) { - fprintf(pf," +%7d: %3d: %s %s\n", - (prev < 0 ? 0 : (timestamp - prev)), - bits, - (isResponse ? "TAG" : " "), - line); - } +// if (pf) { +// fprintf(pf," +%7d: %3d: %s %s\n", +// (prev < 0 ? 0 : (timestamp - prev)), +// bits, +// (isResponse ? "TAG" : " "), +// line); +// } prev = timestamp; i += (len + 9); } - if (pf) { - fclose(pf); - PrintAndLog("Recorded activity succesfully written to file: %s", filename); - } - + return 0; } @@ -142,15 +126,13 @@ int CmdLFHitagSnoop(const char *Cmd) { } int CmdLFHitagSim(const char *Cmd) { - - UsbCommand c = {CMD_SIMULATE_HITAG}; - char filename[FILE_PATH_SIZE] = { 0x00 }; + UsbCommand c = {CMD_SIMULATE_HITAG}; + char filename[256] = { 0x00 }; FILE* pf; bool tag_mem_supplied; - int len = strlen(Cmd); - if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; - memcpy(filename, Cmd, len); - + + param_getstr(Cmd,0,filename); + if (strlen(filename) > 0) { if ((pf = fopen(filename,"rb+")) == NULL) { PrintAndLog("Error: Could not open file [%s]",filename); @@ -158,10 +140,10 @@ int CmdLFHitagSim(const char *Cmd) { } tag_mem_supplied = true; if (fread(c.d.asBytes,48,1,pf) == 0) { - PrintAndLog("Error: File reading error"); + PrintAndLog("Error: File reading error"); fclose(pf); return 1; - } + } fclose(pf); } else { tag_mem_supplied = false; @@ -245,11 +227,11 @@ int CmdLFHitagReader(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, - {"list", CmdLFHitagList, 1, " List Hitag trace history"}, + {"list", CmdLFHitagList, 1, "List Hitag trace history"}, {"reader", CmdLFHitagReader, 1, "Act like a Hitag Reader"}, - {"sim", CmdLFHitagSim, 1, " Simulate Hitag transponder"}, + {"sim", CmdLFHitagSim, 1, "Simulate Hitag transponder"}, {"snoop", CmdLFHitagSnoop, 1, "Eavesdrop Hitag communication"}, - {NULL, NULL, 0, NULL} + {NULL, NULL, 0, NULL} }; int CmdLFHitag(const char *Cmd) diff --git a/client/cmdlfio.c b/client/cmdlfio.c index 129323ac..14ce5498 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -16,13 +16,13 @@ static int CmdHelp(const char *Cmd); int CmdIODemodFSK(const char *Cmd) { - int findone = 0; - if (Cmd[0] =='1') findone = 1; + int findone=0; + if(Cmd[0]=='1') findone=1; - UsbCommand c={CMD_IO_DEMOD_FSK}; - c.arg[0] = findone; - SendCommand(&c); - return 0; + UsbCommand c={CMD_IO_DEMOD_FSK}; + c.arg[0]=findone; + SendCommand(&c); + return 0; } int CmdIOProxDemod(const char *Cmd){ @@ -66,10 +66,10 @@ int CmdIOClone(const char *Cmd) static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"demod", CmdIOProxDemod, 1, "Demodulate Stream"}, - {"fskdemod", CmdIODemodFSK, 0, "['1'] Realtime IO FSK demodulator (option '1' for one tag only)"}, - {"clone", CmdIOClone, 0, "Clone ioProx Tag"}, + {"help", CmdHelp, 1, "This help"}, + {"demod", CmdIOProxDemod, 1, "Demodulate Stream"}, + {"fskdemod", CmdIODemodFSK, 0, "['1'] Realtime IO FSK demodulator (option '1' for one tag only)"}, + {"clone", CmdIOClone, 0, "Clone ioProx Tag"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 24685eb9..a719c7ad 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -13,86 +13,58 @@ #include "proxmark3.h" #include "ui.h" #include "graph.h" -#include "cmdmain.h" #include "cmdparser.h" #include "cmddata.h" #include "cmdlf.h" #include "cmdlft55xx.h" -#include "util.h" -#include "data.h" - -#define LF_TRACE_BUFF_SIZE 20000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..) -#define LF_BITSSTREAM_LEN 1000 // more then 1000 bits shouldn't happend.. 8block * 4 bytes * 8bits = static int CmdHelp(const char *Cmd); + int CmdReadBlk(const char *Cmd) { - int block = -1; - sscanf(Cmd, "%d", &block); + int Block = 8; //default to invalid block + UsbCommand c; - if ((block > 7) | (block < 0)) { - PrintAndLog("Block must be between 0 and 7"); - return 1; - } + sscanf(Cmd, "%d", &Block); - UsbCommand c; - c.cmd = CMD_T55XX_READ_BLOCK; - c.d.asBytes[0] = 0x00; - c.arg[0] = 0; - c.arg[1] = block; - c.arg[2] = 0; - SendCommand(&c); - WaitForResponse(CMD_ACK, NULL); - - uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00}; - - GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,0); //3560 -- should be offset.. - WaitForResponseTimeout(CMD_ACK,NULL, 1500); + if (Block > 7) { + PrintAndLog("Block must be between 0 and 7"); + return 1; + } - for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) { - GraphBuffer[j] = (int)data[j]; - } - GraphTraceLen = LF_TRACE_BUFF_SIZE; - ManchesterDemod(block); - RepaintGraphWindow(); + PrintAndLog("Reading block %d", Block); + + c.cmd = CMD_T55XX_READ_BLOCK; + c.d.asBytes[0] = 0x0; //Normal mode + c.arg[0] = 0; + c.arg[1] = Block; + c.arg[2] = 0; + SendCommand(&c); return 0; } int CmdReadBlkPWD(const char *Cmd) { - int Block = -1; //default to invalid block - int Password = 0xFFFFFFFF; //default to blank Block 7 - UsbCommand c; + int Block = 8; //default to invalid block + int Password = 0xFFFFFFFF; //default to blank Block 7 + UsbCommand c; - sscanf(Cmd, "%d %x", &Block, &Password); + sscanf(Cmd, "%d %x", &Block, &Password); - if ((Block > 7) | (Block < 0)) { - PrintAndLog("Block must be between 0 and 7"); - return 1; - } + if (Block > 7) { + PrintAndLog("Block must be between 0 and 7"); + return 1; + } - PrintAndLog("Reading page 0 block %d pwd %08X", Block, Password); + PrintAndLog("Reading block %d with password %08X", Block, Password); - c.cmd = CMD_T55XX_READ_BLOCK; - c.d.asBytes[0] = 0x1; //Password mode - c.arg[0] = 0; - c.arg[1] = Block; - c.arg[2] = Password; - SendCommand(&c); - WaitForResponse(CMD_ACK, NULL); - - uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00}; - - GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,0); //3560 -- should be offset.. - WaitForResponseTimeout(CMD_ACK,NULL, 1500); - - for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) { - GraphBuffer[j] = ((int)data[j]); - } - GraphTraceLen = LF_TRACE_BUFF_SIZE; - ManchesterDemod(Block); - RepaintGraphWindow(); + c.cmd = CMD_T55XX_READ_BLOCK; + c.d.asBytes[0] = 0x1; //Password mode + c.arg[0] = 0; + c.arg[1] = Block; + c.arg[2] = Password; + SendCommand(&c); return 0; } @@ -147,349 +119,22 @@ int CmdWriteBlkPWD(const char *Cmd) int CmdReadTrace(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: lf t55xx trace [use data from Graphbuffer]"); - PrintAndLog(" [use data from Graphbuffer], if not set, try reading data from tag."); - PrintAndLog(""); - PrintAndLog(" sample: lf t55xx trace"); - PrintAndLog(" sample: lf t55xx trace 1"); - return 0; - } + PrintAndLog("Reading traceability data"); - if ( strlen(Cmd)==0){ - UsbCommand c = {CMD_T55XX_READ_TRACE, {0, 0, 0}}; - SendCommand(&c); - WaitForResponse(CMD_ACK, NULL); - - uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00}; - - GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,0); //3560 -- should be offset.. - WaitForResponseTimeout(CMD_ACK,NULL, 1500); - - for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) { - GraphBuffer[j] = ((int)data[j]); - } - GraphTraceLen = LF_TRACE_BUFF_SIZE; - } - - uint8_t bits[LF_BITSSTREAM_LEN] = {0x00}; - uint8_t * bitstream = bits; - - manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream, LF_BITSSTREAM_LEN); - RepaintGraphWindow(); - - uint8_t si = 5; - uint32_t bl0 = PackBits(si, 32, bitstream); - uint32_t bl1 = PackBits(si+32, 32, bitstream); - - uint32_t acl = PackBits(si, 8, bitstream); si += 8; - uint32_t mfc = PackBits(si, 8, bitstream); si += 8; - uint32_t cid = PackBits(si, 5, bitstream); si += 5; - uint32_t icr = PackBits(si, 3, bitstream); si += 3; - uint32_t year = PackBits(si, 4, bitstream); si += 4; - uint32_t quarter = PackBits(si, 2, bitstream); si += 2; - uint32_t lotid = PackBits(si, 12, bitstream); si += 12; - uint32_t wafer = PackBits(si, 5, bitstream); si += 5; - uint32_t dw = PackBits(si, 15, bitstream); - - PrintAndLog(""); - PrintAndLog("-- T55xx Trace Information ----------------------------------"); - PrintAndLog("-------------------------------------------------------------"); - PrintAndLog(" ACL Allocation class (ISO/IEC 15963-1) : 0x%02X (%d)", acl, acl); - PrintAndLog(" MFC Manufacturer ID (ISO/IEC 7816-6) : 0x%02X (%d)", mfc, mfc); - PrintAndLog(" CID : 0x%02X (%d)", cid, cid); - PrintAndLog(" ICR IC Revision : %d",icr ); - PrintAndLog(" Manufactured"); - PrintAndLog(" Year/Quarter : %d/%d",2000+year, quarter ); - PrintAndLog(" Lot ID : %d", lotid ); - PrintAndLog(" Wafer number : %d", wafer); - PrintAndLog(" Die Number : %d", dw); - PrintAndLog("-------------------------------------------------------------"); - PrintAndLog(" Raw Data - Page 1"); - PrintAndLog(" Block 0 : 0x%08X %s", bl0, sprint_bin(bitstream+5,32) ); - PrintAndLog(" Block 0 : 0x%08X %s", bl1, sprint_bin(bitstream+37,32) ); - PrintAndLog("-------------------------------------------------------------"); - /* - TRACE - BLOCK O - Bits Definition HEX - 1-8 ACL Allocation class (ISO/IEC 15963-1) 0xE0 - 9-16 MFC Manufacturer ID (ISO/IEC 7816-6) 0x15 Atmel Corporation - 17-21 CID 0x1 = Atmel ATA5577M1 0x2 = Atmel ATA5577M2 - 22-24 ICR IC revision - 25-28 YEAR (BCD encoded) 9 (= 2009) - 29-30 QUARTER 1,2,3,4 - 31-32 LOT ID - - TRACE - BLOCK 1 - 1-12 LOT ID - 13-17 Wafer number - 18-32 DW, die number sequential - */ - + UsbCommand c = {CMD_T55XX_READ_TRACE, {0, 0, 0}}; + SendCommand(&c); return 0; } -int CmdInfo(const char *Cmd){ - /* - Page 0 Block 0 Configuration data. - Normal mode - Extended mode - */ - char cmdp = param_getchar(Cmd, 0); - - if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: lf t55xx info [use data from Graphbuffer]"); - PrintAndLog(" [use data from Graphbuffer], if not set, try reading data from tag."); - PrintAndLog(""); - PrintAndLog(" sample: lf t55xx info"); - PrintAndLog(" sample: lf t55xx info 1"); - return 0; - } - - if ( strlen(Cmd) == 0 ){ - CmdReadBlk("0"); - } - - uint8_t bits[LF_BITSSTREAM_LEN] = {0x00}; - - manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bits, LF_BITSSTREAM_LEN); - - uint8_t si = 5; - uint32_t bl0 = PackBits(si, 32, bits); - - uint32_t safer = PackBits(si, 4, bits); si += 4; - uint32_t resv = PackBits(si, 7, bits); si += 7; - uint32_t dbr = PackBits(si, 3, bits); si += 3; - uint32_t extend = PackBits(si, 1, bits); si += 1; - uint32_t datamodulation = PackBits(si, 5, bits); si += 5; - uint32_t pskcf = PackBits(si, 2, bits); si += 2; - uint32_t aor = PackBits(si, 1, bits); si += 1; - uint32_t otp = PackBits(si, 1, bits); si += 1; - uint32_t maxblk = PackBits(si, 3, bits); si += 3; - uint32_t pwd = PackBits(si, 1, bits); si += 1; - uint32_t sst = PackBits(si, 1, bits); si += 1; - uint32_t fw = PackBits(si, 1, bits); si += 1; - uint32_t inv = PackBits(si, 1, bits); si += 1; - uint32_t por = PackBits(si, 1, bits); si += 1; - - PrintAndLog(""); - PrintAndLog("-- T55xx Configuration --------------------------------------"); - PrintAndLog("-------------------------------------------------------------"); - PrintAndLog(" Safer key : %s", GetSaferStr(safer)); - PrintAndLog(" reserved : %d", resv); - PrintAndLog(" Data bit rate : %s", GetBitRateStr(dbr)); - PrintAndLog(" eXtended mode : %s", (extend) ? "Yes - Warning":"No"); - PrintAndLog(" Modulation : %s", GetModulationStr(datamodulation) ); - PrintAndLog(" PSK clock freq : %d", pskcf); - PrintAndLog(" AOR - Answer on Request : %s", (aor) ? "Yes":"No"); - PrintAndLog(" OTP - One Time Pad : %s", (otp) ? "Yes - Warning":"No" ); - PrintAndLog(" Max block : %d", maxblk); - PrintAndLog(" Password mode : %s", (pwd) ? "Yes":"No"); - PrintAndLog(" Sequence Start Terminator : %s", (sst) ? "Yes":"No"); - PrintAndLog(" Fast Write : %s", (fw) ? "Yes":"No"); - PrintAndLog(" Inverse data : %s", (inv) ? "Yes":"No"); - PrintAndLog(" POR-Delay : %s", (por) ? "Yes":"No"); - PrintAndLog("-------------------------------------------------------------"); - PrintAndLog(" Raw Data - Page 0"); - PrintAndLog(" Block 0 : 0x%08X %s", bl0, sprint_bin(bits+5,32) ); - PrintAndLog("-------------------------------------------------------------"); - - return 0; -} - -int CmdDump(const char *Cmd){ - - char cmdp = param_getchar(Cmd, 0); - char s[20]; - uint8_t pwd[4] = {0x00}; - bool hasPwd = ( strlen(Cmd) > 0); - - if ( cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: lf t55xx dump "); - PrintAndLog(" sample: lf t55xx dump FFFFFFFF"); - return 0; - } - - if ( hasPwd ){ - if (param_gethex(Cmd, 0, pwd, 8)) { - PrintAndLog("password must include 8 HEX symbols"); - return 0; - } - } - - for ( int i = 0; i <8; ++i){ - memset(s,0,sizeof(s)); - if ( hasPwd ) { - sprintf(s,"%d %02x%02x%02x%02x", i, pwd[0],pwd[1],pwd[2],pwd[3]); - CmdReadBlkPWD(s); - } else { - sprintf(s,"%d", i); - CmdReadBlk(s); - } - } - return 0; -} - -int CmdIceFsk(const char *Cmd){ - - if (!HasGraphData()) return 0; - - iceFsk3(GraphBuffer, LF_TRACE_BUFF_SIZE); - RepaintGraphWindow(); - return 0; -} -int CmdIceManchester(const char *Cmd){ - ManchesterDemod( -1); - return 0; -} -int ManchesterDemod(int blockNum){ - - if (!HasGraphData()) return 0; - - uint8_t sizebyte = 32; - // the value 5 was selected during empirical studies of the decoded data. Some signal noise to skip. - uint8_t offset = 5; - uint32_t blockData; - uint8_t bits[LF_BITSSTREAM_LEN] = {0x00}; - uint8_t * bitstream = bits; - - //manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream, LF_BITSSTREAM_LEN); - manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bits, LF_BITSSTREAM_LEN); - //blockData = PackBits(offset, sizebyte, bitstream); - blockData = PackBits(offset, sizebyte, bits); - - if ( blockNum < 0) - PrintAndLog(" Decoded : 0x%08X %s", blockData, sprint_bin(bitstream+offset,sizebyte) ); - else - PrintAndLog(" Block %d : 0x%08X %s", blockNum, blockData, sprint_bin(bitstream+offset,sizebyte) ); - - return 0; -} - -char * GetBitRateStr(uint32_t id){ - static char buf[40]; - char *retStr = buf; - switch (id){ - case 0: - sprintf(retStr,"%d - RF/8",id); - break; - case 1: - sprintf(retStr,"%d - RF/16",id); - break; - case 2: - sprintf(retStr,"%d - RF/32",id); - break; - case 3: - sprintf(retStr,"%d - RF/40",id); - break; - case 4: - sprintf(retStr,"%d - RF/50",id); - break; - case 5: - sprintf(retStr,"%d - RF/64",id); - break; - case 6: - sprintf(retStr,"%d - RF/100",id); - break; - case 7: - sprintf(retStr,"%d - RF/128",id); - break; - default: - sprintf(retStr,"%d - (Unknown)",id); - break; - } - - return buf; -} - -char * GetSaferStr(uint32_t id){ - static char buf[40]; - char *retStr = buf; - - sprintf(retStr,"%d",id); - if (id == 6) { - sprintf(retStr,"%d - pasdwd",id); - } - if (id == 9 ){ - sprintf(retStr,"%d - testmode ",id); - } - - return buf; -} -char * GetModulationStr( uint32_t id){ - static char buf[40]; - char *retStr = buf; - - switch (id){ - case 0: - sprintf(retStr,"%d - DIRECT (ASK/NRZ)",id); - break; - case 1: - sprintf(retStr,"%d - PSK 1 phase change when input changes",id); - break; - case 2: - sprintf(retStr,"%d - PSK 2 phase change on bitclk if input high",id); - break; - case 3: - sprintf(retStr,"%d - PSK 3 phase change on rising edge of input",id); - break; - case 4: - sprintf(retStr,"%d - FSK 1 RF/8 RF/5",id); - break; - case 5: - sprintf(retStr,"%d - FSK 2 RF/8 RF/10",id); - break; - case 6: - sprintf(retStr,"%d - FSK 1a RF/5 RF/8",id); - break; - case 7: - sprintf(retStr,"%d - FSK 2a RF/10 RF/8",id); - break; - case 8: - sprintf(retStr,"%d - Manschester",id); - break; - case 16: - sprintf(retStr,"%d - Biphase",id); - break; - case 17: - sprintf(retStr,"%d - Reserved",id); - break; - default: - sprintf(retStr,"0x%02X (Unknown)",id); - break; - } - return buf; -} - - -uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){ - - int i = start; - int j = len-1; - if (len > 32) { - return 0; - } - uint32_t tmp = 0; - for (; j >= 0; --j, ++i){ - tmp |= bits[i] << j; - } - return tmp; -} - static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"rd", CmdReadBlk, 0, " -- Read T55xx block data (page 0)"}, - {"rdpwd", CmdReadBlkPWD, 0, " -- Read T55xx block data with password mode"}, - {"wr", CmdWriteBlk, 0, " -- Write T55xx block data (page 0)"}, - {"wrpwd", CmdWriteBlkPWD, 0, " -- Write T55xx block data with password"}, - {"trace", CmdReadTrace, 0, "[1] Read T55xx traceability data (page 1/ blk 0-1)"}, - {"info", CmdInfo, 0, "[1] Read T55xx configuration data (page 0/ blk 0)"}, - {"dump", CmdDump, 0, "[password] Dump T55xx card block 0-7. optional with password"}, - {"fsk", CmdIceFsk, 0, "FSK demod"}, - {"man", CmdIceManchester, 0, "Manchester demod (with SST)"}, + {"help", CmdHelp, 1, "This help"}, + {"readblock", CmdReadBlk, 1, " -- Read T55xx block data (page 0)"}, + {"readblockPWD", CmdReadBlkPWD, 1, " -- Read T55xx block data in password mode(page 0)"}, + {"writeblock", CmdWriteBlk, 1, " -- Write T55xx block data (page 0)"}, + {"writeblockPWD", CmdWriteBlkPWD, 1, " -- Write T55xx block data in password mode(page 0)"}, + {"readtrace", CmdReadTrace, 1, "Read T55xx traceability data (page 1)"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 8c0cdf58..25503e87 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -17,12 +17,5 @@ int CmdReadBlkPWD(const char *Cmd); int CmdWriteBlk(const char *Cmd); int CmdWriteBLkPWD(const char *Cmd); int CmdReadTrace(const char *Cmd); -int CmdInfo(const char *Cmd); -int CmdIceFsk(const char *Cmd); -int CmdIceManchester(const char *Cmd); -int ManchesterDemod(int block); -char * GetBitRateStr(uint32_t id); -char * GetSaferStr(uint32_t id); -char * GetModulationStr( uint32_t id); -uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bitstream); + #endif diff --git a/client/cmdmain.c b/client/cmdmain.c index b3f04e10..df3d4b2e 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -16,7 +16,7 @@ #include "cmdparser.h" #include "proxmark3.h" #include "data.h" -#include "../include/usb_cmd.h" +#include "usb_cmd.h" #include "ui.h" #include "cmdhf.h" #include "cmddata.h" @@ -42,14 +42,14 @@ static int cmd_tail;//Starts as 0 static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help. Use ' help' for details of a particular command."}, - {"data", CmdData, 1, "{ Plot window / data buffer manipulation... }"}, + {"help", CmdHelp, 1, "This help. Use ' help' for details of a particular command."}, + {"data", CmdData, 1, "{ Plot window / data buffer manipulation... }"}, {"hf", CmdHF, 1, "{ High Frequency commands... }"}, - {"hw", CmdHW, 1, "{ Hardware commands... }"}, + {"hw", CmdHW, 1, "{ Hardware commands... }"}, {"lf", CmdLF, 1, "{ Low Frequency commands... }"}, - {"script", CmdScript, 1,"{ Scripting commands }"}, - {"quit", CmdQuit, 1, "Exit program"}, - {"exit", CmdQuit, 1, "Exit program"}, + {"script", CmdScript, 1,"{ Scripting commands }"}, + {"quit", CmdQuit, 1, "Exit program"}, + {"exit", CmdQuit, 1, "Exit program"}, {NULL, NULL, 0, NULL} }; @@ -130,26 +130,27 @@ int getCommand(UsbCommand* response) * @return true if command was returned, otherwise false */ bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) { + + UsbCommand resp; - UsbCommand resp; - - if (response == NULL) - response = &resp; + if (response == NULL) { + response = &resp; + } + // Wait until the command is received + for(size_t dm_seconds=0; dm_seconds < ms_timeout/10; dm_seconds++) { - // Wait until the command is received - for(size_t dm_seconds=0; dm_seconds < ms_timeout/10; dm_seconds++) { - - while(getCommand(response)) { - if(response->cmd == cmd){ - return true; - } - } - msleep(10); // XXX ugh - if (dm_seconds == 200) { // Two seconds elapsed - PrintAndLog("Waiting for a response from the proxmark..."); - PrintAndLog("Don't forget to cancel its operation first by pressing on the button"); - } + while(getCommand(response)) + { + if(response->cmd == cmd){ + return true; + } + } + msleep(10); // XXX ugh + if (dm_seconds == 200) { // Two seconds elapsed + PrintAndLog("Waiting for a response from the proxmark..."); + PrintAndLog("Don't forget to cancel its operation first by pressing on the button"); + } } return false; } @@ -172,29 +173,29 @@ void CommandReceived(char *Cmd) { //----------------------------------------------------------------------------- void UsbCommandReceived(UsbCommand *UC) { - switch(UC->cmd) { - // First check if we are handling a debug message - case CMD_DEBUG_PRINT_STRING: { + switch(UC->cmd) { + // First check if we are handling a debug message + case CMD_DEBUG_PRINT_STRING: { char s[USB_CMD_DATA_SIZE+1] = {0x00}; - size_t len = MIN(UC->arg[0],USB_CMD_DATA_SIZE); - memcpy(s,UC->d.asBytes,len); - PrintAndLog("#db# %s ", s); - return; - } break; + size_t len = MIN(UC->arg[0],USB_CMD_DATA_SIZE); + memcpy(s,UC->d.asBytes,len); + PrintAndLog("#db# %s ", s); + return; + } break; - case CMD_DEBUG_PRINT_INTEGERS: { - PrintAndLog("#db# %08x, %08x, %08x \r\n", UC->arg[0], UC->arg[1], UC->arg[2]); - return; - } break; - - case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: { - sample_buf_len += UC->arg[1]; - memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]); - } break; + case CMD_DEBUG_PRINT_INTEGERS: { + PrintAndLog("#db# %08x, %08x, %08x \r\n", UC->arg[0], UC->arg[1], UC->arg[2]); + return; + } break; + + case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: { + sample_buf_len += UC->arg[1]; + memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]); + } break; default: - break; - } + break; + } storeCommand(UC); } diff --git a/client/cmdmain.h b/client/cmdmain.h index 5e4ee73a..0cf2b35d 100644 --- a/client/cmdmain.h +++ b/client/cmdmain.h @@ -11,7 +11,7 @@ #ifndef CMDMAIN_H__ #define CMDMAIN_H__ -#include "../include/usb_cmd.h" +#include "usb_cmd.h" #include "cmdparser.h" void UsbCommandReceived(UsbCommand *UC); void CommandReceived(char *Cmd); diff --git a/client/data.h b/client/data.h index 41bd9a41..33ee9d04 100644 --- a/client/data.h +++ b/client/data.h @@ -13,9 +13,6 @@ #include -//trace buffer size as defined in armsrc/apps.h TRACE_SIZE -#define TRACE_BUFFER_SIZE 4096 -#define FILE_PATH_SIZE 1000 #define SAMPLE_BUFFER_SIZE 64 extern uint8_t* sample_buf; diff --git a/client/flash.c b/client/flash.c index 7976d410..4e222ece 100644 --- a/client/flash.c +++ b/client/flash.c @@ -16,7 +16,7 @@ #include "flash.h" #include "elf.h" #include "proxendian.h" -#include "../include/usb_cmd.h" +#include "usb_cmd.h" void SendCommand(UsbCommand* txcmd); void ReceiveCommand(UsbCommand* rxcmd); @@ -275,7 +275,7 @@ static int get_proxmark_state(uint32_t *state) { UsbCommand c; c.cmd = CMD_DEVICE_INFO; - SendCommand(&c); + SendCommand(&c); UsbCommand resp; ReceiveCommand(&resp); @@ -404,11 +404,11 @@ static int write_block(uint32_t address, uint8_t *data, uint32_t length) memset(block_buf, 0xFF, BLOCK_SIZE); memcpy(block_buf, data, length); - UsbCommand c; + UsbCommand c; c.cmd = CMD_FINISH_WRITE; c.arg[0] = address; memcpy(c.d.asBytes, block_buf, length); - SendCommand(&c); + SendCommand(&c); return wait_for_ack(); } @@ -469,7 +469,7 @@ void flash_free(flash_file_t *ctx) // just reset the unit int flash_stop_flashing(void) { UsbCommand c = {CMD_HARDWARE_RESET}; - SendCommand(&c); - msleep(100); - return 0; + SendCommand(&c); + msleep(100); + return 0; } diff --git a/client/flasher.c b/client/flasher.c index 1390d817..2a24ba8f 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -13,7 +13,7 @@ #include "proxmark3.h" #include "flash.h" #include "uart.h" -#include "../include/usb_cmd.h" +#include "usb_cmd.h" #ifdef _WIN32 # define unlink(x) diff --git a/client/graph.c b/client/graph.c index d0f6fe74..a0e85ffd 100644 --- a/client/graph.c +++ b/client/graph.c @@ -9,7 +9,6 @@ //----------------------------------------------------------------------------- #include -#include #include #include "ui.h" #include "graph.h" @@ -22,13 +21,11 @@ int GraphTraceLen; void AppendGraph(int redraw, int clock, int bit) { int i; - int half = (int)(clock/2); - int firstbit = bit ^ 1; - - for (i = 0; i < half; ++i) - GraphBuffer[GraphTraceLen++] = firstbit; + + for (i = 0; i < (int)(clock / 2); ++i) + GraphBuffer[GraphTraceLen++] = bit ^ 1; - for (i = 0; i <= half; ++i) + for (i = (int)(clock / 2); i < clock; ++i) GraphBuffer[GraphTraceLen++] = bit; if (redraw) @@ -39,106 +36,154 @@ void AppendGraph(int redraw, int clock, int bit) int ClearGraph(int redraw) { int gtl = GraphTraceLen; - memset(GraphBuffer, 0x00, GraphTraceLen); - GraphTraceLen = 0; - + if (redraw) RepaintGraphWindow(); return gtl; } -void SetGraphBuf(uint8_t *buff, int size) +/* + * Detect clock rate + */ + //decommissioned - has difficulty detecting rf/32 +/* +int DetectClockOld(int peak) { - if ( buff == NULL ) return; - - uint16_t i = 0; - if ( size > MAX_GRAPH_TRACE_LEN ) - size = MAX_GRAPH_TRACE_LEN; - ClearGraph(0); - for (; i < size; ++i){ - GraphBuffer[i] = buff[i]; - } - GraphTraceLen = size; - RepaintGraphWindow(); - return; -} + int i; + int clock = 0xFFFF; + int lastpeak = 0; -// Copies grahpbuff to buff. -// while triming values to the range -127 -- 127. -int GetFromGraphBuf(uint8_t *buff) + // Detect peak if we don't have one + if (!peak) + for (i = 0; i < GraphTraceLen; ++i) + if (GraphBuffer[i] > peak) + peak = GraphBuffer[i]; + + // peak=(int)(peak*.75); + for (i = 1; i < GraphTraceLen; ++i) + { + // If this is the beginning of a peak + if (GraphBuffer[i - 1] != GraphBuffer[i] && GraphBuffer[i] >= peak) + { + // Find lowest difference between peaks + if (lastpeak && i - lastpeak < clock) + clock = i - lastpeak; + lastpeak = i; + } + } + + return clock; +} +*/ +/* +NOW IN LFDEMOD.C + +// by marshmellow +// not perfect especially with lower clocks or VERY good antennas (heavy wave clipping) +// maybe somehow adjust peak trimming value based on samples to fix? +int DetectASKClock(int peak) { - if ( buff == NULL ) return -1; - uint32_t i = 0; - - for (; i < GraphTraceLen; ++i){ - - // trim upper and lower values. - if (GraphBuffer[i] > 127) - GraphBuffer[i] = 127; - else if (GraphBuffer[i] < -127) - GraphBuffer[i] = -127; - - buff[i] = (uint8_t)(GraphBuffer[i] + 128); - } - return i; + int i=0; + int low=0; + int clk[]={16,32,40,50,64,100,128,256}; + int loopCnt = 256; + if (GraphTraceLenpeak){ + peak = GraphBuffer[i]; + } + if(GraphBuffer[i]=peak) || (GraphBuffer[ii]<=low)){ + errCnt[clkCnt]=0; + for (i=0; i<((int)(GraphTraceLen/clk[clkCnt])-1); ++i){ + if (GraphBuffer[ii+(i*clk[clkCnt])]>=peak || GraphBuffer[ii+(i*clk[clkCnt])]<=low){ + }else if(GraphBuffer[ii+(i*clk[clkCnt])-tol]>=peak || GraphBuffer[ii+(i*clk[clkCnt])-tol]<=low){ + }else if(GraphBuffer[ii+(i*clk[clkCnt])+tol]>=peak || GraphBuffer[ii+(i*clk[clkCnt])+tol]<=low){ + }else{ //error no peak detected + errCnt[clkCnt]++; + } + } + if(errCnt[clkCnt]==0) return clk[clkCnt]; + if(errCnt[clkCnt]127) GraphBuffer[i]=127; //trim + if (GraphBuffer[i]<-127) GraphBuffer[i]=-127; //trim + buff[i]=(uint8_t)(GraphBuffer[i]+128); + } + return i; } /* Get or auto-detect clock rate */ -int GetClock(const char *str, int verbose) +int GetClock(const char *str, int peak, int verbose) { - int clock; + int clock; +// int clock2; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; - sscanf(str, "%i", &clock); - if (!strcmp(str, "")) - clock = 0; + /* Auto-detect clock */ + if (!clock) + { + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + int size = getFromGraphBuf(grph); + clock = DetectASKClock(grph,size,0); + //clock2 = DetectClock2(peak); + /* Only print this message if we're not looping something */ + if (!verbose){ + PrintAndLog("Auto-detected clock rate: %d", clock); + //PrintAndLog("clock2: %d",clock2); + } + } - /* Auto-detect clock */ - if (!clock) { - - uint8_t grph[MAX_GRAPH_TRACE_LEN] = {0x00}; - int size = GetFromGraphBuf(grph); - if ( size < 0 ) { - PrintAndLog("Failed to copy from graphbuffer"); - return -1; - } - clock = DetectASKClock(grph, size, 0); - - /* Only print this message if we're not looping something */ - if (verbose) - PrintAndLog("Auto-detected clock rate: %d", clock); - } - return clock; + return clock; } - -// A simple test to see if there is any data inside Graphbuffer. -bool HasGraphData(){ - - if ( GraphTraceLen <= 0) { - PrintAndLog("No data available, try reading something first"); - return false; - } - return true; -} - -// Detect high and lows in Grapbuffer. -// Only loops the first 256 values. -void DetectHighLowInGraph(int *high, int *low, bool addFuzz) { - - uint8_t loopMax = 255; - if ( loopMax > GraphTraceLen) - loopMax = GraphTraceLen; - - for (uint8_t i = 0; i < loopMax; ++i) { - if (GraphBuffer[i] > *high) - *high = GraphBuffer[i]; - else if (GraphBuffer[i] < *low) - *low = GraphBuffer[i]; - } - - //12% fuzz in case highs and lows aren't clipped - if (addFuzz) { - *high = (int)(*high * .88); - *low = (int)(*low * .88); - } -} \ No newline at end of file diff --git a/client/graph.h b/client/graph.h index c745270d..325582a6 100644 --- a/client/graph.h +++ b/client/graph.h @@ -10,16 +10,17 @@ #ifndef GRAPH_H__ #define GRAPH_H__ +#include void AppendGraph(int redraw, int clock, int bit); int ClearGraph(int redraw); -int GetFromGraphBuf(uint8_t *buff); -int GetClock(const char *str, int verbose); -void SetGraphBuf(uint8_t *buff,int size); -bool HasGraphData(); -void DetectHighLowInGraph(int *high, int *low, bool addFuzz); +//int DetectClock(int peak); +int getFromGraphBuf(uint8_t *buff); +int GetClock(const char *str, int peak, int verbose); +void setGraphBuf(uint8_t *buff,int size); #define MAX_GRAPH_TRACE_LEN (1024*128) extern int GraphBuffer[MAX_GRAPH_TRACE_LEN]; extern int GraphTraceLen; + #endif diff --git a/client/loclass/cipher.c b/client/loclass/cipher.c index 1c9dae8b..463ba9be 100644 --- a/client/loclass/cipher.c +++ b/client/loclass/cipher.c @@ -1,17 +1,5 @@ /***************************************************************************** - * WARNING - * - * THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. - * - * USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL - * PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, - * AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. - * - * THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. - * - ***************************************************************************** - * - * This file is part of loclass. It is a reconstructon of the cipher engine + * This file is part of iClassCipher. It is a reconstructon of the cipher engine * used in iClass, and RFID techology. * * The implementation is based on the work performed by @@ -215,7 +203,7 @@ void MAC(uint8_t* k, BitstreamIn input, BitstreamOut out) BitstreamIn input_32_zeroes = {zeroes_32,sizeof(zeroes_32)*8,0}; State initState = suc(k,init(k),&input); output(k,initState,&input_32_zeroes,&out); -} +} void doMAC(uint8_t *cc_nr_p, int length, uint8_t *div_key_p, uint8_t mac[4]) { @@ -224,17 +212,17 @@ void doMAC(uint8_t *cc_nr_p, int length, uint8_t *div_key_p, uint8_t mac[4]) cc_nr=(uint8_t*)malloc(length+1); memcpy(cc_nr,cc_nr_p,length); memcpy(div_key,div_key_p,8); - - reverse_arraybytes(cc_nr,length); - BitstreamIn bitstream = {cc_nr,length * 8,0}; - uint8_t dest []= {0,0,0,0,0,0,0,0}; - BitstreamOut out = { dest, sizeof(dest)*8, 0 }; - MAC(div_key,bitstream, out); - //The output MAC must also be reversed - reverse_arraybytes(dest, sizeof(dest)); - memcpy(mac,dest,4); + + reverse_arraybytes(cc_nr,length); + BitstreamIn bitstream = {cc_nr,length * 8,0}; + uint8_t dest []= {0,0,0,0,0,0,0,0}; + BitstreamOut out = { dest, sizeof(dest)*8, 0 }; + MAC(div_key,bitstream, out); + //The output MAC must also be reversed + reverse_arraybytes(dest, sizeof(dest)); + memcpy(mac, dest, 4); //printf("Calculated_MAC\t%02x%02x%02x%02x\n", dest[0],dest[1],dest[2],dest[3]); - free(cc_nr); + free(cc_nr); return; } @@ -260,8 +248,8 @@ int testMAC() prnlog("[+] FAILED: MAC calculation failed:"); printarr(" Calculated_MAC", calculated_mac, 4); printarr(" Correct_MAC ", correct_MAC, 4); - return 1; -} + return 1; + } return 0; } diff --git a/client/loclass/cipher.h b/client/loclass/cipher.h index 314a560a..4bfbe0b7 100644 --- a/client/loclass/cipher.h +++ b/client/loclass/cipher.h @@ -1,17 +1,5 @@ /***************************************************************************** - * WARNING - * - * THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. - * - * USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL - * PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, - * AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. - * - * THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. - * - ***************************************************************************** - * - * This file is part of loclass. It is a reconstructon of the cipher engine + * This file is part of iClassCipher. It is a reconstructon of the cipher engine * used in iClass, and RFID techology. * * The implementation is based on the work performed by diff --git a/client/loclass/cipherutils.c b/client/loclass/cipherutils.c index f82a11ce..e11e8d22 100644 --- a/client/loclass/cipherutils.c +++ b/client/loclass/cipherutils.c @@ -1,17 +1,5 @@ /***************************************************************************** - * WARNING - * - * THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. - * - * USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL - * PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, - * AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. - * - * THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. - * - ***************************************************************************** - * - * This file is part of loclass. It is a reconstructon of the cipher engine + * This file is part of iClassCipher. It is a reconstructon of the cipher engine * used in iClass, and RFID techology. * * The implementation is based on the work performed by diff --git a/client/loclass/cipherutils.h b/client/loclass/cipherutils.h index e2338534..acf96115 100644 --- a/client/loclass/cipherutils.h +++ b/client/loclass/cipherutils.h @@ -1,17 +1,5 @@ /***************************************************************************** - * WARNING - * - * THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. - * - * USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL - * PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, - * AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. - * - * THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. - * - ***************************************************************************** - * - * This file is part of loclass. It is a reconstructon of the cipher engine + * This file is part of iClassCipher. It is a reconstructon of the cipher engine * used in iClass, and RFID techology. * * The implementation is based on the work performed by diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index 3801d662..f0eb964b 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -1,41 +1,3 @@ -/***************************************************************************** - * WARNING - * - * THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. - * - * USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL - * PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, - * AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. - * - * THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. - * - ***************************************************************************** - * - * This file is part of loclass. It is a reconstructon of the cipher engine - * used in iClass, and RFID techology. - * - * The implementation is based on the work performed by - * Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and - * Milosch Meriac in the paper "Dismantling IClass". - * - * Copyright (C) 2014 Martin Holst Swende - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with loclass. If not, see . - * - * - * - ****************************************************************************/ - #include #include #include @@ -552,6 +514,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) */ int bruteforceFile(const char *filename, uint16_t keytable[]) { + FILE *f = fopen(filename, "rb"); if(!f) { prnlog("Failed to read from file '%s'", filename); @@ -563,7 +526,7 @@ int bruteforceFile(const char *filename, uint16_t keytable[]) fseek(f, 0, SEEK_SET); uint8_t *dump = malloc(fsize); - size_t bytes_read = fread(dump, fsize, 1, f); + size_t bytes_read = fread(dump, 1, fsize, f); fclose(f); if (bytes_read < fsize) @@ -614,9 +577,18 @@ int _testBruteforce() **** The 64-bit HS Custom Key Value = 5B7C62C491C11B39 **** **/ uint16_t keytable[128] = {0}; - //save some time... - startvalue = 0x7B0000; - errors |= bruteforceFile("iclass_dump.bin",keytable); + + //Test a few variants + if(fileExists("iclass_dump.bin")) + { + errors |= bruteforceFile("iclass_dump.bin",keytable); + }else if(fileExists("loclass/iclass_dump.bin")){ + errors |= bruteforceFile("loclass/iclass_dump.bin",keytable); + }else if(fileExists("client/loclass/iclass_dump.bin")){ + errors |= bruteforceFile("client/loclass/iclass_dump.bin",keytable); + }else{ + prnlog("Error: The file iclass_dump.bin was not found!"); + } } return errors; } diff --git a/client/loclass/elite_crack.h b/client/loclass/elite_crack.h index fb27355f..21004e59 100644 --- a/client/loclass/elite_crack.h +++ b/client/loclass/elite_crack.h @@ -1,42 +1,3 @@ -/***************************************************************************** - * WARNING - * - * THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. - * - * USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL - * PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, - * AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. - * - * THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. - * - ***************************************************************************** - * - * This file is part of loclass. It is a reconstructon of the cipher engine - * used in iClass, and RFID techology. - * - * The implementation is based on the work performed by - * Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and - * Milosch Meriac in the paper "Dismantling IClass". - * - * Copyright (C) 2014 Martin Holst Swende - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with loclass. If not, see . - * - * - * - ****************************************************************************/ - - #ifndef ELITE_CRACK_H #define ELITE_CRACK_H void permutekey(uint8_t key[8], uint8_t dest[8]); diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c index 443070c1..f96f8652 100644 --- a/client/loclass/fileutils.c +++ b/client/loclass/fileutils.c @@ -1,41 +1,3 @@ -/***************************************************************************** - * WARNING - * - * THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. - * - * USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL - * PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, - * AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. - * - * THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. - * - ***************************************************************************** - * - * This file is part of loclass. It is a reconstructon of the cipher engine - * used in iClass, and RFID techology. - * - * The implementation is based on the work performed by - * Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and - * Milosch Meriac in the paper "Dismantling IClass". - * - * Copyright (C) 2014 Martin Holst Swende - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with loclass. If not, see . - * - * - * - ****************************************************************************/ - #include #include #include @@ -51,11 +13,11 @@ int fileExists(const char *filename) { #ifdef _WIN32 - struct _stat fileStat; - int result = _stat(filename, &fileStat); + struct _stat st; + int result = _stat(filename, &st); #else - struct stat fileStat; - int result = stat(filename, &fileStat); + struct stat st; + int result = stat(filename, &st); #endif return result == 0; } @@ -76,33 +38,21 @@ int saveFile(const char *preferredName, const char *suffix, const void* data, si /* We should have a valid filename now, e.g. dumpdata-3.bin */ /*Opening file for writing in binary mode*/ - FILE *fh=fopen(fileName,"wb"); - if(!fh) { + FILE *fileHandle=fopen(fileName,"wb"); + if(!fileHandle) { PrintAndLog("Failed to write to file '%s'", fileName); - free(fh); + free(fileName); return 1; } - fwrite(data, 1, datalen, fh); - fclose(fh); - PrintAndLog("Saved data to '%s'", fileName); + fwrite(data, 1, datalen, fileHandle); + fclose(fileHandle); + PrintAndLog(">Saved data to '%s'", fileName); + free(fileName); return 0; } -int loadFile(const char *fileName, void* data, size_t datalen) -{ - FILE *filehandle = fopen(fileName, "rb"); - if(!filehandle) { - PrintAndLog("Failed to read from file '%s'", fileName); - free(filehandle); - return 1; - } - fread(data,datalen,1,filehandle); - fclose(filehandle); - free(filehandle); - return 0; -} /** * Utility function to print to console. This is used consistently within the library instead * of printf, but it actually only calls printf (and adds a linebreak). @@ -113,11 +63,11 @@ int loadFile(const char *fileName, void* data, size_t datalen) */ void prnlog(char *fmt, ...) { - + char buffer[2048] = {0}; va_list args; va_start(args,fmt); - PrintAndLog(fmt, args); - //vprintf(fmt,args); + vsprintf (buffer,fmt, args); va_end(args); - //printf("\n"); + PrintAndLog(buffer); + } diff --git a/client/loclass/fileutils.h b/client/loclass/fileutils.h index 405c9704..e02079d5 100644 --- a/client/loclass/fileutils.h +++ b/client/loclass/fileutils.h @@ -1,41 +1,3 @@ -/***************************************************************************** - * WARNING - * - * THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. - * - * USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL - * PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, - * AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. - * - * THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. - * - ***************************************************************************** - * - * This file is part of loclass. It is a reconstructon of the cipher engine - * used in iClass, and RFID techology. - * - * The implementation is based on the work performed by - * Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and - * Milosch Meriac in the paper "Dismantling IClass". - * - * Copyright (C) 2014 Martin Holst Swende - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with loclass. If not, see . - * - * - * - ****************************************************************************/ - #ifndef FILEUTILS_H #define FILEUTILS_H /** @@ -49,16 +11,7 @@ * @return 0 for ok, 1 for failz */ int saveFile(const char *preferredName, const char *suffix, const void* data, size_t datalen); -/** - * @brief Utility function to save load binary data from a a file. This method takes a filename, - * Should only be used for fixed-size binary files - * @param fileName the name of the file - * @param data a buffer to place data in - * @param datalen the length of the data/data. - * @return - */ -int loadFile(const char *fileName, void* data, size_t datalen); /** * Utility function to print to console. This is used consistently within the library instead @@ -68,4 +21,5 @@ int loadFile(const char *fileName, void* data, size_t datalen); * @param fmt */ void prnlog(char *fmt, ...); +int fileExists(const char *filename); #endif // FILEUTILS_H diff --git a/client/loclass/hash1_brute.c b/client/loclass/hash1_brute.c deleted file mode 100644 index a9fe0d19..00000000 --- a/client/loclass/hash1_brute.c +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include "cipherutils.h" -#include -#include -#include -#include -#include -#include "elite_crack.h" - -void calc_score(uint8_t* csn, uint8_t* k) -{ - uint8_t score =0 ; - uint8_t i; - uint8_t goodvals[16] = {0}; - uint8_t uniq_vals[8] = {0}; - memset(goodvals, 0x00, 16); - memset(uniq_vals, 0x00, 8); - uint8_t badval = 0; - int badscore =0; - for(i=0; i < 8 ; i++) - { - if(k[i] == 0x01) continue; - if(k[i] == 0x00) continue; - if(k[i] == 0x45) continue; - if(k[i] < 16){ - goodvals[k[i]] = 1; - } -// if(k[i] ==9 || k[i]==2){ -// goodvals[k[i]] = 1; -// } - - else if(k[i]>=16){ - badscore++; - badval = k[i]; - } - } - for(i =0; i < 16; i++) - { - if(goodvals[i]) - { - uniq_vals[score] = i; - score +=1; - } - } - if(score >=2 && badscore < 2) - { - printf("CSN\t%02x%02x%02x%02x%02x%02x%02x%02x\t%02x %02x %02x %02x %02x %02x %02x %02x\t" - ,csn[0],csn[1],csn[2],csn[3],csn[4],csn[5],csn[6],csn[7] - ,k[0],k[1],k[2],k[3],k[4],k[5],k[6],k[7] - ); - for(i =0 ; i < score; i++) - { - printf("%d,", uniq_vals[i]); - } - printf("\tbadscore: %d (%02x)", badscore, badval); - printf("\r\n"); - - } - -} - -void brute_hash1(){ - uint8_t csn[8] = {0,0,0,0,0xf7,0xff,0x12,0xe0}; - uint8_t k[8]= {0,0,0,0,0,0,0,0}; - uint16_t a,b,c,d; - uint8_t testcsn[8] ={0x00,0x0d,0x0f,0xfd,0xf7,0xff,0x12,0xe0} ; - uint8_t testkey[8] ={0x05 ,0x01 ,0x00 ,0x10 ,0x45 ,0x08 ,0x45,0x56} ; - calc_score(testcsn,testkey); - printf("Brute forcing hashones\n"); - //exit(1); - for(a=0;a < 256;a++) - { - //if(a > 0)printf("%d/256 done...\n", a); - for(b=0;b < 256 ; b++) - for(c=0;c < 256;c++) - for(d=0;d < 256;d++) - { - csn[0] = a; - csn[1] = b; - csn[2] = c; - csn[3] = d; - csn[4] = 0xf7; - csn[5] = 0xff; - csn[6] = 0x12; - csn[7] = 0xe0; - hash1(csn, k); - calc_score(csn,k); - } - } - -} - diff --git a/client/loclass/hash1_brute.h b/client/loclass/hash1_brute.h deleted file mode 100644 index b26ad96d..00000000 --- a/client/loclass/hash1_brute.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef HASH1_BRUTE_H -#define HASH1_BRUTE_H -void brute_hash1(); - -#endif // HASH1_BRUTE_H diff --git a/client/loclass/ikeys.c b/client/loclass/ikeys.c index fccd71d8..4749181e 100644 --- a/client/loclass/ikeys.c +++ b/client/loclass/ikeys.c @@ -1,17 +1,5 @@ /***************************************************************************** - * WARNING - * - * THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. - * - * USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL - * PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, - * AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. - * - * THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. - * - ***************************************************************************** - * - * This file is part of loclass. It is a reconstructon of the cipher engine + * This file is part of iClassCipher. It is a reconstructon of the cipher engine * used in iClass, and RFID techology. * * The implementation is based on the work performed by @@ -737,6 +725,7 @@ int doTestsWithKnownInputs() int readKeyFile(uint8_t key[8]) { + FILE *f; int retval = 1; f = fopen("iclass_key.bin", "rb"); @@ -749,6 +738,7 @@ int readKeyFile(uint8_t key[8]) fclose(f); } return retval; + } diff --git a/client/loclass/ikeys.h b/client/loclass/ikeys.h index 13096194..1de46b62 100644 --- a/client/loclass/ikeys.h +++ b/client/loclass/ikeys.h @@ -1,41 +1,3 @@ -/***************************************************************************** - * WARNING - * - * THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. - * - * USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL - * PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, - * AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. - * - * THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. - * - ***************************************************************************** - * - * This file is part of loclass. It is a reconstructon of the cipher engine - * used in iClass, and RFID techology. - * - * The implementation is based on the work performed by - * Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and - * Milosch Meriac in the paper "Dismantling IClass". - * - * Copyright (C) 2014 Martin Holst Swende - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with loclass. If not, see . - * - * - * - ****************************************************************************/ - #ifndef IKEYS_H #define IKEYS_H diff --git a/client/loclass/main.c b/client/loclass/main.c index 50671a19..42019072 100644 --- a/client/loclass/main.c +++ b/client/loclass/main.c @@ -1,17 +1,5 @@ /***************************************************************************** - * WARNING - * - * THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. - * - * USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL - * PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, - * AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. - * - * THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. - * - ***************************************************************************** - * - * This file is part of loclass. It is a reconstructon of the cipher engine + * This file is part of iClassCipher. It is a reconstructon of the cipher engine * used in iClass, and RFID techology. * * The implementation is based on the work performed by @@ -30,13 +18,9 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with loclass. If not, see . - * - * - * + * along with IClassCipher. If not, see . ****************************************************************************/ - #include #include #include @@ -80,18 +64,7 @@ int main (int argc, char **argv) { prnlog("IClass Cipher version 1.2, Copyright (C) 2014 Martin Holst Swende\n"); prnlog("Comes with ABSOLUTELY NO WARRANTY"); - prnlog("Released as GPLv2\n"); - prnlog("WARNING"); - prnlog(""); - prnlog("THIS TOOL IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY. "); - prnlog(""); - prnlog("USAGE OF THIS TOOL IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL "); - prnlog("PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL, "); - prnlog("AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES. "); - prnlog(""); - prnlog("THIS TOOL SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS. "); - - + prnlog("This is free software, and you are welcome to use, abuse and repackage, please keep the credits\n"); char *fileName = NULL; int c; while ((c = getopt (argc, argv, "thf:")) != -1) diff --git a/client/lualibs/commands.lua b/client/lualibs/commands.lua index d2acb3be..aeba31a7 100644 --- a/client/lualibs/commands.lua +++ b/client/lualibs/commands.lua @@ -48,8 +48,8 @@ local _commands = { CMD_EM4X_READ_WORD = 0x0218, CMD_EM4X_WRITE_WORD = 0x0219, CMD_IO_DEMOD_FSK = 0x021A, - CMD_IO_CLONE_TAG = 0x021B, - CMD_EM410X_DEMOD = 0x021c, + CMD_IO_CLONE_TAG = 0x021B, + CMD_EM410X_DEMOD = 0x021C, --/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */ --// For the 13.56 MHz tags @@ -64,7 +64,6 @@ local _commands = { CMD_ISO_15693_COMMAND_DONE = 0x0314, CMD_ISO_15693_FIND_AFI = 0x0315, CMD_ISO_15693_DEBUG = 0x0316, - CMD_LF_SNOOP_RAW_ADC_SAMPLES = 0x0317, --// For Hitag2 transponders CMD_SNOOP_HITAG = 0x0370, @@ -81,13 +80,10 @@ local _commands = { CMD_READER_LEGIC_RF = 0x0388, CMD_WRITER_LEGIC_RF = 0x0389, CMD_EPA_PACE_COLLECT_NONCE = 0x038A, - --//CMD_EPA_ = 0x038B, CMD_SNOOP_ICLASS = 0x0392, CMD_SIMULATE_TAG_ICLASS = 0x0393, CMD_READER_ICLASS = 0x0394, - CMD_READER_ICLASS_REPLAY = 0x0395, - CMD_ICLASS_ISO14443A_WRITE = 0x0397, --// For measurements of the antenna tuning CMD_MEASURE_ANTENNA_TUNING = 0x0400, @@ -104,54 +100,30 @@ local _commands = { CMD_MIFARE_EML_MEMSET = 0x0602, CMD_MIFARE_EML_MEMGET = 0x0603, CMD_MIFARE_EML_CARDLOAD = 0x0604, - - --// magic chinese card commands - CMD_MIFARE_CSETBLOCK = 0x0605, - CMD_MIFARE_CGETBLOCK = 0x0606, - CMD_MIFARE_CIDENT = 0x0607, - + CMD_MIFARE_EML_CSETBLOCK = 0x0605, + CMD_MIFARE_EML_CGETBLOCK = 0x0606, + CMD_SIMULATE_MIFARE_CARD = 0x0610, CMD_READER_MIFARE = 0x0611, CMD_MIFARE_NESTED = 0x0612, CMD_MIFARE_READBL = 0x0620, - CMD_MIFAREU_READBL = 0x0720, - CMD_MIFARE_READSC = 0x0621, - CMD_MIFAREU_READCARD = 0x0721, - CMD_MIFARE_WRITEBL = 0x0622, - CMD_MIFAREU_WRITEBL = 0x0722, - CMD_MIFAREU_WRITEBL_COMPAT = 0x0723, - CMD_MIFARE_CHKKEYS = 0x0623, CMD_MIFARE_SNIFFER = 0x0630, - --//ultralightC - CMD_MIFAREUC_AUTH1 = 0x0724, - CMD_MIFAREUC_AUTH2 = 0x0725, - CMD_MIFAREUC_READCARD = 0x0726, - - --// mifare desfire - CMD_MIFARE_DESFIRE_READBL = 0x0728, - CMD_MIFARE_DESFIRE_WRITEBL = 0x0729, - CMD_MIFARE_DESFIRE_AUTH1 = 0x072a, - CMD_MIFARE_DESFIRE_AUTH2 = 0x072b, - CMD_MIFARE_DES_READER = 0x072c, - CMD_MIFARE_DESFIRE_INFO = 0x072d, - CMD_MIFARE_DESFIRE = 0x072e, - CMD_UNKNOWN = 0xFFFF, } local _reverse_lookup,k,v = {} - for k, v in pairs(_commands) do - _reverse_lookup[v] = k - end - _commands.tostring = function(command) +for k, v in pairs(_commands) do + _reverse_lookup[v] = k +end +_commands.tostring = function(command) if(type(command) == 'number') then return ("%s (%d)"):format(_reverse_lookup[command]or "ERROR UNDEFINED!", command) end @@ -213,6 +185,7 @@ function Command:getBytes() local cmd = self.cmd local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3 + return bin.pack("LLLLH",cmd, arg1, arg2, arg3,data); end return _commands \ No newline at end of file diff --git a/client/lualibs/default_toys.lua b/client/lualibs/default_toys.lua deleted file mode 100644 index abb56515..00000000 --- a/client/lualibs/default_toys.lua +++ /dev/null @@ -1,63 +0,0 @@ -local _names = { - --[[ - --]] - ["0400"]="BASH", - ["1600"]="BOOMER" , - ["1800"]="CAMO", - ["3000"]="CHOPCHOP" , - ["2000"]="CYNDER", - ["6400"]="JET-VAC", - ["6700"]="FLASHWING", - ["7000"]="TREE REX", - ["7100"]="LIGHTCORE SHROOMBOOM", - ["1C00"]="DARK SPYRO", - ["0600"]="DINORANG" , - ["1200"]="DOUBLE TROUBLE" , - ["1500"]="DRILLSERGEANT" , - ["1400"]="DROBOT", - ["0900"]="LIGHTCORE ERUPTOR" , - ["0B00"]="FLAMESLINGER" , - ["1F00"]="GHOST ROASTER", - ["0E00"]="GILL GRUNT" , - ["1D00"]="HEX", - ["0A00"]="IGNITOR", - ["0300"]="LIGHTNINGROD", - ["0700"]="LIGHTCORE PRISM BREAK", - ["1500"]="SLAMBAM", - ["0100"]="SONIC BOOM", - ["1000"]="SPYRO", - ["1A00"]="STEALTH ELF", - ["1B00"]="STUMP SMASH", - ["0800"]="SUNBURN", - ["0500"]="TERRAFIN", - ["1300"]="TRIGGER HAPPY", - ["1100"]="VOODOOD", - ["0200"]="WARNADO", - ["0D00"]="WHAM SHELL", - ["0000"]="WHIRLWIND", - ["1700"]="WRECKING BALL", - ["0C00"]="ZAP", - ["1900"]="ZOOK", - ["0300"]="DRAGON", - ["012D"]="ICE", - ["012E"]="PIRATE", - ["0130"]="PVPUNLOCK", - ["012F"]="UNDEAD", - ["0200"]="ANVIL" , - ["CB00"]="CROSSED SWORDS", - ["CC00"]="HOURGLASS", - ["CA00"]="REGENERATION", - ["C900"]="SECRET STASH", - ["CD00"]="SHIELD", - ["CF00"]="SPARX", - ["CE00"]="SPEED BOOTS", - ["0194"]="LEGENDARY BASH", - ["0430"]="LEGENDARY CHOPCHOP", - ["01A0"]="LEGENDARY SPYRO", - ["01A3"]="LEGENDARY TRIGGER HAPPY", - ["0202"]="PET GILL GRUNT", - ["020E"]="PET STEALTH ELF", - ["01F9"]="PET TERRAFIN", - ["0207"]="PET TRIGGER HAPPY", -} -return _names diff --git a/client/lualibs/html_dumplib.lua b/client/lualibs/html_dumplib.lua index a7890885..b8c7ccaa 100644 --- a/client/lualibs/html_dumplib.lua +++ b/client/lualibs/html_dumplib.lua @@ -47,18 +47,6 @@ local function save_HTML(javascript, filename) end -local function save_TEXT(data,filename) - -- Open the output file - local outfile = io.open(filename, "wb") - if outfile == nil then - return oops(string.format("Could not write to file %s",tostring(filename))) - end - - outfile:write(data) - io.close(outfile) - return filename -end - local function save_BIN(data, filename) -- Open the output file @@ -192,7 +180,5 @@ end return { convert_bin_to_html = convert_bin_to_html, convert_eml_to_html = convert_eml_to_html, - convert_eml_to_bin = convert_eml_to_bin, - SaveAsBinary = save_BIN, - SaveAsText = save_TEXT, + convert_eml_to_bin = convert_eml_to_bin, } diff --git a/client/lualibs/htmlskel.lua b/client/lualibs/htmlskel.lua index b468eb2d..a52abdef 100644 --- a/client/lualibs/htmlskel.lua +++ b/client/lualibs/htmlskel.lua @@ -55,7 +55,6 @@ local skel_1 = [[ return "UNKNOWN" } - add("04,,,Mifare TNP3xxx Activision 1K,0f01,01"); add("04,,,Mifare Mini,0004,09"); add("04,,,Mifare Classic 1k/Mifare Plus(4 byte UID) 2K SL1,0004,08"); add("04,,,Mifare Plus (4 byte UID) 2K SL2,0004,10"); diff --git a/client/lualibs/md5.lua b/client/lualibs/md5.lua deleted file mode 100644 index 2390f957..00000000 --- a/client/lualibs/md5.lua +++ /dev/null @@ -1,384 +0,0 @@ -local md5 = { - _VERSION = "md5.lua 0.5.0", - _DESCRIPTION = "MD5 computation in Lua (5.1)", - _URL = "https://github.com/kikito/md5.lua", - _LICENSE = [[ - MIT LICENSE - - Copyright (c) 2013 Enrique García Cota + Adam Baldwin + hanzao + Equi 4 Software - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ]] -} - --- bit lib implementions - -local floor, abs, max = math.floor, math.abs, math.max -local char, byte, format, rep, sub = - string.char, string.byte, string.format, string.rep, string.sub - -local function check_int(n) - -- checking not float - if(n - floor(n) > 0) then - error("trying to use bitwise operation on non-integer!") - end -end - -local function tbl2number(tbl) - local n = #tbl - - local rslt = 0 - local power = 1 - for i = 1, n do - rslt = rslt + tbl[i]*power - power = power*2 - end - - return rslt -end - -local function expand(tbl_m, tbl_n) - local big = {} - local small = {} - if(#tbl_m > #tbl_n) then - big = tbl_m - small = tbl_n - else - big = tbl_n - small = tbl_m - end - -- expand small - for i = #small + 1, #big do - small[i] = 0 - end - -end - -local to_bits -- needs to be declared before bit_not - -local function bit_not(n) - local tbl = to_bits(n) - local size = max(#tbl, 32) - for i = 1, size do - if(tbl[i] == 1) then - tbl[i] = 0 - else - tbl[i] = 1 - end - end - return tbl2number(tbl) -end - --- defined as local above -to_bits = function (n) - check_int(n) - if(n < 0) then - -- negative - return to_bits(bit_not(abs(n)) + 1) - end - -- to bits table - local tbl = {} - local cnt = 1 - while (n > 0) do - local last = math.fmod(n,2) - if(last == 1) then - tbl[cnt] = 1 - else - tbl[cnt] = 0 - end - n = (n-last)/2 - cnt = cnt + 1 - end - - return tbl -end - -local function bit_or(m, n) - local tbl_m = to_bits(m) - local tbl_n = to_bits(n) - expand(tbl_m, tbl_n) - - local tbl = {} - local rslt = max(#tbl_m, #tbl_n) - for i = 1, rslt do - if(tbl_m[i]== 0 and tbl_n[i] == 0) then - tbl[i] = 0 - else - tbl[i] = 1 - end - end - - return tbl2number(tbl) -end - -local function bit_and(m, n) - local tbl_m = to_bits(m) - local tbl_n = to_bits(n) - expand(tbl_m, tbl_n) - - local tbl = {} - local rslt = max(#tbl_m, #tbl_n) - for i = 1, rslt do - if(tbl_m[i]== 0 or tbl_n[i] == 0) then - tbl[i] = 0 - else - tbl[i] = 1 - end - end - - return tbl2number(tbl) -end - -local function bit_xor(m, n) - local tbl_m = to_bits(m) - local tbl_n = to_bits(n) - expand(tbl_m, tbl_n) - - local tbl = {} - local rslt = max(#tbl_m, #tbl_n) - for i = 1, rslt do - if(tbl_m[i] ~= tbl_n[i]) then - tbl[i] = 1 - else - tbl[i] = 0 - end - end - - return tbl2number(tbl) -end - -local function bit_rshift(n, bits) - check_int(n) - - local high_bit = 0 - if(n < 0) then - -- negative - n = bit_not(abs(n)) + 1 - high_bit = 2147483648 -- 0x80000000 - end - - for i=1, bits do - n = n/2 - n = bit_or(floor(n), high_bit) - end - return floor(n) -end - -local function bit_lshift(n, bits) - check_int(n) - - if(n < 0) then - -- negative - n = bit_not(abs(n)) + 1 - end - - for i=1, bits do - n = n*2 - end - return bit_and(n, 4294967295) -- 0xFFFFFFFF -end - --- convert little-endian 32-bit int to a 4-char string -local function lei2str(i) - local f=function (s) return char( bit_and( bit_rshift(i, s), 255)) end - return f(0)..f(8)..f(16)..f(24) -end - --- convert raw string to big-endian int -local function str2bei(s) - local v=0 - for i=1, #s do - v = v * 256 + byte(s, i) - end - return v -end - --- convert raw string to little-endian int -local function str2lei(s) - local v=0 - for i = #s,1,-1 do - v = v*256 + byte(s, i) - end - return v -end - --- cut up a string in little-endian ints of given size -local function cut_le_str(s,...) - local o, r = 1, {} - local args = {...} - for i=1, #args do - table.insert(r, str2lei(sub(s, o, o + args[i] - 1))) - o = o + args[i] - end - return r -end - -local swap = function (w) return str2bei(lei2str(w)) end - -local function hex2binaryaux(hexval) - return char(tonumber(hexval, 16)) -end - -local function hex2binary(hex) - local result, _ = hex:gsub('..', hex2binaryaux) - return result -end - --- An MD5 mplementation in Lua, requires bitlib (hacked to use LuaBit from above, ugh) --- 10/02/2001 jcw@equi4.com - -local FF = 0xffffffff -local CONSTS = { - 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, - 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, - 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, - 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, - 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, - 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, - 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, - 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, - 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, - 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, - 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, - 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, - 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, - 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, - 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, - 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, - 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 -} - -local f=function (x,y,z) return bit_or(bit_and(x,y),bit_and(-x-1,z)) end -local g=function (x,y,z) return bit_or(bit_and(x,z),bit_and(y,-z-1)) end -local h=function (x,y,z) return bit_xor(x,bit_xor(y,z)) end -local i=function (x,y,z) return bit_xor(y,bit_or(x,-z-1)) end -local z=function (f,a,b,c,d,x,s,ac) - a=bit_and(a+f(b,c,d)+x+ac,FF) - -- be *very* careful that left shift does not cause rounding! - return bit_or(bit_lshift(bit_and(a,bit_rshift(FF,s)),s),bit_rshift(a,32-s))+b -end - -local function transform(A,B,C,D,X) - local a,b,c,d=A,B,C,D - local t=CONSTS - - a=z(f,a,b,c,d,X[ 0], 7,t[ 1]) - d=z(f,d,a,b,c,X[ 1],12,t[ 2]) - c=z(f,c,d,a,b,X[ 2],17,t[ 3]) - b=z(f,b,c,d,a,X[ 3],22,t[ 4]) - a=z(f,a,b,c,d,X[ 4], 7,t[ 5]) - d=z(f,d,a,b,c,X[ 5],12,t[ 6]) - c=z(f,c,d,a,b,X[ 6],17,t[ 7]) - b=z(f,b,c,d,a,X[ 7],22,t[ 8]) - a=z(f,a,b,c,d,X[ 8], 7,t[ 9]) - d=z(f,d,a,b,c,X[ 9],12,t[10]) - c=z(f,c,d,a,b,X[10],17,t[11]) - b=z(f,b,c,d,a,X[11],22,t[12]) - a=z(f,a,b,c,d,X[12], 7,t[13]) - d=z(f,d,a,b,c,X[13],12,t[14]) - c=z(f,c,d,a,b,X[14],17,t[15]) - b=z(f,b,c,d,a,X[15],22,t[16]) - - a=z(g,a,b,c,d,X[ 1], 5,t[17]) - d=z(g,d,a,b,c,X[ 6], 9,t[18]) - c=z(g,c,d,a,b,X[11],14,t[19]) - b=z(g,b,c,d,a,X[ 0],20,t[20]) - a=z(g,a,b,c,d,X[ 5], 5,t[21]) - d=z(g,d,a,b,c,X[10], 9,t[22]) - c=z(g,c,d,a,b,X[15],14,t[23]) - b=z(g,b,c,d,a,X[ 4],20,t[24]) - a=z(g,a,b,c,d,X[ 9], 5,t[25]) - d=z(g,d,a,b,c,X[14], 9,t[26]) - c=z(g,c,d,a,b,X[ 3],14,t[27]) - b=z(g,b,c,d,a,X[ 8],20,t[28]) - a=z(g,a,b,c,d,X[13], 5,t[29]) - d=z(g,d,a,b,c,X[ 2], 9,t[30]) - c=z(g,c,d,a,b,X[ 7],14,t[31]) - b=z(g,b,c,d,a,X[12],20,t[32]) - - a=z(h,a,b,c,d,X[ 5], 4,t[33]) - d=z(h,d,a,b,c,X[ 8],11,t[34]) - c=z(h,c,d,a,b,X[11],16,t[35]) - b=z(h,b,c,d,a,X[14],23,t[36]) - a=z(h,a,b,c,d,X[ 1], 4,t[37]) - d=z(h,d,a,b,c,X[ 4],11,t[38]) - c=z(h,c,d,a,b,X[ 7],16,t[39]) - b=z(h,b,c,d,a,X[10],23,t[40]) - a=z(h,a,b,c,d,X[13], 4,t[41]) - d=z(h,d,a,b,c,X[ 0],11,t[42]) - c=z(h,c,d,a,b,X[ 3],16,t[43]) - b=z(h,b,c,d,a,X[ 6],23,t[44]) - a=z(h,a,b,c,d,X[ 9], 4,t[45]) - d=z(h,d,a,b,c,X[12],11,t[46]) - c=z(h,c,d,a,b,X[15],16,t[47]) - b=z(h,b,c,d,a,X[ 2],23,t[48]) - - a=z(i,a,b,c,d,X[ 0], 6,t[49]) - d=z(i,d,a,b,c,X[ 7],10,t[50]) - c=z(i,c,d,a,b,X[14],15,t[51]) - b=z(i,b,c,d,a,X[ 5],21,t[52]) - a=z(i,a,b,c,d,X[12], 6,t[53]) - d=z(i,d,a,b,c,X[ 3],10,t[54]) - c=z(i,c,d,a,b,X[10],15,t[55]) - b=z(i,b,c,d,a,X[ 1],21,t[56]) - a=z(i,a,b,c,d,X[ 8], 6,t[57]) - d=z(i,d,a,b,c,X[15],10,t[58]) - c=z(i,c,d,a,b,X[ 6],15,t[59]) - b=z(i,b,c,d,a,X[13],21,t[60]) - a=z(i,a,b,c,d,X[ 4], 6,t[61]) - d=z(i,d,a,b,c,X[11],10,t[62]) - c=z(i,c,d,a,b,X[ 2],15,t[63]) - b=z(i,b,c,d,a,X[ 9],21,t[64]) - - return A+a,B+b,C+c,D+d -end - ----------------------------------------------------------------- - -function md5.sumhexa(s) - local msgLen = #s - local padLen = 56 - msgLen % 64 - - if msgLen % 64 > 56 then padLen = padLen + 64 end - - if padLen == 0 then padLen = 64 end - - s = s .. char(128) .. rep(char(0),padLen-1) .. lei2str(8*msgLen) .. lei2str(0) - - assert(#s % 64 == 0) - - local t = CONSTS - local a,b,c,d = t[65],t[66],t[67],t[68] - - for i=1,#s,64 do - local X = cut_le_str(sub(s,i,i+63),4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4) - assert(#X == 16) - X[0] = table.remove(X,1) -- zero based! - a,b,c,d = transform(a,b,c,d,X) - end - - return format("%08x%08x%08x%08x",swap(a),swap(b),swap(c),swap(d)) -end - -function md5.sum(s) - return hex2binary(md5.sumhexa(s)) -end - -return md5 diff --git a/client/lualibs/mf_default_keys.lua b/client/lualibs/mf_default_keys.lua index 810f0d6e..4859ff0c 100644 --- a/client/lualibs/mf_default_keys.lua +++ b/client/lualibs/mf_default_keys.lua @@ -141,25 +141,7 @@ local _keys = { '200000000000', 'a00000000000', 'b00000000000', - - --[[ - Should be for Mifare TNP3xxx tags A KEY. - --]] - '4b0b20107ccb', - - --[[ - Kiev metro cards - --]] - '8fe644038790', - 'f14ee7cae863', - '632193be1c3c', - '569369c5a0e5', - '9de89e070277', - 'eff603e1efe9', - '644672bd4afe', - - 'b5ff67cba951', -} + } --- -- The keys above have just been pasted in, for completeness sake. They contain duplicates. diff --git a/client/lualibs/read14a.lua b/client/lualibs/read14a.lua index 10e7c2d4..24021a1d 100644 --- a/client/lualibs/read14a.lua +++ b/client/lualibs/read14a.lua @@ -25,7 +25,6 @@ local ISO14A_COMMAND = { local ISO14443a_TYPES = {} ISO14443a_TYPES[0x00] = "NXP MIFARE Ultralight | Ultralight C" -ISO14443a_TYPES[0x01] = "NXP MIFARE TNP3xxx Activision Game Appliance" ISO14443a_TYPES[0x04] = "NXP MIFARE (various !DESFire !DESFire EV1)" ISO14443a_TYPES[0x08] = "NXP MIFARE CLASSIC 1k | Plus 2k" ISO14443a_TYPES[0x09] = "NXP MIFARE Mini 0.3k" diff --git a/client/lualibs/utils.lua b/client/lualibs/utils.lua index 9b36dfc8..3d27d5b6 100644 --- a/client/lualibs/utils.lua +++ b/client/lualibs/utils.lua @@ -33,86 +33,9 @@ local Utils = return answer end, - - ------------ FILE READING - ReadDumpFile = function (filename) - - if filename == nil then - return nil, 'Filename is empty' - end - if #filename == 0 then - return nil, 'Filename length is zero' - end - - infile = io.open(filename, "rb") - if infile == nil then - return nil, string.format("Could not read file %s",filename) - end - local t = infile:read("*all") - len = string.len(t) - local _,hex = bin.unpack(("H%d"):format(len),t) - io.close(infile) - return hex - end, - - ------------ string split function - Split = function( inSplitPattern, outResults ) - if not outResults then - outResults = {} - end - local start = 1 - local splitStart, splitEnd = string.find( self, inSplitPattern, start ) - while splitStart do - table.insert( outResults, string.sub( self, start, splitStart-1 ) ) - start = splitEnd + 1 - splitStart, splitEnd = string.find( self, inSplitPattern, start ) - end - table.insert( outResults, string.sub( self, start ) ) - return outResults - end, - - ------------ CRC-16 ccitt checksums - - -- Takes a hex string and calculates a crc16 - Crc16 = function(s) - if s == nil then return nil end - if #s == 0 then return nil end - if type(s) == 'string' then - local utils = require('utils') - local asc = utils.ConvertHexToAscii(s) - local hash = core.crc16(asc) - return hash - end - return nil - end, - - -- input parameter is a string - -- Swaps the endianess and returns a number, - -- IE: 'cd7a' -> '7acd' -> 0x7acd - SwapEndianness = function(s, len) - if s == nil then return nil end - if #s == 0 then return '' end - if type(s) ~= 'string' then return nil end - - local retval = 0 - if len == 16 then - local t = s:sub(3,4)..s:sub(1,2) - retval = tonumber(t,16) - elseif len == 24 then - local t = s:sub(5,6)..s:sub(3,4)..s:sub(1,2) - retval = tonumber(t,16) - elseif len == 32 then - local t = s:sub(7,8)..s:sub(5,6)..s:sub(3,4)..s:sub(1,2) - retval = tonumber(t,16) - end - return retval - end, - - ------------ CONVERSIONS - -- -- Converts DECIMAL to HEX - ConvertDecToHex = function(IN) + ConvertDec2Hex = function(IN) local B,K,OUT,I,D=16,"0123456789ABCDEF","",0 while IN>0 do I=I+1 @@ -123,100 +46,12 @@ local Utils = end, --- -- Convert Byte array to string of hex - ConvertBytesToHex = function(bytes) - if #bytes == 0 then - return '' - end - local s={} + ConvertBytes2String = function(bytes) + s = {} for i = 1, #(bytes) do - s[i] = string.format("%02X",bytes[i]) + s[i] = string.format("%02X",bytes[i]) end return table.concat(s) end, - -- Convert byte array to string with ascii - ConvertBytesToAscii = function(bytes) - if #bytes == 0 then - return '' - end - local s={} - for i = 1, #(bytes) do - s[i] = string.char(bytes[i]) - end - return table.concat(s) - end, - ConvertHexToBytes = function(s) - local t={} - if s == nil then return t end - if #s == 0 then return t end - for k in s:gmatch"(%x%x)" do - table.insert(t,tonumber(k,16)) - end - return t - end, - ConvertAsciiToBytes = function(s) - local t={} - if s == nil then return t end - if #s == 0 then return t end - - for k in s:gmatch"(.)" do - table.insert(t, string.byte(k)) - end - return t - end, - ConvertHexToAscii = function(s) - local t={} - if s == nil then return t end - if #s == 0 then return t end - for k in s:gmatch"(%x%x)" do - table.insert(t, string.char(tonumber(k,16))) - end - return table.concat(t) - end, - - -- function convertStringToBytes(str) - -- local bytes = {} - -- local strLength = string.len(str) - -- for i=1,strLength do - -- table.insert(bytes, string.byte(str, i)) - -- end - - -- return bytes --- end - --- function convertBytesToString(bytes) - -- local bytesLength = table.getn(bytes) - -- local str = "" - -- for i=1,bytesLength do - -- str = str .. string.char(bytes[i]) - -- end - - -- return str --- end - --- function convertHexStringToBytes(str) - -- local bytes = {} - -- local strLength = string.len(str) - -- for k=2,strLength,2 do - -- local hexString = "0x" .. string.sub(str, (k - 1), k) - -- table.insert(bytes, hex.to_dec(hexString)) - -- end - - -- return bytes --- end - --- function convertBytesToHexString(bytes) - -- local str = "" - -- local bytesLength = table.getn(bytes) - -- for i=1,bytesLength do - -- local hexString = string.sub(hex.to_hex(bytes[i]), 3) - -- if string.len(hexString) == 1 then - -- hexString = "0" .. hexString - -- end - -- str = str .. hexString - -- end - - -- return str --- end - } return Utils \ No newline at end of file diff --git a/client/mifarehost.c b/client/mifarehost.c index 3516fca4..d025918d 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -72,7 +72,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo uint16_t i, len; uint32_t uid; UsbCommand resp; - + StateList_t statelists[2]; struct Crypto1State *p1, *p2, *p3, *p4; @@ -216,7 +216,7 @@ int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) { UsbCommand c = {CMD_MIFARE_EML_MEMGET, {blockNum, blocksCount, 0}}; SendCommand(&c); - UsbCommand resp; + UsbCommand resp; if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) return 1; memcpy(data, resp.d.asBytes, blocksCount * 16); return 0; @@ -250,7 +250,7 @@ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uin memcpy(c.d.asBytes, data, 16); SendCommand(&c); - UsbCommand resp; + UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { isOK = resp.arg[0] & 0xff; if (uid != NULL) memcpy(uid, resp.d.asBytes, 4); @@ -339,10 +339,10 @@ int loadTraceCard(uint8_t *tuid) { while(!feof(f)){ memset(buf, 0, sizeof(buf)); if (fgets(buf, sizeof(buf), f) == NULL) { - PrintAndLog("File reading error."); + PrintAndLog("File reading error."); fclose(f); return 2; - } + } if (strlen(buf) < 32){ if (feof(f)) break; @@ -440,7 +440,7 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) { } // AUTHENTICATION - if ((len == 4) && ((data[0] == 0x60) || (data[0] == 0x61))) { + if ((len ==4) && ((data[0] == 0x60) || (data[0] == 0x61))) { traceState = TRACE_AUTH1; traceCurBlock = data[1]; traceCurKey = data[0] == 60 ? 1:0; diff --git a/client/nonce2key/crapto1.c b/client/nonce2key/crapto1.c index c2dd7a54..61215420 100644 --- a/client/nonce2key/crapto1.c +++ b/client/nonce2key/crapto1.c @@ -545,10 +545,11 @@ lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], statelist = malloc((sizeof *statelist) << 21); //how large should be? if(!statelist || !odd || !even) { - free(statelist); - free(odd); - free(even); - return 0; + free(statelist); + free(odd); + free(even); + return 0; + } s = statelist; diff --git a/client/proxguiqt.cpp b/client/proxguiqt.cpp index 3e9bdfd5..a820fe41 100644 --- a/client/proxguiqt.cpp +++ b/client/proxguiqt.cpp @@ -280,7 +280,7 @@ void ProxWidget::paintEvent(QPaintEvent *event) ProxWidget::ProxWidget(QWidget *parent) : QWidget(parent), GraphStart(0), GraphPixelsPerPoint(1) { - resize(600, 300); + resize(600, 500); QPalette palette(QColor(0,0,0,0)); palette.setColor(QPalette::WindowText, QColor(255,255,255)); diff --git a/client/proxmark3.c b/client/proxmark3.c index 4b463f1d..16a8fa02 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -47,7 +47,7 @@ void SendCommand(UsbCommand *c) { PrintAndLog("Sending bytes to proxmark failed - offline"); return; } - /** + /** The while-loop below causes hangups at times, when the pm3 unit is unresponsive or disconnected. The main console thread is alive, but comm thread just spins here. Not good.../holiman diff --git a/client/proxmark3.h b/client/proxmark3.h index a634fd68..8236bfe7 100644 --- a/client/proxmark3.h +++ b/client/proxmark3.h @@ -20,7 +20,7 @@ #include "usb_cmd.h" -#define PROXPROMPT "pm3 --> " +#define PROXPROMPT "proxmark3> " void SendCommand(UsbCommand *c); diff --git a/client/scripting.c b/client/scripting.c index cc59f995..963bb64c 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -18,8 +18,6 @@ #include "util.h" #include "nonce2key/nonce2key.h" #include "../common/iso15693tools.h" -#include -#include "../common/crc16.h" /** * The following params expected: * UsbCommand c @@ -226,54 +224,6 @@ static int l_iso15693_crc(lua_State *L) return 1; } -/* - Simple AES 128 cbc hook up to OpenSSL. - params: key, input -*/ -static int l_aes(lua_State *L) -{ - //Check number of arguments - int i; - size_t size; - const char *p_key = luaL_checklstring(L, 1, &size); - if(size != 32) return returnToLuaWithError(L,"Wrong size of key, got %d bytes, expected 32", (int) size); - - const char *p_encTxt = luaL_checklstring(L, 2, &size); - - unsigned char indata[AES_BLOCK_SIZE] = {0x00}; - unsigned char outdata[AES_BLOCK_SIZE] = {0x00}; - unsigned char aes_key[AES_BLOCK_SIZE] = {0x00}; - unsigned char iv[AES_BLOCK_SIZE] = {0x00}; - - // convert key to bytearray - for (i = 0; i < 32; i += 2) { - sscanf(&p_encTxt[i], "%02x", (unsigned int *)&indata[i / 2]); - } - - // convert input to bytearray - for (i = 0; i < 32; i += 2) { - sscanf(&p_key[i], "%02x", (unsigned int *)&aes_key[i / 2]); - } - - AES_KEY key; - AES_set_decrypt_key(aes_key, 128, &key); - AES_cbc_encrypt(indata, outdata, sizeof(indata), &key, iv, AES_DECRYPT); - - //Push decrypted array as a string - lua_pushlstring(L,(const char *)&outdata, sizeof(outdata)); - return 1;// return 1 to signal one return value -} - -static int l_crc16(lua_State *L) -{ - size_t size; - const char *p_str = luaL_checklstring(L, 1, &size); - - uint16_t retval = crc16_ccitt( (uint8_t*) p_str, size); - lua_pushinteger(L, (int) retval); - return 1; -} - /** * @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be * able to do "require('foobar')" if foobar.lua is within lualibs folder. @@ -309,10 +259,8 @@ int set_pm3_libraries(lua_State *L) {"foobar", l_foobar}, {"ukbhit", l_ukbhit}, {"clearCommandBuffer", l_clearCommandBuffer}, - {"console", l_CmdConsole}, - {"iso15693_crc", l_iso15693_crc}, - {"aes", l_aes}, - {"crc16", l_crc16}, + {"console", l_CmdConsole}, + {"iso15693_crc", l_iso15693_crc}, {NULL, NULL} }; diff --git a/client/scripts/formatMifare.lua b/client/scripts/formatMifare.lua index 66a61fba..1ced0c28 100644 --- a/client/scripts/formatMifare.lua +++ b/client/scripts/formatMifare.lua @@ -80,20 +80,18 @@ function GetCardInfo() core.clearCommandBuffer() - if 0x18 == result.sak then -- NXP MIFARE Classic 4k | Plus 4k + if 0x18 == result.sak then --NXP MIFARE Classic 4k | Plus 4k -- IFARE Classic 4K offers 4096 bytes split into forty sectors, -- of which 32 are same size as in the 1K with eight more that are quadruple size sectors. numSectors = 40 - elseif 0x08 == result.sak then -- NXP MIFARE CLASSIC 1k | Plus 2k + elseif 0x08 == result.sak then -- NXP MIFARE CLASSIC 1k | Plus 2k -- 1K offers 1024 bytes of data storage, split into 16 sector numSectors = 16 - elseif 0x09 == result.sak then -- NXP MIFARE Mini 0.3k + elseif 0x09 == result.sak then -- NXP MIFARE Mini 0.3k -- MIFARE Classic mini offers 320 bytes split into five sectors. numSectors = 5 - elseif 0x10 == result.sak then -- NXP MIFARE Plus 2k + elseif 0x10 == result.sak then-- "NXP MIFARE Plus 2k" numSectors = 32 - elseif 0x01 == sak then -- NXP MIFARE TNP3xxx 1K - numSectors = 16 else print("I don't know how many sectors there are on this type of card, defaulting to 16") end diff --git a/client/scripts/mifare_autopwn.lua b/client/scripts/mifare_autopwn.lua index eb98ffbf..8d0d358f 100644 --- a/client/scripts/mifare_autopwn.lua +++ b/client/scripts/mifare_autopwn.lua @@ -133,8 +133,6 @@ function nested(key,sak) typ = 0 elseif 0x10 == sak then-- "NXP MIFARE Plus 2k" typ = 2 - elseif 0x01 == sak then-- "NXP MIFARE TNP3xxx 1K" - typ = 1 else print("I don't know how many sectors there are on this type of card, defaulting to 16") end diff --git a/client/scripts/tnp3dump.lua b/client/scripts/tnp3dump.lua deleted file mode 100644 index 520161b9..00000000 --- a/client/scripts/tnp3dump.lua +++ /dev/null @@ -1,272 +0,0 @@ -local cmds = require('commands') -local getopt = require('getopt') -local bin = require('bin') -local lib14a = require('read14a') -local utils = require('utils') -local md5 = require('md5') -local dumplib = require('html_dumplib') -local toyNames = require('default_toys') - -example =[[ - 1. script run tnp3dump - 2. script run tnp3dump -n - 3. script run tnp3dump -k aabbccddeeff - 4. script run tnp3dump -k aabbccddeeff -n - 5. script run tnp3dump -o myfile - 6. script run tnp3dump -n -o myfile - 7. script run tnp3dump -k aabbccddeeff -n -o myfile -]] -author = "Iceman" -usage = "script run tnp3dump -k -n -o " -desc =[[ -This script will try to dump the contents of a Mifare TNP3xxx card. -It will need a valid KeyA in order to find the other keys and decode the card. -Arguments: - -h : this help - -k : Sector 0 Key A. - -n : Use the nested cmd to find all keys - -o : filename for the saved dumps -]] - -local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20' - -local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds -local DEBUG = false -- the debug flag -local numBlocks = 64 -local numSectors = 16 ---- --- A debug printout-function -function dbg(args) - if not DEBUG then - return - end - - if type(args) == "table" then - local i = 1 - while result[i] do - dbg(result[i]) - i = i+1 - end - else - print("###", args) - end -end ---- --- This is only meant to be used when errors occur -function oops(err) - print("ERROR: ",err) -end ---- --- Usage help -function help() - print(desc) - print("Example usage") - print(example) -end --- --- Exit message -function ExitMsg(msg) - print( string.rep('--',20) ) - print( string.rep('--',20) ) - print(msg) - print() -end - -local function readdumpkeys(infile) - t = infile:read("*all") - len = string.len(t) - local len,hex = bin.unpack(("H%d"):format(len),t) - return hex -end - -local function waitCmd() - local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) - if response then - local count,cmd,arg0 = bin.unpack('LL',response) - if(arg0==1) then - local count,arg1,arg2,data = bin.unpack('LLH511',response,count) - return data:sub(1,32) - else - return nil, "Couldn't read block.." - end - end - return nil, "No response from device" -end - -local function computeCrc16(s) - local hash = core.crc16(utils.ConvertHexToAscii(s)) - return hash -end - -local function reverseCrcBytes(crc) - crc2 = crc:sub(3,4)..crc:sub(1,2) - return tonumber(crc2,16) -end - -local function main(args) - - print( string.rep('--',20) ) - print( string.rep('--',20) ) - - local keyA - local cmd - local err - local useNested = false - local cmdReadBlockString = 'hf mf rdbl %d A %s' - local input = "dumpkeys.bin" - local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M%S"); - - -- Arguments for the script - for o, a in getopt.getopt(args, 'hk:no:') do - if o == "h" then return help() end - if o == "k" then keyA = a end - if o == "n" then useNested = true end - if o == "o" then outputTemplate = a end - end - - -- validate input args. - keyA = keyA or '4b0b20107ccb' - if #(keyA) ~= 12 then - return oops( string.format('Wrong length of write key (was %d) expected 12', #keyA)) - end - - -- Turn off Debug - local cmdSetDbgOff = "hf mf dbg 0" - core.console( cmdSetDbgOff) - - result, err = lib14a.read1443a(false) - if not result then - return oops(err) - end - - core.clearCommandBuffer() - - if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx - return oops('This is not a TNP3xxx tag. aborting.') - end - - -- Show tag info - print((' Found tag : %s'):format(result.name)) - print(('Using keyA : %s'):format(keyA)) - - --Trying to find the other keys - if useNested then - core.console( ('hf mf nested 1 0 A %s d'):format(keyA) ) - end - - core.clearCommandBuffer() - - -- Loading keyfile - print('Loading dumpkeys.bin') - local hex, err = utils.ReadDumpFile(input) - if not hex then - return oops(err) - end - - local akeys = hex:sub(0,12*16) - - -- Read block 0 - cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0,arg2 = 0,arg3 = 0, data = keyA} - err = core.SendCommand(cmd:getBytes()) - if err then return oops(err) end - local block0, err = waitCmd() - if err then return oops(err) end - - -- Read block 1 - cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 1,arg2 = 0,arg3 = 0, data = keyA} - err = core.SendCommand(cmd:getBytes()) - if err then return oops(err) end - local block1, err = waitCmd() - if err then return oops(err) end - - local key - local pos = 0 - local blockNo - local blocks = {} - - print('Reading card data') - core.clearCommandBuffer() - - -- main loop - io.write('Decrypting blocks > ') - for blockNo = 0, numBlocks-1, 1 do - - if core.ukbhit() then - print("aborted by user") - break - end - - pos = (math.floor( blockNo / 4 ) * 12)+1 - key = akeys:sub(pos, pos + 11 ) - cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blockNo ,arg2 = 0,arg3 = 0, data = key} - local err = core.SendCommand(cmd:getBytes()) - if err then return oops(err) end - local blockdata, err = waitCmd() - if err then return oops(err) end - - if blockNo%4 ~= 3 then - if blockNo < 8 then - -- Block 0-7 not encrypted - blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata) - else - local base = ('%s%s%02x%s'):format(block0, block1, blockNo, HASHCONSTANT) - local baseStr = utils.ConvertHexToAscii(base) - local md5hash = md5.sumhexa(baseStr) - local aestest = core.aes(md5hash, blockdata) - - local hex = utils.ConvertAsciiToBytes(aestest) - hex = utils.ConvertBytesToHex(hex) - - -- blocks with zero not encrypted. - if string.find(blockdata, '^0+$') then - blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata) - else - blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,hex) - io.write( blockNo..',') - end - end - else - -- Sectorblocks, not encrypted - blocks[blockNo+1] = ('%02d :: %s%s'):format(blockNo,key,blockdata:sub(13,32)) - end - end - io.write('\n') - - core.clearCommandBuffer() - - -- Print results - local bindata = {} - local emldata = '' - - for _,s in pairs(blocks) do - local slice = s:sub(8,#s) - local str = utils.ConvertBytesToAscii( - utils.ConvertHexToBytes(slice) - ) - emldata = emldata..slice..'\n' - for c in (str):gmatch('.') do - bindata[#bindata+1] = c - end - end - - -- Write dump to files - if not DEBUG then - local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'.bin') - print(("Wrote a BIN dump to the file %s"):format(foo)) - local bar = dumplib.SaveAsText(emldata, outputTemplate..'.eml') - print(("Wrote a EML dump to the file %s"):format(bar)) - end - - local uid = block0:sub(1,8) - local itemtype = block1:sub(1,4) - local cardid = block1:sub(9,24) - - -- Show info - print( string.rep('--',20) ) - print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) ) - print( (' UID : 0x%s'):format(uid) ) - print( (' CARDID : 0x%s'):format(cardid ) ) - print( string.rep('--',20) ) - -end -main(args) \ No newline at end of file diff --git a/client/scripts/tnp3sim.lua b/client/scripts/tnp3sim.lua deleted file mode 100644 index f43dafa2..00000000 --- a/client/scripts/tnp3sim.lua +++ /dev/null @@ -1,355 +0,0 @@ -local cmds = require('commands') -local getopt = require('getopt') -local bin = require('bin') -local lib14a = require('read14a') -local utils = require('utils') -local md5 = require('md5') -local toyNames = require('default_toys') - -example =[[ - 1. script run tnp3sim - 2. script run tnp3sim -m - 3. script run tnp3sim -m -i myfile -]] -author = "Iceman" -usage = "script run tnp3sim -h -m -i " -desc =[[ -This script will try to load a binary datadump of a Mifare TNP3xxx card. -It vill try to validate all checksums and view some information stored in the dump -For an experimental mode, it tries to manipulate some data. -At last it sends all data to the PM3 device memory where it can be used in the command "hf mf sim" - -Arguments: - -h : this help - -m : Maxed out items (experimental) - -i : filename for the datadump to read (bin) -]] - -local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds -local DEBUG = true -- the debug flag ---- --- A debug printout-function -function dbg(args) - if not DEBUG then - return - end - - if type(args) == "table" then - local i = 1 - while result[i] do - dbg(result[i]) - i = i+1 - end - else - print("###", args) - end -end ---- --- This is only meant to be used when errors occur -function oops(err) - print("ERROR: ",err) -end ---- --- Usage help -function help() - print(desc) - print("Example usage") - print(example) -end --- --- Exit message -function ExitMsg(msg) - print( string.rep('--',20) ) - print( string.rep('--',20) ) - print(msg) - print() -end - - -local function writedumpfile(infile) - t = infile:read("*all") - len = string.len(t) - local len,hex = bin.unpack(("H%d"):format(len),t) - return hex -end --- blocks with data --- there are two dataareas, in block 8 or block 36, ( 1==8 , --- checksum type = 0, 1, 2, 3 -local function GetCheckSum(blocks, dataarea, chksumtype) - - local crc - local area = 36 - if dataarea == 1 then - area = 8 - end - - if chksumtype == 0 then - crc = blocks[1]:sub(29,32) - elseif chksumtype == 1 then - crc = blocks[area]:sub(29,32) - elseif chksumtype == 2 then - crc = blocks[area]:sub(25,28) - elseif chksumtype == 3 then - crc = blocks[area]:sub(21,24) - end - return utils.SwapEndianness(crc,16) -end - -local function SetCheckSum(blocks, chksumtype) - - if blocks == nil then return nil, 'Argument \"blocks\" nil' end - local newcrc - local area1 = 8 - local area2 = 36 - - if chksumtype == 0 then - newcrc = ('%04X'):format(CalcCheckSum(blocks,1,0)) - blocks[1] = blocks[1]:sub(1,28)..newcrc:sub(3,4)..newcrc:sub(1,2) - elseif chksumtype == 1 then - newcrc = ('%04X'):format(CalcCheckSum(blocks,1,1)) - blocks[area1] = blocks[area1]:sub(1,28)..newcrc:sub(3,4)..newcrc:sub(1,2) - newcrc = ('%04X'):format(CalcCheckSum(blocks,2,1)) - blocks[area2] = blocks[area2]:sub(1,28)..newcrc:sub(3,4)..newcrc:sub(1,2) - elseif chksumtype == 2 then - newcrc = ('%04X'):format(CalcCheckSum(blocks,1,2)) - blocks[area1] = blocks[area1]:sub(1,24)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area1]:sub(29,32) - newcrc = ('%04X'):format(CalcCheckSum(blocks,2,2)) - blocks[area2] = blocks[area2]:sub(1,24)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area2]:sub(29,32) - elseif chksumtype == 3 then - newcrc = ('%04X'):format(CalcCheckSum(blocks,1,3)) - blocks[area1] = blocks[area1]:sub(1,20)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area1]:sub(25,32) - newcrc = ('%04X'):format(CalcCheckSum(blocks,2,3)) - blocks[area2] = blocks[area2]:sub(1,20)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area2]:sub(25,32) - end -end - -function CalcCheckSum(blocks, dataarea, chksumtype) - local area = 36 - if dataarea == 1 then - area = 8 - end - - if chksumtype == 0 then - data = blocks[0]..blocks[1]:sub(1,28) - elseif chksumtype == 1 then - data = blocks[area]:sub(1,28)..'0500' - elseif chksumtype == 2 then - data = blocks[area+1]..blocks[area+2]..blocks[area+4] - elseif chksumtype == 3 then - data = blocks[area+5]..blocks[area+6]..blocks[area+8]..string.rep('00',0xe0) - end - return utils.Crc16(data) -end - -local function ValidateCheckSums(blocks) - - local isOk, crc, calc - -- Checksum Type 0 - crc = GetCheckSum(blocks,1,0) - calc = CalcCheckSum(blocks, 1, 0) - if crc == calc then isOk='Ok' else isOk = 'Error' end - io.write( ('TYPE 0 : %04x = %04x -- %s\n'):format(crc,calc,isOk)) - - -- Checksum Type 1 (DATAAREAHEADER 1) - crc = GetCheckSum(blocks,1,1) - calc = CalcCheckSum(blocks,1,1) - if crc == calc then isOk='Ok' else isOk = 'Error' end - io.write( ('TYPE 1 area 1: %04x = %04x -- %s\n'):format(crc,calc,isOk)) - - -- Checksum Type 1 (DATAAREAHEADER 2) - crc = GetCheckSum(blocks,2,1) - calc = CalcCheckSum(blocks,2,1) - if crc == calc then isOk='Ok' else isOk = 'Error' end - io.write( ('TYPE 1 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk)) - - -- Checksum Type 2 (DATAAREA 1) - crc = GetCheckSum(blocks,1,2) - calc = CalcCheckSum(blocks,1,2) - if crc == calc then isOk='Ok' else isOk = 'Error' end - io.write( ('TYPE 2 area 1: %04x = %04x -- %s\n'):format(crc,calc,isOk)) - - -- Checksum Type 2 (DATAAREA 2) - crc = GetCheckSum(blocks,2,2) - calc = CalcCheckSum(blocks,2,2) - if crc == calc then isOk='Ok' else isOk = 'Error' end - io.write( ('TYPE 2 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk)) - - -- Checksum Type 3 (DATAAREA 1) - crc = GetCheckSum(blocks,1,3) - calc = CalcCheckSum(blocks,1,3) - if crc == calc then isOk='Ok' else isOk = 'Error' end - io.write( ('TYPE 3 area 1: %04x = %04x -- %s\n'):format(crc,calc,isOk)) - - -- Checksum Type 3 (DATAAREA 2) - crc = GetCheckSum(blocks,2,3) - calc = CalcCheckSum(blocks,2,3) - if crc == calc then isOk='Ok' else isOk = 'Error' end - io.write( ('TYPE 3 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk)) -end - - -local function LoadEmulator(blocks) - local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20' - local cmd - local blockdata - for _,b in pairs(blocks) do - - blockdata = b - - if _%4 ~= 3 then - if (_ >= 8 and _<=21) or (_ >= 36 and _<=49) then - local base = ('%s%s%02x%s'):format(blocks[0], blocks[1], _ , HASHCONSTANT) - local baseStr = utils.ConvertHexToAscii(base) - local key = md5.sumhexa(baseStr) - local enc = core.aes(key, blockdata) - local hex = utils.ConvertAsciiToBytes(enc) - hex = utils.ConvertBytesToHex(hex) - - blockdata = hex - io.write( _..',') - end - end - - cmd = Command:new{cmd = cmds.CMD_MIFARE_EML_MEMSET, arg1 = _ ,arg2 = 1,arg3 = 0, data = blockdata} - local err = core.SendCommand(cmd:getBytes()) - if err then - return err - end - end - io.write('\n') -end - -local function main(args) - - print( string.rep('--',20) ) - print( string.rep('--',20) ) - - local result, err, hex - local maxed = false - local inputTemplate = "dumpdata.bin" - local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M"); - - -- Arguments for the script - for o, a in getopt.getopt(args, 'hmi:o:') do - if o == "h" then return help() end - if o == "m" then maxed = true end - if o == "o" then outputTemplate = a end - if o == "i" then inputTemplate = a end - end - - -- Turn off Debug - local cmdSetDbgOff = "hf mf dbg 0" - core.console( cmdSetDbgOff) - - -- Look for tag present on reader, - result, err = lib14a.read1443a(false) - if not result then return oops(err) end - - core.clearCommandBuffer() - - if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx - return oops('This is not a TNP3xxx tag. aborting.') - end - - -- Show tag info - print((' Found tag : %s'):format(result.name)) - - -- Load dump.bin file - print( (' Load data from %s'):format(inputTemplate)) - hex, err = utils.ReadDumpFile(inputTemplate) - if not hex then return oops(err) end - - local blocks = {} - local blockindex = 0 - for i = 1, #hex, 32 do - blocks[blockindex] = hex:sub(i,i+31) - blockindex = blockindex + 1 - end - - if DEBUG then - print('Validating checksums in the loaded datadump') - ValidateCheckSums(blocks) - end - - -- - print( string.rep('--',20) ) - print(' Gathering info') - local uid = blocks[0]:sub(1,8) - local itemtype = blocks[1]:sub(1,4) - local cardid = blocks[1]:sub(9,24) - - -- Show info - print( string.rep('--',20) ) - print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) ) - print( (' UID : 0x%s'):format(uid) ) - print( (' CARDID : 0x%s'):format(cardid ) ) - print( string.rep('--',20) ) - - -- lets do something. - -- - local experience = blocks[8]:sub(1,6) - print(('Experience : %d'):format(utils.SwapEndianness(experience,24))) - local money = blocks[8]:sub(7,10) - print(('Money : %d'):format(utils.SwapEndianness(money,16))) - local fairy = blocks[9]:sub(1,8) - --FD0F = Left, FF0F = Right - local path = 'not choosen' - if fairy:sub(2,2) == 'D' then - path = 'Left' - elseif fairy:sub(2,2) == 'F' then - path = 'Right' - end - print(('Fairy : %d [Path: %s] '):format(utils.SwapEndianness(fairy,24),path)) - - local hat = blocks[9]:sub(8,11) - print(('Hat : %d'):format(utils.SwapEndianness(hat,16))) - - --0x0D 0x29 0x0A 0x02 16-bit hero points value. Maximum 100. - local heropoints = blocks[13]:sub(20,23) - print(('Hero points : %d'):format(utils.SwapEndianness(heropoints,16))) - - --0x10 0x2C 0x0C 0x04 32 bit flag value indicating heroic challenges completed. - local challenges = blocks[16]:sub(25,32) - print(('Finished hero challenges : %d'):format(utils.SwapEndianness(challenges,32))) - - if maxed then - print('Lets try to max out some values') - -- max out money, experience - --print (blocks[8]) - blocks[8] = 'FFFFFF'..'FFFF'..blocks[8]:sub(11,32) - blocks[36] = 'FFFFFF'..'FFFF'..blocks[36]:sub(11,32) - --print (blocks[8]) - - -- max out hero challenges - --print (blocks[16]) - blocks[16] = blocks[16]:sub(1,24)..'FFFFFFFF' - blocks[44] = blocks[44]:sub(1,24)..'FFFFFFFF' - --print (blocks[16]) - - -- max out heropoints - --print (blocks[13]) - blocks[13] = blocks[13]:sub(1,19)..'0064'..blocks[13]:sub(24,32) - blocks[41] = blocks[41]:sub(1,19)..'0064'..blocks[41]:sub(24,32) - --print (blocks[13]) - - -- Update Checksums - print('Updating all checksums') - SetCheckSum(blocks, 3) - SetCheckSum(blocks, 2) - SetCheckSum(blocks, 1) - SetCheckSum(blocks, 0) - - print('Validating all checksums') - ValidateCheckSums(blocks) - end - - --Load dumpdata to emulator memory - if DEBUG then - print('Sending dumpdata to emulator memory') - err = LoadEmulator(blocks) - if err then return oops(err) end - core.clearCommandBuffer() - print('The simulation is now prepared.\n --> run \"hf mf sim 5 '..uid..'\" <--') - end -end -main(args) \ No newline at end of file diff --git a/client/ui.c b/client/ui.c index e464a533..c0d01bc3 100644 --- a/client/ui.c +++ b/client/ui.c @@ -12,22 +12,16 @@ #include #include #include -#include #include #include #include -#include "loclass/cipherutils.h" + #include "ui.h" -#include "cmdmain.h" -#include "cmddata.h" -#include "graph.h" -//#include -#define M_PI 3.14159265358979323846264338327 double CursorScaleFactor; int PlotGridX, PlotGridY, PlotGridXdefault= 64, PlotGridYdefault= 64; int offline; -int flushAfterWrite = 0; +int flushAfterWrite = 0; //buzzy extern pthread_mutex_t print_lock; static char *logfilename = "proxmark3.log"; @@ -38,13 +32,13 @@ void PrintAndLog(char *fmt, ...) int saved_point; va_list argptr, argptr2; static FILE *logfile = NULL; - static int logging = 1; + static int logging=1; // lock this section to avoid interlacing prints from different threats pthread_mutex_lock(&print_lock); if (logging && !logfile) { - logfile = fopen(logfilename, "a"); + logfile=fopen(logfilename, "a"); if (!logfile) { fprintf(stderr, "Can't open logfile, logging disabled!\n"); logging=0; @@ -83,401 +77,16 @@ void PrintAndLog(char *fmt, ...) } va_end(argptr2); - if (flushAfterWrite == 1) { + if (flushAfterWrite == 1) //buzzy + { fflush(NULL); } //release lock pthread_mutex_unlock(&print_lock); } + void SetLogFilename(char *fn) { logfilename = fn; } - -int manchester_decode( int * data, const size_t len, uint8_t * dataout, size_t dataoutlen){ - - int bitlength = 0; - int clock, high, low, startindex; - low = startindex = 0; - high = 1; - uint8_t * bitStream = (uint8_t* ) malloc(sizeof(uint8_t) * dataoutlen); - memset(bitStream, 0x00, dataoutlen); - - /* Detect high and lows */ - DetectHighLowInGraph(&high, &low, TRUE); - - /* get clock */ - clock = GetClock("", 0); - - startindex = DetectFirstTransition(data, len, high); - - if (high != 1) - // decode "raw" - bitlength = ManchesterConvertFrom255(data, len, bitStream, dataoutlen, high, low, clock, startindex); - else - // decode manchester - bitlength = ManchesterConvertFrom1(data, len, bitStream, dataoutlen, clock, startindex); - - memcpy(dataout, bitStream, bitlength); - free(bitStream); - return bitlength; -} - - int DetectFirstTransition(const int * data, const size_t len, int threshold){ - - int i = 0; - /* now look for the first threshold */ - for (; i < len; ++i) { - if (data[i] == threshold) { - break; - } - } - return i; - } - - int ManchesterConvertFrom255(const int * data, const size_t len, uint8_t * dataout, int dataoutlen, int high, int low, int clock, int startIndex){ - - int i, j, z, hithigh, hitlow, bitIndex, startType; - i = 0; - bitIndex = 0; - - int isDamp = 0; - int damplimit = (int)((high / 2) * 0.3); - int dampHi = (high/2)+damplimit; - int dampLow = (high/2)-damplimit; - int firstST = 0; - - // i = clock frame of data - for (; i < (int)(len/clock); i++) - { - hithigh = 0; - hitlow = 0; - startType = -1; - z = startIndex + (i*clock); - isDamp = 0; - - /* Find out if we hit both high and low peaks */ - for (j = 0; j < clock; j++) - { - if (data[z+j] == high){ - hithigh = 1; - if ( startType == -1) - startType = 1; - } - - if (data[z+j] == low ){ - hitlow = 1; - if ( startType == -1) - startType = 0; - } - - if (hithigh && hitlow) - break; - } - - // No high value found, are we in a dampening field? - if ( !hithigh ) { - //PrintAndLog(" # Entering damp test at index : %d (%d)", z+j, j); - for (j = 0; j < clock; j++) { - if ( - (data[z+j] <= dampHi && data[z+j] >= dampLow) - ){ - isDamp++; - } - } - } - - /* Manchester Switching.. - 0: High -> Low - 1: Low -> High - */ - if (startType == 0) - dataout[bitIndex++] = 1; - else if (startType == 1) - dataout[bitIndex++] = 0; - else - dataout[bitIndex++] = 2; - - if ( isDamp > clock/2 ) { - firstST++; - } - - if ( firstST == 4) - break; - if ( bitIndex >= dataoutlen-1 ) - break; - } - return bitIndex; - } - - int ManchesterConvertFrom1(const int * data, const size_t len, uint8_t * dataout,int dataoutlen, int clock, int startIndex){ - - PrintAndLog(" Path B"); - - int i,j, bitindex, lc, tolerance, warnings; - warnings = 0; - int upperlimit = len*2/clock+8; - i = startIndex; - j = 0; - tolerance = clock/4; - uint8_t decodedArr[len]; - - /* Detect duration between 2 successive transitions */ - for (bitindex = 1; i < len; i++) { - - if (data[i-1] != data[i]) { - lc = i - startIndex; - startIndex = i; - - // Error check: if bitindex becomes too large, we do not - // have a Manchester encoded bitstream or the clock is really wrong! - if (bitindex > upperlimit ) { - PrintAndLog("Error: the clock you gave is probably wrong, aborting."); - return 0; - } - // Then switch depending on lc length: - // Tolerance is 1/4 of clock rate (arbitrary) - if (abs((lc-clock)/2) < tolerance) { - // Short pulse : either "1" or "0" - decodedArr[bitindex++] = data[i-1]; - } else if (abs(lc-clock) < tolerance) { - // Long pulse: either "11" or "00" - decodedArr[bitindex++] = data[i-1]; - decodedArr[bitindex++] = data[i-1]; - } else { - ++warnings; - PrintAndLog("Warning: Manchester decode error for pulse width detection."); - if (warnings > 10) { - PrintAndLog("Error: too many detection errors, aborting."); - return 0; - } - } - } - } - - /* - * We have a decodedArr of "01" ("1") or "10" ("0") - * parse it into final decoded dataout - */ - for (i = 0; i < bitindex; i += 2) { - - if ((decodedArr[i] == 0) && (decodedArr[i+1] == 1)) { - dataout[j++] = 1; - } else if ((decodedArr[i] == 1) && (decodedArr[i+1] == 0)) { - dataout[j++] = 0; - } else { - i++; - warnings++; - PrintAndLog("Unsynchronized, resync..."); - PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)"); - - if (warnings > 10) { - PrintAndLog("Error: too many decode errors, aborting."); - return 0; - } - } - } - - PrintAndLog("%s", sprint_hex(dataout, j)); - return j; - } - - void ManchesterDiffDecodedString(const uint8_t* bitstream, size_t len, uint8_t invert){ - /* - * We have a bitstream of "01" ("1") or "10" ("0") - * parse it into final decoded bitstream - */ - int i, j, warnings; - uint8_t decodedArr[(len/2)+1]; - - j = warnings = 0; - - uint8_t lastbit = 0; - - for (i = 0; i < len; i += 2) { - - uint8_t first = bitstream[i]; - uint8_t second = bitstream[i+1]; - - if ( first == second ) { - ++i; - ++warnings; - if (warnings > 10) { - PrintAndLog("Error: too many decode errors, aborting."); - return; - } - } - else if ( lastbit != first ) { - decodedArr[j++] = 0 ^ invert; - } - else { - decodedArr[j++] = 1 ^ invert; - } - lastbit = second; - } - - PrintAndLog("%s", sprint_hex(decodedArr, j)); -} - -void PrintPaddedManchester( uint8_t* bitStream, size_t len, size_t blocksize){ - - PrintAndLog(" Manchester decoded : %d bits", len); - - uint8_t mod = len % blocksize; - uint8_t div = len / blocksize; - int i; - - // Now output the bitstream to the scrollback by line of 16 bits - for (i = 0; i < div*blocksize; i+=blocksize) { - PrintAndLog(" %s", sprint_bin(bitStream+i,blocksize) ); - } - - if ( mod > 0 ) - PrintAndLog(" %s", sprint_bin(bitStream+i, mod) ); -} - -/* Sliding DFT - Smooths out -*/ -void iceFsk2(int * data, const size_t len){ - - int i, j; - int * output = (int* ) malloc(sizeof(int) * len); - memset(output, 0x00, len); - - // for (i=0; i 60)? 100:0; - } - } - - for (j=0; j 0)? 10 : -10; - } - - // show data - for (j=0; j0 ? 1:0; - printf("%d", bit ); - } - printf("\n"); - - printf("R/50 : "); - for (i =startPos ; i < adjustedLen; i += 50){ - bit = data[i]>0 ? 1:0; - printf("%d", bit ); } - printf("\n"); - - free(output); -} - -float complex cexpf (float complex Z) -{ - float complex Res; - double rho = exp (__real__ Z); - __real__ Res = rho * cosf(__imag__ Z); - __imag__ Res = rho * sinf(__imag__ Z); - return Res; -} diff --git a/client/ui.h b/client/ui.h index 6a45fcfd..a45799d5 100644 --- a/client/ui.h +++ b/client/ui.h @@ -11,10 +11,6 @@ #ifndef UI_H__ #define UI_H__ -#include -#include -#include "util.h" - void ShowGui(void); void HideGraphWindow(void); void ShowGraphWindow(void); @@ -27,13 +23,4 @@ extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault; extern int offline; extern int flushAfterWrite; //buzzy -int manchester_decode( int * data, const size_t len, uint8_t * dataout, size_t dataoutlen); -int GetT55x7Clock( const int * data, const size_t len, int high ); -int DetectFirstTransition(const int * data, const size_t len, int low); -void PrintPaddedManchester( uint8_t * bitStream, size_t len, size_t blocksize); -void ManchesterDiffDecodedString( const uint8_t *bitStream, size_t len, uint8_t invert ); -int ManchesterConvertFrom255(const int * data, const size_t len, uint8_t * dataout,int dataoutlen, int high, int low, int clock, int startIndex); -int ManchesterConvertFrom1(const int * data, const size_t len, uint8_t * dataout, int dataoutlen, int clock, int startIndex); -void iceFsk2(int * data, const size_t len); -void iceFsk3(int * data, const size_t len); #endif diff --git a/client/util.c b/client/util.c index b8d5c316..15e911a1 100644 --- a/client/util.c +++ b/client/util.c @@ -13,7 +13,6 @@ #ifndef _WIN32 #include #include - int ukbhit(void) { int cnt = 0; @@ -46,18 +45,12 @@ int ukbhit(void) { #endif // log files functions -void AddLogLine(char *file, char *extData, char *c) { +void AddLogLine(char *fileName, char *extData, char *c) { FILE *fLog = NULL; - char filename[FILE_PATH_SIZE] = {0x00}; - int len = 0; - len = strlen(file); - if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; - memcpy(filename, file, len); - - fLog = fopen(filename, "a"); + fLog = fopen(fileName, "a"); if (!fLog) { - printf("Could not append log file %s", filename); + printf("Could not append log file %s", fileName); return; } @@ -109,31 +102,16 @@ void print_hex(const uint8_t * data, const size_t len) } char * sprint_hex(const uint8_t * data, const size_t len) { - - int maxLen = ( len > 1024/3) ? 1024/3 : len; static char buf[1024]; char * tmp = buf; size_t i; - for (i=0; i < maxLen; ++i, tmp += 3) + for (i=0; i < len && i < 1024/3; i++, tmp += 3) sprintf(tmp, "%02x ", data[i]); return buf; } -char * sprint_bin(const uint8_t * data, const size_t len) { - - int maxLen = ( len > 1024) ? 1024 : len; - static char buf[1024]; - char * tmp = buf; - size_t i; - - for (i=0; i < maxLen; ++i, ++tmp) - sprintf(tmp, "%u", data[i]); - - return buf; -} - void num_to_bytes(uint64_t n, size_t len, uint8_t* dest) { while (len--) { @@ -153,28 +131,6 @@ uint64_t bytes_to_num(uint8_t* src, size_t len) return num; } -//assumes little endian -char * printBits(size_t const size, void const * const ptr) -{ - unsigned char *b = (unsigned char*) ptr; - unsigned char byte; - static char buf[1024]; - char * tmp = buf; - int i, j; - - for (i=size-1;i>=0;i--) - { - for (j=7;j>=0;j--) - { - byte = b[i] & (1<>= j; - sprintf(tmp, "%u", byte); - tmp++; - } - } - return buf; -} - // ------------------------------------------------------------------------- // string parameters lib // ------------------------------------------------------------------------- @@ -292,102 +248,3 @@ int param_getstr(const char *line, int paramnum, char * str) return en - bg + 1; } - -/* -The following methods comes from Rfidler sourcecode. -https://github.com/ApertureLabsLtd/RFIDler/blob/master/firmware/Pic32/RFIDler.X/src/ -*/ - -// convert hex to sequence of 0/1 bit values -// returns number of bits converted -int hextobinarray(char *target, char *source) -{ - int length, i, count= 0; - char x; - - length = strlen(source); - // process 4 bits (1 hex digit) at a time - while(length--) - { - x= *(source++); - // capitalize - if (x >= 'a' && x <= 'f') - x -= 32; - // convert to numeric value - if (x >= '0' && x <= '9') - x -= '0'; - else if (x >= 'A' && x <= 'F') - x -= 'A' - 10; - else - return 0; - // output - for(i= 0 ; i < 4 ; ++i, ++count) - *(target++)= (x >> (3 - i)) & 1; - } - - return count; -} - -// convert hex to human readable binary string -int hextobinstring(char *target, char *source) -{ - int length; - - if(!(length= hextobinarray(target, source))) - return 0; - binarraytobinstring(target, target, length); - return length; -} - -// convert binary array of 0x00/0x01 values to hex (safe to do in place as target will always be shorter than source) -// return number of bits converted -int binarraytohex(char *target, char *source, int length) -{ - unsigned char i, x; - int j = length; - - if(j % 4) - return 0; - - while(j) - { - for(i= x= 0 ; i < 4 ; ++i) - x += ( source[i] << (3 - i)); - sprintf(target,"%X", x); - ++target; - source += 4; - j -= 4; - } - return length; -} - -// convert binary array to human readable binary -void binarraytobinstring(char *target, char *source, int length) -{ - int i; - - for(i= 0 ; i < length ; ++i) - *(target++)= *(source++) + '0'; - *target= '\0'; -} - -// return parity bit required to match type -uint8_t GetParity( char *bits, uint8_t type, int length) -{ - int x; - - for(x= 0 ; length > 0 ; --length) - x += bits[length - 1]; - x %= 2; - - return x ^ type; -} - -// add HID parity to binary array: EVEN prefix for 1st half of ID, ODD suffix for 2nd half -void wiegand_add_parity(char *target, char *source, char length) -{ - *(target++)= GetParity(source, EVEN, length / 2); - memcpy(target, source, length); - target += length; - *(target)= GetParity(source + length / 2, ODD, length / 2); -} diff --git a/client/util.h b/client/util.h index 22d41e0c..ce8876ed 100644 --- a/client/util.h +++ b/client/util.h @@ -15,7 +15,6 @@ #include #include #include -#include "data.h" #ifndef MIN # define MIN(a, b) (((a) < (b)) ? (a) : (b)) @@ -23,10 +22,6 @@ #ifndef MAX # define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif -#define TRUE 1 -#define FALSE 0 -#define EVEN 0 -#define ODD 1 int ukbhit(void); @@ -38,11 +33,9 @@ void FillFileNameByUID(char *fileName, uint8_t * uid, char *ext, int byteCount); void print_hex(const uint8_t * data, const size_t len); char * sprint_hex(const uint8_t * data, const size_t len); -char * sprint_bin(const uint8_t * data, const size_t len); void num_to_bytes(uint64_t n, size_t len, uint8_t* dest); uint64_t bytes_to_num(uint8_t* src, size_t len); -char * printBits(size_t const size, void const * const ptr); char param_getchar(const char *line, int paramnum); uint8_t param_get8(const char *line, int paramnum); @@ -52,10 +45,3 @@ uint64_t param_get64ex(const char *line, int paramnum, int deflt, int base); int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt); int param_getstr(const char *line, int paramnum, char * str); - int hextobinarray( char *target, char *source); - int hextobinstring( char *target, char *source); - int binarraytohex( char *target, char *source, int length); -void binarraytobinstring(char *target, char *source, int length); -uint8_t GetParity( char *string, uint8_t type, int length); -void wiegand_add_parity(char *target, char *source, char length); - diff --git a/common/Makefile.common b/common/Makefile.common index b30294a8..2befd456 100644 --- a/common/Makefile.common +++ b/common/Makefile.common @@ -54,8 +54,7 @@ DELETE=del /q MOVE=ren COPY=copy PATHSEP=\\# -#FLASH_TOOL=winsrc\\prox.exe -FLASH_TOOL=winsrc\\flash.exe +FLASH_TOOL=winsrc\\prox.exe DETECTED_OS=Windows endif @@ -68,8 +67,7 @@ INCLUDES = ../include/proxmark3.h ../include/at91sam7s512.h ../include/config_gp CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=c99 $(APP_CFLAGS) -Os LDFLAGS = -nostartfiles -nodefaultlibs -Wl,-gc-sections -n - -LIBS = -lgcc +LIBS = -lgcc THUMBOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(THUMBSRC)) ARMOBJ = $(ARMSRC:%.c=$(OBJDIR)/%.o) diff --git a/common/cmd.c b/common/cmd.c index 66b93990..49d9d942 100644 --- a/common/cmd.c +++ b/common/cmd.c @@ -32,7 +32,9 @@ #include "cmd.h" #include "string.h" -#include "../include/proxmark3.h" +#include "proxmark3.h" + +//static UsbCommand txcmd; bool cmd_receive(UsbCommand* cmd) { diff --git a/common/cmd.h b/common/cmd.h index 35885de4..b330a219 100644 --- a/common/cmd.h +++ b/common/cmd.h @@ -33,8 +33,8 @@ #ifndef _PROXMARK_CMD_H_ #define _PROXMARK_CMD_H_ -#include "../include/common.h" -#include "../include/usb_cmd.h" +#include +#include #include "usb_cdc.h" bool cmd_receive(UsbCommand* cmd); diff --git a/common/crc.h b/common/crc.h deleted file mode 100644 index 8e68f3b3..00000000 --- a/common/crc.h +++ /dev/null @@ -1,48 +0,0 @@ -//----------------------------------------------------------------------------- -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// Generic CRC calculation code. -//----------------------------------------------------------------------------- - -#ifndef __CRC_H -#define __CRC_H - -#include - -typedef struct crc { - uint32_t state; - int order; - uint32_t polynom; - uint32_t initial_value; - uint32_t final_xor; - uint32_t mask; -} crc_t; - -/* Initialize a crc structure. order is the order of the polynom, e.g. 32 for a CRC-32 - * polynom is the CRC polynom. initial_value is the initial value of a clean state. - * final_xor is XORed onto the state before returning it from crc_result(). */ -extern void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor); - -/* Update the crc state. data is the data of length data_width bits (only the the - * data_width lower-most bits are used). - */ -extern void crc_update(crc_t *crc, uint32_t data, int data_width); - -/* Clean the crc state, e.g. reset it to initial_value */ -extern void crc_clear(crc_t *crc); - -/* Get the result of the crc calculation */ -extern uint32_t crc_finish(crc_t *crc); - -/* Static initialization of a crc structure */ -#define CRC_INITIALIZER(_order, _polynom, _initial_value, _final_xor) { \ - .state = ((_initial_value) & ((1L<<(_order))-1)), \ - .order = (_order), \ - .polynom = (_polynom), \ - .initial_value = (_initial_value), \ - .final_xor = (_final_xor), \ - .mask = ((1L<<(_order))-1) } - -#endif /* __CRC_H */ diff --git a/common/crc16.c b/common/crc16.c index 973cd103..d181bb2a 100644 --- a/common/crc16.c +++ b/common/crc16.c @@ -8,7 +8,6 @@ #include "crc16.h" - unsigned short update_crc16( unsigned short crc, unsigned char c ) { unsigned short i, v, tcrc = 0; @@ -21,25 +20,3 @@ unsigned short update_crc16( unsigned short crc, unsigned char c ) return ((crc >> 8) ^ tcrc)&0xffff; } - -uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t polynomial) { - - if (length == 0) - return (~remainder); - - for (int byte = 0; byte < length; ++byte) { - remainder ^= (message[byte] << 8); - for (uint8_t bit = 8; bit > 0; --bit) { - if (remainder & 0x8000) { - remainder = (remainder << 1) ^ polynomial; - } else { - remainder = (remainder << 1); - } - } - } - return remainder; -} - -uint16_t crc16_ccitt(uint8_t const *message, int length) { - return crc16(message, length, 0xffff, 0x1021); -} diff --git a/common/crc16.h b/common/crc16.h index d16d83b5..055a60bc 100644 --- a/common/crc16.h +++ b/common/crc16.h @@ -5,11 +5,10 @@ //----------------------------------------------------------------------------- // CRC16 //----------------------------------------------------------------------------- -#include #ifndef __CRC16_H #define __CRC16_H + unsigned short update_crc16(unsigned short crc, unsigned char c); -uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t polynomial); -uint16_t crc16_ccitt(uint8_t const *message, int length); + #endif diff --git a/common/crc32.c b/common/crc32.c deleted file mode 100644 index 69d770f4..00000000 --- a/common/crc32.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include "crc32.h" - -#define htole32(x) (x) -#define CRC32_PRESET 0xFFFFFFFF - - -static void crc32_byte (uint32_t *crc, const uint8_t value); - -static void crc32_byte (uint32_t *crc, const uint8_t value) { - /* x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 */ - const uint32_t poly = 0xEDB88320; - - *crc ^= value; - for (int current_bit = 7; current_bit >= 0; current_bit--) { - int bit_out = (*crc) & 0x00000001; - *crc >>= 1; - if (bit_out) - *crc ^= poly; - } -} - -void crc32 (const uint8_t *data, const size_t len, uint8_t *crc) { - uint32_t desfire_crc = CRC32_PRESET; - for (size_t i = 0; i < len; i++) { - crc32_byte (&desfire_crc, data[i]); - } - - *((uint32_t *)(crc)) = htole32 (desfire_crc); -} - -void crc32_append (uint8_t *data, const size_t len) { - crc32 (data, len, data + len); -} diff --git a/common/crc32.h b/common/crc32.h deleted file mode 100644 index 0dd2a328..00000000 --- a/common/crc32.h +++ /dev/null @@ -1,15 +0,0 @@ -//----------------------------------------------------------------------------- -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// CRC32 -//----------------------------------------------------------------------------- - -#ifndef __CRC32_H -#define __CRC32_H - -void crc32 (const uint8_t *data, const size_t len, uint8_t *crc); -void crc32_append (uint8_t *data, const size_t len); - -#endif diff --git a/common/desfire.h b/common/desfire.h deleted file mode 100644 index c163c5c5..00000000 --- a/common/desfire.h +++ /dev/null @@ -1,179 +0,0 @@ -#ifndef __DESFIRE_H -#define __DESFIRE_H - -#include -#include - -#include "aes.h" - -#define MAX_CRYPTO_BLOCK_SIZE 16 -/* Mifare DESFire EV1 Application crypto operations */ -#define APPLICATION_CRYPTO_DES 0x00 -#define APPLICATION_CRYPTO_3K3DES 0x40 -#define APPLICATION_CRYPTO_AES 0x80 - -#define MAC_LENGTH 4 -#define CMAC_LENGTH 8 - -typedef enum { - MCD_SEND, - MCD_RECEIVE -} MifareCryptoDirection; - -typedef enum { - MCO_ENCYPHER, - MCO_DECYPHER -} MifareCryptoOperation; - -#define MDCM_MASK 0x000F - -#define CMAC_NONE 0 - -// Data send to the PICC is used to update the CMAC -#define CMAC_COMMAND 0x010 -// Data received from the PICC is used to update the CMAC -#define CMAC_VERIFY 0x020 - -// MAC the command (when MDCM_MACED) -#define MAC_COMMAND 0x100 -// The command returns a MAC to verify (when MDCM_MACED) -#define MAC_VERIFY 0x200 - -#define ENC_COMMAND 0x1000 -#define NO_CRC 0x2000 - -#define MAC_MASK 0x0F0 -#define CMAC_MACK 0xF00 - -/* Communication mode */ -#define MDCM_PLAIN 0x00 -#define MDCM_MACED 0x01 -#define MDCM_ENCIPHERED 0x03 - -/* Error code managed by the library */ -#define CRYPTO_ERROR 0x01 - - -enum DESFIRE_AUTH_SCHEME { - AS_LEGACY, - AS_NEW -}; - -enum DESFIRE_CRYPTOALGO { - T_DES = 0x00, - T_3DES = 0x01, - T_3K3DES = 0x02, - T_AES = 0x03 -}; - - -#define DESFIRE_KEY(key) ((struct desfire_key *) key) -struct desfire_key { - enum DESFIRE_CRYPTOALGO type; - uint8_t data[24]; - // DES_key_schedule ks1; - // DES_key_schedule ks2; - // DES_key_schedule ks3; - AesCtx aes_ks; - uint8_t cmac_sk1[24]; - uint8_t cmac_sk2[24]; - uint8_t aes_version; -}; -typedef struct desfire_key *desfirekey_t; - -#define DESFIRE(tag) ((struct desfire_tag *) tag) -struct desfire_tag { - iso14a_card_select_t info; - int active; - uint8_t last_picc_error; - uint8_t last_internal_error; - uint8_t last_pcd_error; - desfirekey_t session_key; - enum DESFIRE_AUTH_SCHEME authentication_scheme; - uint8_t authenticated_key_no; - - uint8_t ivect[MAX_CRYPTO_BLOCK_SIZE]; - uint8_t cmac[16]; - uint8_t *crypto_buffer; - size_t crypto_buffer_size; - uint32_t selected_application; -}; -typedef struct desfire_tag *desfiretag_t; - - -/* File types */ -enum DESFIRE_FILE_TYPES { - MDFT_STANDARD_DATA_FILE = 0x00, - MDFT_BACKUP_DATA_FILE = 0x01, - MDFT_VALUE_FILE_WITH_BACKUP = 0x02, - MDFT_LINEAR_RECORD_FILE_WITH_BACKUP = 0x03, - MDFT_CYCLIC_RECORD_FILE_WITH_BACKUP = 0x04 -}; - - - -enum DESFIRE_STATUS { - OPERATION_OK = 0x00, - NO_CHANGES = 0x0c, - OUT_OF_EEPROM_ERROR = 0x0e, - ILLEGAL_COMMAND_CODE = 0x1c, - INTEGRITY_ERROR = 0x1e, - NO_SUCH_KEY = 0x40, - LENGTH_ERROR = 0x7e, - PERMISSION_DENIED = 0x9d, - PARAMETER_ERROR = 0x9e, - APPLICATION_NOT_FOUND = 0xa0, - APPL_INTEGRITY_ERROR = 0xa1, - AUTHENTICATION_ERROR = 0xae, - ADDITIONAL_FRAME = 0xaf, - BOUNDARY_ERROR = 0xbe, - PICC_INTEGRITY_ERROR = 0xc1, - COMMAND_ABORTED = 0xca, - PICC_DISABLED_ERROR = 0xcd, - COUNT_ERROR = 0xce, - DUPLICATE_ERROR = 0xde, - EEPROM_ERROR = 0xee, - FILE_NOT_FOUND = 0xf0, - FILE_INTEGRITY_ERROR = 0xf1 -}; - -enum DESFIRE_CMD { - CREATE_APPLICATION = 0xca, - DELETE_APPLICATION = 0xda, - GET_APPLICATION_IDS = 0x6a, - SELECT_APPLICATION = 0x5a, - FORMAT_PICC = 0xfc, - GET_VERSION = 0x60, - READ_DATA = 0xbd, - WRITE_DATA = 0x3d, - GET_VALUE = 0x6c, - CREDIT = 0x0c, - DEBIT = 0xdc, - LIMITED_CREDIT = 0x1c, - WRITE_RECORD = 0x3b, - READ_RECORDS = 0xbb, - CLEAR_RECORD_FILE = 0xeb, - COMMIT_TRANSACTION = 0xc7, - ABORT_TRANSACTION = 0xa7, - GET_FREE_MEMORY = 0x6e, - GET_FILE_IDS = 0x6f, - GET_FILE_SETTINGS = 0xf5, - CHANGE_FILE_SETTINGS = 0x5f, - CREATE_STD_DATA_FILE = 0xcd, - CREATE_BACKUP_DATA_FILE = 0xcb, - CREATE_VALUE_FILE = 0xcc, - CREATE_LINEAR_RECORD_FILE = 0xc1, - CREATE_CYCLIC_RECORD_FILE = 0xc0, - DELETE_FILE = 0xdf, - AUTHENTICATE = 0x0a, // AUTHENTICATE_NATIVE - AUTHENTICATE_ISO = 0x1a, // AUTHENTICATE_STANDARD - AUTHENTICATE_AES = 0xaa, - CHANGE_KEY_SETTINGS = 0x54, - GET_KEY_SETTINGS = 0x45, - CHANGE_KEY = 0xc4, - GET_KEY_VERSION = 0x64, - AUTHENTICATION_FRAME = 0xAF -}; - -#endif - diff --git a/common/iso14443crc.c b/common/iso14443crc.c index 851546ae..a6def1a9 100644 --- a/common/iso14443crc.c +++ b/common/iso14443crc.c @@ -6,7 +6,7 @@ // ISO14443 CRC calculation code. //----------------------------------------------------------------------------- -#include "../common/iso14443crc.h" +#include "iso14443crc.h" static unsigned short UpdateCrc14443(unsigned char ch, unsigned short *lpwCrc) { diff --git a/common/iso14443crc.h b/common/iso14443crc.h index 80941116..87347714 100644 --- a/common/iso14443crc.h +++ b/common/iso14443crc.h @@ -8,7 +8,7 @@ #ifndef __ISO14443CRC_H #define __ISO14443CRC_H -#include "../include/common.h" +#include "common.h" //----------------------------------------------------------------------------- // Routines to compute the CRCs (two different flavours, just for confusion) diff --git a/common/iso15693tools.c b/common/iso15693tools.c index 0ec5492b..26e636ca 100644 --- a/common/iso15693tools.c +++ b/common/iso15693tools.c @@ -7,7 +7,7 @@ //----------------------------------------------------------------------------- -#include "../include/proxmark3.h" +#include "proxmark3.h" #include #include //#include "iso15693tools.h" diff --git a/common/legic_prng.c b/common/legic_prng.c index 322429ad..4f3b1ffe 100644 --- a/common/legic_prng.c +++ b/common/legic_prng.c @@ -6,7 +6,7 @@ // LEFIC's obfuscation function //----------------------------------------------------------------------------- -#include "../include/legic_prng.h" +#include "legic_prng.h" struct lfsr { uint8_t a; diff --git a/common/lfdemod.c b/common/lfdemod.c index eb5a4d95..79c99f73 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -8,656 +8,626 @@ // Low frequency commands //----------------------------------------------------------------------------- -#include #include #include #include "lfdemod.h" //by marshmellow //takes 1s and 0s and searches for EM410x format - output EM ID -uint64_t Em410xDecode(uint8_t *BitStream, uint32_t BitLen) +uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen) { - //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future - // otherwise could be a void with no arguments - //set defaults - int high = 0, low = 128; - uint64_t lo = 0; - uint32_t i = 0; - uint32_t initLoopMax = 65; + //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future + // otherwise could be a void with no arguments + //set defaults + int high=0, low=128; + uint64_t lo=0; //hi=0, - if (initLoopMax > BitLen) - initLoopMax = BitLen; + uint32_t i = 0; + uint32_t initLoopMax = 65; + if (initLoopMax>BitLen) initLoopMax=BitLen; - for (; i < initLoopMax; ++i) //65 samples should be plenty to find high and low values - { - if (BitStream[i] > high) - high = BitStream[i]; - else if (BitStream[i] < low) - low = BitStream[i]; - } - - if (((high !=1)||(low !=0))){ //allow only 1s and 0s - return 0; - } - - uint8_t parityTest = 0; - // 111111111 bit pattern represent start of frame - uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1}; - uint32_t idx = 0; - uint32_t j = 0; - uint8_t resetCnt = 0; - while( (idx + 64) < BitLen) { - - restart: - - // search for a start of frame marker - if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) { - // frame marker found - idx += 9;//sizeof(frame_marker_mask); - for ( i = 0; i < 10; ++i){ - for( j = 0; j < 5; ++j){ - parityTest += BitStream[(i*5) + j + idx]; - } - if (parityTest == ( (parityTest >> 1) << 1)){ - parityTest = 0; - for (j = 0; j < 4; ++j){ - lo = ( lo << 1LL)|( BitStream[( i * 5 ) + j + idx]); - } - } else { - //parity failed - parityTest = 0; - idx -= 8; - if (resetCnt > 5) return 0; - resetCnt++; - goto restart;//continue; - } - } - //skip last 5 bit parity test for simplicity. - return lo; - } else { - idx++; - } - } - return 0; + for (;i < initLoopMax; ++i) //65 samples should be plenty to find high and low values + { + if (BitStream[i] > high) + high = BitStream[i]; + else if (BitStream[i] < low) + low = BitStream[i]; + } + if (((high !=1)||(low !=0))){ //allow only 1s and 0s + // PrintAndLog("no data found"); + return 0; + } + uint8_t parityTest=0; + // 111111111 bit pattern represent start of frame + uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1}; + uint32_t idx = 0; + uint32_t ii=0; + uint8_t resetCnt = 0; + while( (idx + 64) < BitLen) { +restart: + // search for a start of frame marker + if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=9;//sizeof(frame_marker_mask); + for (i=0; i<10;i++){ + for(ii=0; ii<5; ++ii){ + parityTest += BitStream[(i*5)+ii+idx]; + } + if (parityTest== ((parityTest>>1)<<1)){ + parityTest=0; + for (ii=0; ii<4;++ii){ + //hi = (hi<<1)|(lo>>31); + lo=(lo<<1LL)|(BitStream[(i*5)+ii+idx]); + } + //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1],lo); + }else {//parity failed + //PrintAndLog("DEBUG: EM parity failed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1]); + parityTest=0; + idx-=8; + if (resetCnt>5)return 0; + resetCnt++; + goto restart;//continue; + } + } + //skip last 5 bit parity test for simplicity. + return lo; + }else{ + idx++; + } + } + return 0; } //by marshmellow //takes 2 arguments - clock and invert both as integers //attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands -int askmandemod(uint8_t *BinStream, uint32_t *BitLen, int *clk, int *invert) +int askmandemod(uint8_t * BinStream,uint32_t *BitLen,int *clk, int *invert) { - int i; - int high = 0, low = 128; - *clk = DetectASKClock(BinStream, (size_t)*BitLen, *clk); //clock default - - if (*clk < 8 ) *clk = 64; - if (*clk < 32 ) *clk = 32; - if (*invert != 1) *invert = 0; - - uint32_t initLoopMax = 200; - if (initLoopMax > *BitLen) - initLoopMax = *BitLen; - - // Detect high and lows - // 200 samples should be enough to find high and low values - for (i = 0; i < initLoopMax; ++i) { - if (BinStream[i] > high) - high = BinStream[i]; - else if (BinStream[i] < low) - low = BinStream[i]; - } - - //throw away static - if ((high < 158) ) - return -2; + int i; + int high = 0, low = 128; + *clk=DetectASKClock(BinStream,(size_t)*BitLen,*clk); //clock default - //25% fuzz in case highs and lows aren't clipped [marshmellow] - high = (int)(high * .75); - low = (int)(low+128 * .25); - - int lastBit = 0; // set first clock check - uint32_t bitnum = 0; // output counter - - // clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave - //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely - int tol = ( *clk == 32 ) ? 1 : 0; - - int j = 0; - uint32_t gLen = *BitLen; - - if (gLen > 3000) gLen = 3000; - - uint8_t errCnt = 0; - uint32_t bestStart = *BitLen; - uint32_t bestErrCnt = (*BitLen/1000); - uint32_t maxErr = bestErrCnt; - - //loop to find first wave that works - for (j=0; j < gLen; ++j){ - - if ((BinStream[j] >= high)||(BinStream[j] <= low)){ - lastBit = j - *clk; - errCnt = 0; - - //loop through to see if this start location works - for (i = j; i < *BitLen; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit += *clk; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit += *clk; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit) > (*clk + tol)){ - //should have hit a high or low based on clock!! - - errCnt++; - lastBit += *clk;//skip over until hit too many errors - if (errCnt > maxErr) break; //allow 1 error for every 1000 samples else start over - } - } - if ((i-j) >(400 * *clk)) break; //got plenty of bits - } - //we got more than 64 good bits and not all errors - if ((((i-j)/ *clk) > (64 + errCnt)) && (errCnt < maxErr)) { - //possible good read - if (errCnt == 0){ - bestStart = j; - bestErrCnt = errCnt; - break; //great read - finish - } - if (errCnt < bestErrCnt){ //set this as new best run - bestErrCnt = errCnt; - bestStart = j; - } - } + if (*clk<8) *clk =64; + if (*clk<32) *clk=32; + if (*invert != 0 && *invert != 1) *invert=0; + uint32_t initLoopMax = 200; + if (initLoopMax>*BitLen) initLoopMax=*BitLen; + // Detect high and lows + for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values + { + if (BinStream[i] > high) + high = BinStream[i]; + else if (BinStream[i] < low) + low = BinStream[i]; } - } - if (bestErrCnt < maxErr){ - //best run is good enough set to best run and set overwrite BinStream - j = bestStart; - lastBit = bestStart - *clk; - bitnum = 0; - for (i = j; i < *BitLen; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit += *clk; - BinStream[bitnum] = *invert; - bitnum++; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit += *clk; - BinStream[bitnum] = 1 - *invert; - bitnum++; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit) > (*clk+tol)){ - //should have hit a high or low based on clock!! - if (bitnum > 0){ - BinStream[bitnum] = 77; - bitnum++; - } - lastBit += *clk;//skip over error - } - } - if (bitnum >= 400) break; - } - *BitLen = bitnum; - } else { - *invert = bestStart; - *clk = j; - return -1; - } - return bestErrCnt; + if ((high < 158) ){ //throw away static + //PrintAndLog("no data found"); + return -2; + } + //25% fuzz in case highs and lows aren't clipped [marshmellow] + high=(int)((high-128)*.75)+128; + low= (int)((low-128)*.75)+128; + + //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); + int lastBit = 0; //set first clock check + uint32_t bitnum = 0; //output counter + int tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave + if (*clk==32)tol=1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely + int iii = 0; + uint32_t gLen = *BitLen; + if (gLen > 3000) gLen=3000; + uint8_t errCnt =0; + uint32_t bestStart = *BitLen; + uint32_t bestErrCnt = (*BitLen/1000); + uint32_t maxErr = (*BitLen/1000); + //PrintAndLog("DEBUG - lastbit - %d",lastBit); + //loop to find first wave that works + for (iii=0; iii < gLen; ++iii){ + if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ + lastBit=iii-*clk; + errCnt=0; + //loop through to see if this start location works + for (i = iii; i < *BitLen; ++i) { + if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ + lastBit+=*clk; + } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + } else { + //mid value found or no bar supposed to be here + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! + + //debug + //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit); + + errCnt++; + lastBit+=*clk;//skip over until hit too many errors + if (errCnt>(maxErr)) break; //allow 1 error for every 1000 samples else start over + } + } + if ((i-iii) >(400 * *clk)) break; //got plenty of bits + } + //we got more than 64 good bits and not all errors + if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt= high) && ((i-lastBit)>(*clk-tol))){ + lastBit+=*clk; + BinStream[bitnum] = *invert; + bitnum++; + } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + BinStream[bitnum] = 1-*invert; + bitnum++; + } else { + //mid value found or no bar supposed to be here + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! + + //debug + //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit); + if (bitnum > 0){ + BinStream[bitnum]=77; + bitnum++; + } + + lastBit+=*clk;//skip over error + } + } + if (bitnum >=400) break; + } + *BitLen=bitnum; + } else{ + *invert=bestStart; + *clk=iii; + return -1; + } + return bestErrCnt; } //by marshmellow //take 10 and 01 and manchester decode //run through 2 times and take least errCnt -int manrawdecode(uint8_t * bits, int *bitlen) +int manrawdecode(uint8_t * BitStream, int *bitLen) { - int bitnum = 0; - int errCnt = 0; - int bestErr = 1000; - int bestRun = 0; - int i = 1; - int j = 1; - - for (; j < 3; ++j){ - i = 1; - for ( i = i + j; i < *bitlen-2; i += 2){ - if ( bits[i]==1 && (bits[i+1]==0)){ - } else if ((bits[i]==0)&& bits[i+1]==1){ - } else { - errCnt++; - } - if(bitnum > 300) break; - } - if (bestErr > errCnt){ - bestErr = errCnt; - bestRun = j; - } - errCnt = 0; - } - errCnt = bestErr; - if (errCnt < 20){ - j = bestRun; - i = 1; - for ( i = i+j; i < *bitlen-2; i += 2){ - if ( bits[i] == 1 && bits[i + 1] == 0 ){ - bits[bitnum++] = 0; - } else if ( bits[i] == 0 && bits[i + 1] == 1 ){ - bits[bitnum++] = 1; - } else { - bits[bitnum++] = 77; - } - if ( bitnum > 300 ) break; - } - *bitlen = bitnum; - } - return errCnt; + int bitnum=0; + int errCnt =0; + int i=1; + int bestErr = 1000; + int bestRun = 0; + int ii=1; + for (ii=1;ii<3;++ii){ + i=1; + for (i=i+ii;i<*bitLen-2;i+=2){ + if(BitStream[i]==1 && (BitStream[i+1]==0)){ + } else if((BitStream[i]==0)&& BitStream[i+1]==1){ + } else { + errCnt++; + } + if(bitnum>300) break; + } + if (bestErr>errCnt){ + bestErr=errCnt; + bestRun=ii; + } + errCnt=0; + } + errCnt=bestErr; + if (errCnt<20){ + ii=bestRun; + i=1; + for (i=i+ii;i<*bitLen-2;i+=2){ + if(BitStream[i]==1 && (BitStream[i+1]==0)){ + BitStream[bitnum++]=0; + } else if((BitStream[i]==0)&& BitStream[i+1]==1){ + BitStream[bitnum++]=1; + } else { + BitStream[bitnum++]=77; + //errCnt++; + } + if(bitnum>300) break; + } + *bitLen=bitnum; + } + return errCnt; } //by marshmellow //take 01 or 10 = 0 and 11 or 00 = 1 -int BiphaseRawDecode(uint8_t * bits, int *bitlen, int offset) +int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset) { - uint8_t bitnum = 0; - uint32_t errCnt = 0; - uint32_t i = offset; - - for (; i < *bitlen-2; i += 2 ){ - if ( (bits[i]==1 && bits[i+1]==0)|| - (bits[i]==0 && bits[i+1]==1)){ - bits[bitnum++] = 1; - } else if ( (bits[i]==0 && bits[i+1]==0)|| - (bits[i]==1 && bits[i+1]==1)){ - bits[bitnum++] = 0; - } else { - bits[bitnum++] = 77; - errCnt++; - } - if ( bitnum > 250) break; - } - *bitlen = bitnum; - return errCnt; + uint8_t bitnum=0; + uint32_t errCnt =0; + uint32_t i=1; + i=offset; + for (;i<*bitLen-2;i+=2){ + if((BitStream[i]==1 && BitStream[i+1]==0)||(BitStream[i]==0 && BitStream[i+1]==1)){ + BitStream[bitnum++]=1; + } else if((BitStream[i]==0 && BitStream[i+1]==0)||(BitStream[i]==1 && BitStream[i+1]==1)){ + BitStream[bitnum++]=0; + } else { + BitStream[bitnum++]=77; + errCnt++; + } + if(bitnum>250) break; + } + *bitLen=bitnum; + return errCnt; } //by marshmellow //takes 2 arguments - clock and invert both as integers //attempts to demodulate ask only //prints binary found and saves in graphbuffer for further commands -int askrawdemod(uint8_t *BinStream, int *bitLen, int *clk, int *invert) +int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert) { - uint32_t i; - uint32_t initLoopMax = 200; - int high = 0, low = 128; - uint8_t BitStream[502] = {0x00}; - - *clk = DetectASKClock(BinStream, *bitLen, *clk); //clock default - - if (*clk < 8) *clk = 64; - if (*clk < 32) *clk = 32; - if (*invert != 1) *invert = 0; + uint32_t i; + // int invert=0; //invert default + int high = 0, low = 128; + *clk=DetectASKClock(BinStream,*bitLen,*clk); //clock default + uint8_t BitStream[502] = {0}; - if (initLoopMax > *bitLen) - initLoopMax = *bitLen; - - // Detect high and lows - for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values - { - if (BinStream[i] > high) - high = BinStream[i]; - else if (BinStream[i] < low) - low = BinStream[i]; - } - - //throw away static - if ((high < 158)){ - return -2; - } - - //25% fuzz in case highs and lows aren't clipped [marshmellow] - high = (int)(high * .75); - low = (int)(low+128 * .25); - - int lastBit = 0; //set first clock check - uint32_t bitnum = 0; //output counter - - uint8_t tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave - if (*clk==32) tol = 1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely - - uint32_t gLen = *bitLen; - if (gLen > 500) gLen = 500; - - uint32_t j = 0; - uint8_t errCnt = 0; - uint32_t bestStart = *bitLen; - uint32_t bestErrCnt = (*bitLen / 1000); - uint32_t errCntLimit = bestErrCnt; - uint8_t midBit = 0; - - //loop to find first wave that works - for (j = 0; j < gLen; ++j){ - - if ((BinStream[j] >= high)||(BinStream[j] <= low)){ - lastBit = j - *clk; - //loop through to see if this start location works - for (i = j; i < *bitLen; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit += *clk; - BitStream[bitnum] = *invert; - bitnum++; - midBit = 0; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit += *clk; - BitStream[bitnum] = 1-*invert; - bitnum++; - midBit=0; - } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit = 1; - BitStream[bitnum] = 1 - *invert; - bitnum++; - } else if ((BinStream[i]>=high)&&(midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit = 1; - BitStream[bitnum] = *invert; - bitnum++; - } else if ((i-lastBit)>((*clk/2)+tol)&&(midBit==0)){ - //no mid bar found - midBit = 1; - BitStream[bitnum] = BitStream[bitnum-1]; - bitnum++; - } else { - //mid value found or no bar supposed to be here - - if (( i - lastBit) > ( *clk + tol)){ - //should have hit a high or low based on clock!! - - if (bitnum > 0){ - BitStream[bitnum] = 77; - bitnum++; - } - - errCnt++; - lastBit += *clk;//skip over until hit too many errors - if (errCnt > errCntLimit){ //allow 1 error for every 1000 samples else start over - errCnt = 0; - bitnum = 0;//start over - break; - } - } - } - if (bitnum > 500) break; - } - //we got more than 64 good bits and not all errors - //possible good read - if ((bitnum > (64 + errCnt)) && (errCnt < errCntLimit)) { - - //great read - finish - if (errCnt == 0) break; - - //if current run == bestErrCnt run (after exhausted testing) then finish - if (bestStart == j) break; - - //set this as new best run - if (errCnt < bestErrCnt){ - bestErrCnt = errCnt; - bestStart = j; - } - } + if (*clk<8) *clk =64; + if (*clk<32) *clk=32; + if (*invert != 0 && *invert != 1) *invert =0; + uint32_t initLoopMax = 200; + if (initLoopMax>*bitLen) initLoopMax=*bitLen; + // Detect high and lows + for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values + { + if (BinStream[i] > high) + high = BinStream[i]; + else if (BinStream[i] < low) + low = BinStream[i]; } - if (j >= gLen){ //exhausted test - //if there was a ok test go back to that one and re-run the best run (then dump after that run) - if (bestErrCnt < errCntLimit) - j = bestStart; + if ((high < 158)){ //throw away static + // PrintAndLog("no data found"); + return -2; } - } - if (bitnum > 16){ + //25% fuzz in case highs and lows aren't clipped [marshmellow] + high=(int)((high-128)*.75)+128; + low= (int)((low-128)*.75)+128; - for (i = 0; i < bitnum; ++i){ - BinStream[i] = BitStream[i]; - } - *bitLen = bitnum; - } else { - return -1; - } - return errCnt; + //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); + int lastBit = 0; //set first clock check + uint32_t bitnum = 0; //output counter + uint8_t tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave + if (*clk==32)tol=1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely + uint32_t iii = 0; + uint32_t gLen = *bitLen; + if (gLen > 500) gLen=500; + uint8_t errCnt =0; + uint32_t bestStart = *bitLen; + uint32_t bestErrCnt = (*bitLen/1000); + uint8_t midBit=0; + //PrintAndLog("DEBUG - lastbit - %d",lastBit); + //loop to find first wave that works + for (iii=0; iii < gLen; ++iii){ + if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ + lastBit=iii-*clk; + //loop through to see if this start location works + for (i = iii; i < *bitLen; ++i) { + if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ + lastBit+=*clk; + BitStream[bitnum] = *invert; + bitnum++; + midBit=0; + } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + BitStream[bitnum] = 1-*invert; + bitnum++; + midBit=0; + } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ + //mid bar? + midBit=1; + BitStream[bitnum]= 1-*invert; + bitnum++; + } else if ((BinStream[i]>=high)&&(midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ + //mid bar? + midBit=1; + BitStream[bitnum]= *invert; + bitnum++; + } else if ((i-lastBit)>((*clk/2)+tol)&&(midBit==0)){ + //no mid bar found + midBit=1; + BitStream[bitnum]= BitStream[bitnum-1]; + bitnum++; + } else { + //mid value found or no bar supposed to be here + + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! + //debug + //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit); + if (bitnum > 0){ + BitStream[bitnum]=77; + bitnum++; + } + + + errCnt++; + lastBit+=*clk;//skip over until hit too many errors + if (errCnt>((*bitLen/1000))){ //allow 1 error for every 1000 samples else start over + errCnt=0; + bitnum=0;//start over + break; + } + } + } + if (bitnum>500) break; + } + //we got more than 64 good bits and not all errors + if ((bitnum > (64+errCnt)) && (errCnt<(*bitLen/1000))) { + //possible good read + if (errCnt==0) break; //great read - finish + if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish + if (errCnt=gLen){ //exhausted test + //if there was a ok test go back to that one and re-run the best run (then dump after that run) + if (bestErrCnt < (*bitLen/1000)) iii=bestStart; + } + } + if (bitnum>16){ + + // PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); + //move BitStream back to BinStream + // ClearGraph(0); + for (i=0; i < bitnum; ++i){ + BinStream[i]=BitStream[i]; + } + *bitLen=bitnum; + // RepaintGraphWindow(); + //output + // if (errCnt>0){ + // PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + // } + // PrintAndLog("ASK decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + // printBitStream2(BitStream,bitnum); + //int errCnt=0; + //errCnt=manrawdemod(BitStream,bitnum); + + // Em410xDecode(Cmd); + } else return -1; + return errCnt; } //translate wave to 11111100000 (1 for each short wave 0 for each long wave) size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow) { - uint32_t last_transition = 0; - uint32_t idx = 1; - uint32_t maxVal = 0; - - if (fchigh == 0) fchigh = 10; - if (fclow == 0) fclow = 8; - - // we do care about the actual theshold value as sometimes near the center of the - // wave we may get static that changes direction of wave for one value - // if our value is too low it might affect the read. and if our tag or - // antenna is weak a setting too high might not see anything. [marshmellow] - if ( size < 100) - return 0; - - // Find high from first 100 samples - for ( idx = 1; idx < 100; idx++ ){ - if ( maxVal < dest[idx]) - maxVal = dest[idx]; - } - + uint32_t last_transition = 0; + uint32_t idx = 1; + uint32_t maxVal=0; + if (fchigh==0) fchigh=10; + if (fclow==0) fclow=8; + // we do care about the actual theshold value as sometimes near the center of the + // wave we may get static that changes direction of wave for one value + // if our value is too low it might affect the read. and if our tag or + // antenna is weak a setting too high might not see anything. [marshmellow] + if (size<100) return 0; + for(idx=1; idx<100; idx++){ + if(maxVal1 transition - if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition - if ( ( idx - last_transition ) <( fclow - 2 ) ) { //0-5 = garbage noise - //do nothing with extra garbage - } else if ((idx - last_transition) < ( fchigh - 1 )) { //6-8 = 8 waves - dest[numBits]=1; - } else { //9+ = 10 waves - dest[numBits]=0; - } - last_transition = idx; - numBits++; - } - } - //it returns the number of bytes, but each byte represents a bit: 1 or 0 - return numBits; + if(dest[0] < threshold_value) dest[0] = 0; + else dest[0] = 1; + + size_t numBits = 0; + // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8) + // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere + // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10 + for(idx = 1; idx < size; idx++) { + // threshold current value + + if (dest[idx] < threshold_value) dest[idx] = 0; + else dest[idx] = 1; + + // Check for 0->1 transition + if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition + if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise + //do nothing with extra garbage + } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves + dest[numBits]=1; + } else { //9+ = 10 waves + dest[numBits]=0; + } + last_transition = idx; + numBits++; + } + } + return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 } uint32_t myround2(float f) { - if (f >= 2000) return 2000;//something bad happened - return (uint32_t) (f + (float)0.5); + if (f >= 2000) return 2000;//something bad happened + return (uint32_t) (f + (float)0.5); } //translate 11111100000 to 10 -size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert, uint8_t fchigh, uint8_t fclow ) +size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert,uint8_t fchigh,uint8_t fclow )// uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, { - uint8_t lastval = dest[0]; - uint32_t idx = 0; - uint32_t n = 1; - size_t numBits = 0; + uint8_t lastval=dest[0]; + uint32_t idx=0; + size_t numBits=0; + uint32_t n=1; - for( idx = 1; idx < size; idx++) { + for( idx=1; idx < size; idx++) { - if (dest[idx] == lastval) { - n++; - continue; - } - //if lastval was 1, we have a 1->0 crossing - if ( dest[idx-1] == 1 ) { - n = myround2( (float)( n + 1 ) / ((float)(rfLen)/(float)fclow)); - } else { // 0->1 crossing - n = myround2( (float)( n + 1 ) / ((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor - } - if (n == 0) n = 1; + if (dest[idx]==lastval) { + n++; + continue; + } + //if lastval was 1, we have a 1->0 crossing + if ( dest[idx-1]==1 ) { + n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow)); + //n=(n+1) / h2l_crossing_value; + } else {// 0->1 crossing + n=myround2((float)(n+1)/((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor + //n=(n+1) / l2h_crossing_value; + } + if (n == 0) n = 1; - if(n < maxConsequtiveBits) //Consecutive - { - if(invert == 0){ //invert bits - memset(dest+numBits, dest[idx-1] , n); - }else{ - memset(dest+numBits, dest[idx-1]^1 , n); - } - numBits += n; - } - n = 0; - lastval = dest[idx]; - }//end for - return numBits; + if(n < maxConsequtiveBits) //Consecutive + { + if(invert==0){ //invert bits + memset(dest+numBits, dest[idx-1] , n); + }else{ + memset(dest+numBits, dest[idx-1]^1 , n); + } + numBits += n; + } + n=0; + lastval=dest[idx]; + }//end for + return numBits; } - //by marshmellow (from holiman's base) // full fsk demod from GraphBuffer wave to decoded 1s and 0s (no mandemod) int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow) { - // FSK demodulator - size = fsk_wave_demod(dest, size, fchigh, fclow); - if ( size > 0 ) - size = aggregate_bits(dest, size, rfLen, 192, invert, fchigh, fclow); - return size; + // FSK demodulator + size = fsk_wave_demod(dest, size, fchigh, fclow); + size = aggregate_bits(dest, size,rfLen,192,invert,fchigh,fclow); + return size; } - // loop to get raw HID waveform then FSK demodulate the TAG ID from it int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo) { - size_t idx = 0; - int numshifts = 0; - // FSK demodulator - size = fskdemod(dest, size, 50, 0, 10, 8); + size_t idx=0; //, found=0; //size=0, + // FSK demodulator + size = fskdemod(dest, size,50,0,10,8); - // final loop, go over previously decoded manchester data and decode into usable tag ID - // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 - uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; - - uint8_t mask_len = sizeof frame_marker_mask / sizeof frame_marker_mask[0]; - - //one scan - while( idx + mask_len < size) { - // search for a start of frame marker - if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { // frame marker found - idx += mask_len; - while(dest[idx] != dest[idx+1] && idx < size-2) - { - // Keep going until next frame marker (or error) - // Shift in a bit. Start by shifting high registers - *hi2 = ( *hi2 << 1 ) | ( *hi >> 31 ); - *hi = ( *hi << 1 ) | ( *lo >> 31 ); - //Then, shift in a 0 or one into low - if (dest[idx] && !dest[idx+1]) // 1 0 - *lo = ( *lo << 1 ) | 0; - else // 0 1 - *lo = ( *lo << 1 ) | 1; - numshifts++; - idx += 2; - } - // Hopefully, we read a tag and hit upon the next frame marker - if(idx + mask_len < size) - { - if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { - //good return - return idx; - } - } - // reset - *hi2 = *hi = *lo = 0; - numshifts = 0; - }else { - idx++; - } - } - return -1; + // final loop, go over previously decoded manchester data and decode into usable tag ID + // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 + uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; + int numshifts = 0; + idx = 0; + //one scan + while( idx + sizeof(frame_marker_mask) < size) { + // search for a start of frame marker + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=sizeof(frame_marker_mask); + while(dest[idx] != dest[idx+1] && idx < size-2) + { + // Keep going until next frame marker (or error) + // Shift in a bit. Start by shifting high registers + *hi2 = (*hi2<<1)|(*hi>>31); + *hi = (*hi<<1)|(*lo>>31); + //Then, shift in a 0 or one into low + if (dest[idx] && !dest[idx+1]) // 1 0 + *lo=(*lo<<1)|0; + else // 0 1 + *lo=(*lo<<1)|1; + numshifts++; + idx += 2; + } + // Hopefully, we read a tag and hit upon the next frame marker + if(idx + sizeof(frame_marker_mask) < size) + { + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { + //good return + return idx; + } + } + // reset + *hi2 = *hi = *lo = 0; + numshifts = 0; + }else { + idx++; + } + } + return -1; } -uint32_t bytebits_to_byte(uint8_t *src, int numbits) +uint32_t bytebits_to_byte(uint8_t* src, int numbits) { - //HACK: potential overflow in numbits is larger then uint32 bits. - - uint32_t num = 0; - for(int i = 0 ; i < numbits ; ++i) { - num = (num << 1) | (*src); - src++; - } - return num; + uint32_t num = 0; + for(int i = 0 ; i < numbits ; i++) + { + num = (num << 1) | (*src); + src++; + } + return num; } int IOdemodFSK(uint8_t *dest, size_t size) { - //make sure buffer has data - if (size < 100) return -1; - - uint32_t idx = 0; - uint8_t testMax = 0; - - //test samples are not just noise - for (; idx < 65; ++idx ){ - if (testMax < dest[idx]) - testMax = dest[idx]; - } - - //if not, just noise - if (testMax < 20) return -2; - - // FSK demodulator - size = fskdemod(dest, size, 64, 1, 10, 8); // RF/64 and invert - - //did we get a good demod? - if (size < 65) return -3; - - //Index map - //0 10 20 30 40 50 60 - //| | | | | | | - //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 - //----------------------------------------------------------------------------- - //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 - // - //XSF(version)facility:codeone+codetwo - //Handle the data - - uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1}; - - for( idx = 0; idx < (size - 65); ++idx) { - if ( memcmp(dest + idx, mask, sizeof(mask))==0) { - //frame marker found - if (!dest[idx+8] && - dest[idx+17] == 1 && - dest[idx+26] == 1 && - dest[idx+35] == 1 && - dest[idx+44] == 1 && - dest[idx+53] == 1){ - //confirmed proper separator bits found - //return start position - return (int) idx; - } - } - } - return 0; + uint32_t idx=0; + //make sure buffer has data + if (size < 66) return -1; + //test samples are not just noise + uint8_t testMax=0; + for(idx=0;idx<65;idx++){ + if (testMax20){ + // FSK demodulator + size = fskdemod(dest, size,64,1,10,8); // RF/64 and invert + if (size < 65) return -1; //did we get a good demod? + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- + //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 + // + //XSF(version)facility:codeone+codetwo + //Handle the data + uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1}; + for( idx=0; idx < (size - 65); idx++) { + if ( memcmp(dest + idx, mask, sizeof(mask))==0) { + //frame marker found + if (!dest[idx+8] && dest[idx+17]==1 && dest[idx+26]==1 && dest[idx+35]==1 && dest[idx+44]==1 && dest[idx+53]==1){ + //confirmed proper separator bits found + //return start position + return (int) idx; + } + } + } + } + return 0; } // by marshmellow @@ -665,86 +635,67 @@ int IOdemodFSK(uint8_t *dest, size_t size) // maybe somehow adjust peak trimming value based on samples to fix? int DetectASKClock(uint8_t dest[], size_t size, int clock) { - int i = 0; - int clk[] = {16,32,40,50,64,100,128,256}; - uint8_t clkLen = sizeof clk / sizeof clk[0]; - - //if we already have a valid clock quit - for (; i < clkLen; ++i) - if (clk[i] == clock) - return clock; - - int peak = 0; - int low = 128; - int loopCnt = 256; - if (size < loopCnt) - loopCnt = size; - - //get high and low peak - for ( i = 0; i < loopCnt; ++i ){ - if(dest[i] > peak) - peak = dest[i]; - if(dest[i] < low) - low = dest[i]; - } + int i=0; + int peak=0; + int low=128; + int clk[]={16,32,40,50,64,100,128,256}; + int loopCnt = 256; //don't need to loop through entire array... + if (size low)) - continue; - - errCnt[cnt] = 0; - - // now that we have the first one lined up test rest of wave array - for ( i = 0; i < ((int)(size / clk[cnt]) - 1); ++i){ - - tmpIndex = ii + (i * clk[cnt] ); - tmplow = dest[ tmpIndex - tol]; - tmphigh = dest[ tmpIndex + tol]; - - if ( dest[tmpIndex] >= peak || dest[tmpIndex] <= low ) { - } - else if ( tmplow >= peak || tmplow <= low){ - } - else if ( tmphigh >= peak || tmphigh <= low){ - } - else - errCnt[cnt]++; //error no peak detected - } - - //if we found no errors this is correct one - return this clock - if ( errCnt[cnt] == 0 ) - return clk[cnt]; - - if ( errCnt[cnt] < bestErr) - bestErr = errCnt[cnt]; - } - // save the least error. - errCnt[cnt] = bestErr; - } - // find best clock which has lowest number of errors - int j = 0, bestIndex = 0; - for (; j < clkLen; ++j){ - if ( errCnt[j] < errCnt[bestIndex] ) - bestIndex = j; - } - return clk[bestIndex]; + //get high and low peak + for (i=0;ipeak){ + peak = dest[i]; + } + if(dest[i]=peak) || (dest[ii]<=low)){ + errCnt[clkCnt]=0; + // now that we have the first one lined up test rest of wave array + for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ + if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ + }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ + }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ + }else{ //error no peak detected + errCnt[clkCnt]++; + } + } + //if we found no errors this is correct one - return this clock + if(errCnt[clkCnt]==0) return clk[clkCnt]; + //if we found errors see if it is lowest so far and save it as best run + if(errCnt[clkCnt] (b)) ? (a) : (b)) @@ -223,6 +223,7 @@ byte_t btReceiveBank = AT91C_UDP_RX_DATA_BK0; void usb_disable() { // Disconnect the USB device AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU; +// SpinDelay(100); // Clear all lingering interrupts if(pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) { @@ -235,31 +236,32 @@ void usb_disable() { //* \brief This function Activates the USB device //*---------------------------------------------------------------------------- void usb_enable() { - // Set the PLL USB Divider - AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ; - - // Specific Chip USB Initialisation - // Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock - AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP; - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP); - - // Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO - // Set in PIO mode and Configure in Output - AT91C_BASE_PIOA->PIO_PER = GPIO_USB_PU; // Set in PIO mode + // Set the PLL USB Divider + AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ; + + // Specific Chip USB Initialisation + // Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock + AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP; + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP); + + // Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO + // Set in PIO mode and Configure in Output + AT91C_BASE_PIOA->PIO_PER = GPIO_USB_PU; // Set in PIO mode AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; // Configure as Output - - // Clear for set the Pullup resistor + + // Clear for set the Pullup resistor AT91C_BASE_PIOA->PIO_CODR = GPIO_USB_PU; + + // Disconnect and reconnect USB controller for 100ms + usb_disable(); + + // Wait for a short while + for (volatile size_t i=0; i<0x100000; i++); +// SpinDelay(100); - // Disconnect and reconnect USB controller for 100ms - usb_disable(); - - // Wait for a short while - for (volatile size_t i=0; i<0x100000; i++); - - // Reconnect USB reconnect - AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU; - AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; + // Reconnect USB reconnect + AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU; + AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; } //*---------------------------------------------------------------------------- @@ -298,26 +300,28 @@ bool usb_poll() //* \brief Read available data from Endpoint OUT //*---------------------------------------------------------------------------- uint32_t usb_read(byte_t* data, size_t len) { - byte_t bank = btReceiveBank; + byte_t bank = btReceiveBank; uint32_t packetSize, nbBytesRcv = 0; - uint32_t time_out = 0; + uint32_t time_out = 0; - while (len) { + while (len) + { if (!usb_check()) break; if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) { packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len); - len -= packetSize; + len -= packetSize; while(packetSize--) data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT]; pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(bank); - if (bank == AT91C_UDP_RX_DATA_BK0) { + if (bank == AT91C_UDP_RX_DATA_BK0) + { bank = AT91C_UDP_RX_DATA_BK1; - } else { + } else { bank = AT91C_UDP_RX_DATA_BK0; - } + } } - if (time_out++ == 0x1fff) break; + if (time_out++ == 0x1fff) break; } btReceiveBank = bank; @@ -349,7 +353,7 @@ uint32_t usb_write(const byte_t* data, const size_t len) { // Wait for the the first bank to be sent while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) { if (!usb_check()) return length; - } + } pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP); while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP); pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY; diff --git a/common/usb_cdc.h b/common/usb_cdc.h index b6489937..d7b9c2e5 100644 --- a/common/usb_cdc.h +++ b/common/usb_cdc.h @@ -35,7 +35,7 @@ #ifndef _USB_CDC_H_ #define _USB_CDC_H_ -#include "../include/common.h" +#include void usb_disable(); void usb_enable(); diff --git a/cp2tau b/cp2tau deleted file mode 100644 index 8b6ee4b4..00000000 --- a/cp2tau +++ /dev/null @@ -1,4 +0,0 @@ -cp armsrc/obj/*.elf /z -cp armsrc/obj/*.s19 /z -cp bootrom/obj/*.elf /z -cp bootrom/obj/*.s19 /z diff --git a/iceman.txt b/iceman.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/include/at91sam7s512.h b/include/at91sam7s512.h index 2cdcbce3..5be13622 100644 --- a/include/at91sam7s512.h +++ b/include/at91sam7s512.h @@ -428,7 +428,7 @@ typedef struct _AT91S_PIO { #define PIO_PDR (AT91_CAST(AT91_REG *) 0x00000004) // (PIO_PDR) PIO Disable Register #define PIO_PSR (AT91_CAST(AT91_REG *) 0x00000008) // (PIO_PSR) PIO Status Register #define PIO_OER (AT91_CAST(AT91_REG *) 0x00000010) // (PIO_OER) Output Enable Register -#define PIO_ODR (AT91_CAST(AT91_REG *) 0x00000014) // (PIO_ODR) Output Disable Register +#define PIO_ODR (AT91_CAST(AT91_REG *) 0x00000014) // (PIO_ODR) Output Disable Registerr #define PIO_OSR (AT91_CAST(AT91_REG *) 0x00000018) // (PIO_OSR) Output Status Register #define PIO_IFER (AT91_CAST(AT91_REG *) 0x00000020) // (PIO_IFER) Input Filter Enable Register #define PIO_IFDR (AT91_CAST(AT91_REG *) 0x00000024) // (PIO_IFDR) Input Filter Disable Register diff --git a/include/crc.h.old b/include/crc.h.old deleted file mode 100644 index 8e68f3b3..00000000 --- a/include/crc.h.old +++ /dev/null @@ -1,48 +0,0 @@ -//----------------------------------------------------------------------------- -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// Generic CRC calculation code. -//----------------------------------------------------------------------------- - -#ifndef __CRC_H -#define __CRC_H - -#include - -typedef struct crc { - uint32_t state; - int order; - uint32_t polynom; - uint32_t initial_value; - uint32_t final_xor; - uint32_t mask; -} crc_t; - -/* Initialize a crc structure. order is the order of the polynom, e.g. 32 for a CRC-32 - * polynom is the CRC polynom. initial_value is the initial value of a clean state. - * final_xor is XORed onto the state before returning it from crc_result(). */ -extern void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor); - -/* Update the crc state. data is the data of length data_width bits (only the the - * data_width lower-most bits are used). - */ -extern void crc_update(crc_t *crc, uint32_t data, int data_width); - -/* Clean the crc state, e.g. reset it to initial_value */ -extern void crc_clear(crc_t *crc); - -/* Get the result of the crc calculation */ -extern uint32_t crc_finish(crc_t *crc); - -/* Static initialization of a crc structure */ -#define CRC_INITIALIZER(_order, _polynom, _initial_value, _final_xor) { \ - .state = ((_initial_value) & ((1L<<(_order))-1)), \ - .order = (_order), \ - .polynom = (_polynom), \ - .initial_value = (_initial_value), \ - .final_xor = (_final_xor), \ - .mask = ((1L<<(_order))-1) } - -#endif /* __CRC_H */ diff --git a/include/mifare.h b/include/mifare.h index 403132ac..e2b7a7c5 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -11,7 +11,7 @@ #ifndef _MIFARE_H_ #define _MIFARE_H_ -#include "../include/common.h" +#include "common.h" //----------------------------------------------------------------------------- // ISO 14443A diff --git a/include/proxmark3.h b/include/proxmark3.h index b3530c64..8c9417da 100644 --- a/include/proxmark3.h +++ b/include/proxmark3.h @@ -14,7 +14,6 @@ // Might as well have the hardware-specific defines everywhere. #include "at91sam7s512.h" #include "config_gpio.h" -#include "usb_cmd.h" #define WDT_HIT() AT91C_BASE_WDTC->WDTC_WDCR = 0xa5000001 @@ -68,6 +67,8 @@ #define TRUE 1 #define FALSE 0 +#include + //#define PACKED __attribute__((__packed__)) #define LED_A_ON() HIGH(GPIO_LED_A) diff --git a/include/usb_cmd.h b/include/usb_cmd.h index ecdf8ac1..69c3c1b6 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -115,12 +115,11 @@ typedef struct { #define CMD_READER_LEGIC_RF 0x0388 #define CMD_WRITER_LEGIC_RF 0x0389 #define CMD_EPA_PACE_COLLECT_NONCE 0x038A -//#define CMD_EPA_ 0x038B #define CMD_SNOOP_ICLASS 0x0392 #define CMD_SIMULATE_TAG_ICLASS 0x0393 #define CMD_READER_ICLASS 0x0394 -#define CMD_READER_ICLASS_REPLAY 0x0395 +#define CMD_READER_ICLASS_REPLAY 0x0395 #define CMD_ICLASS_ISO14443A_WRITE 0x0397 // For measurements of the antenna tuning @@ -150,11 +149,9 @@ typedef struct { #define CMD_MIFARE_NESTED 0x0612 #define CMD_MIFARE_READBL 0x0620 -#define CMD_MIFAREU_READBL 0x0720 - +#define CMD_MIFAREU_READBL 0x0720 #define CMD_MIFARE_READSC 0x0621 -#define CMD_MIFAREU_READCARD 0x0721 - +#define CMD_MIFAREU_READCARD 0x0721 #define CMD_MIFARE_WRITEBL 0x0622 #define CMD_MIFAREU_WRITEBL 0x0722 #define CMD_MIFAREU_WRITEBL_COMPAT 0x0723 @@ -187,7 +184,7 @@ typedef struct { //Iclass reader flags -#define FLAG_ICLASS_READER_ONLY_ONCE 0x01 +#define FLAG_ICLASS_READER_ONLY_ONCE 0x01 #define FLAG_ICLASS_READER_GET_CC 0x02 // CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions: diff --git a/tools/mkversion.pl b/tools/mkversion.pl index e12dd447..19616441 100644 --- a/tools/mkversion.pl +++ b/tools/mkversion.pl @@ -16,7 +16,7 @@ my $gitbranch = `git rev-parse --abbrev-ref HEAD`; my $clean = 2; my @compiletime = gmtime(); -my $fullgitinfo = 'iceman' . $gitbranch . '/' . $gitversion; +my $fullgitinfo = $gitbranch . '/' . $gitversion; $fullgitinfo =~ s/(\s)//g;