Merge pull request #65 from RfidResearchGroup/master

Update from RRG
This commit is contained in:
mwalker33 2021-03-08 09:15:06 +11:00 committed by GitHub
commit 75cf52e0f2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 1245 additions and 1008 deletions

View file

@ -19,7 +19,7 @@
#define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC #define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC
#define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these #define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these
#define CARD_MEMORY_SIZE 4096 #define CARD_MEMORY_SIZE 4096
#define DMA_BUFFER_SIZE 256 #define DMA_BUFFER_SIZE 512
// 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits // 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) #define TOSEND_BUFFER_SIZE (9 * MAX_FRAME_SIZE + 1 + 1 + 2)

View file

@ -2202,6 +2202,10 @@ static void PacketReceived(PacketCommandNG *packet) {
Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable(); Flash_WriteEnable();
Flash_Erase4k(3, 0xB); Flash_Erase4k(3, 0xB);
} else if (startidx == FLASH_MEM_SIGNATURE_OFFSET) {
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
Flash_Erase4k(3, 0xF);
} }
res = Flash_Write(startidx, data, len); res = Flash_Write(startidx, data, len);

View file

@ -53,13 +53,21 @@ static bool bCollision;
static bool bPwd; static bool bPwd;
static bool bSuccessful; static bool bSuccessful;
/*
Password Mode : 0x06 - 0000 0110
Crypto Mode : 0x0E - 0000 1110
Public Mode A : 0x02 - 0000 0010
Public Mode B : 0x00 - 0000 0000
Public Mode C : 0x04 - 0000 0100
*/
static struct hitag2_tag tag = { static struct hitag2_tag tag = {
.state = TAG_STATE_RESET, .state = TAG_STATE_RESET,
.sectors = { // Password mode: | Crypto mode: .sectors = { // Password mode: | Crypto mode:
[0] = { 0x02, 0x4e, 0x02, 0x20}, // UID | UID [0] = { 0x02, 0x4e, 0x02, 0x20}, // UID | UID
[1] = { 0x4d, 0x49, 0x4b, 0x52}, // Password RWD | 32 bit LSB key [1] = { 0x4d, 0x49, 0x4b, 0x52}, // Password RWD | 32 bit LSB key
[2] = { 0x20, 0xf0, 0x4f, 0x4e}, // Reserved | 16 bit MSB key, 16 bit reserved [2] = { 0x20, 0xf0, 0x4f, 0x4e}, // Reserved | 16 bit MSB key, 16 bit reserved
[3] = { 0x0e, 0xaa, 0x48, 0x54}, // Configuration, password TAG | Configuration, password TAG [3] = { 0x06, 0xaa, 0x48, 0x54}, // Configuration, password TAG | Configuration, password TAG
[4] = { 0x46, 0x5f, 0x4f, 0x4b}, // Data: F_OK [4] = { 0x46, 0x5f, 0x4f, 0x4b}, // Data: F_OK
[5] = { 0x55, 0x55, 0x55, 0x55}, // Data: UUUU [5] = { 0x55, 0x55, 0x55, 0x55}, // Data: UUUU
[6] = { 0xaa, 0xaa, 0xaa, 0xaa}, // Data: .... [6] = { 0xaa, 0xaa, 0xaa, 0xaa}, // Data: ....
@ -91,7 +99,7 @@ static uint8_t key[8];
static uint8_t writedata[4]; static uint8_t writedata[4];
static uint8_t logdata_0[4], logdata_1[4]; static uint8_t logdata_0[4], logdata_1[4];
static uint8_t nonce[4]; static uint8_t nonce[4];
static bool key_no; static uint8_t key_no;
static uint64_t cipher_state; static uint64_t cipher_state;
static int16_t blocknr; static int16_t blocknr;
@ -375,16 +383,15 @@ static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len)
return wait; return wait;
} }
static uint8_t hitag_crc(uint8_t *data, size_t length) { static uint8_t hitag_crc(uint8_t *data, size_t n) {
uint8_t crc = 0xff; uint8_t crc = 0xFF;
unsigned int byte, bit; for (size_t i = 0; i < ((n + 7) / 8); i++) {
for (byte = 0; byte < ((length + 7) / 8); byte++) { crc ^= *(data + i);
crc ^= *(data + byte); uint8_t bit = n < (8 * (i + 1)) ? (n % 8) : 8;
bit = length < (8 * (byte + 1)) ? (length % 8) : 8;
while (bit--) { while (bit--) {
if (crc & 0x80) { if (crc & 0x80) {
crc <<= 1; crc <<= 1;
crc ^= 0x1d; crc ^= 0x1D;
} else { } else {
crc <<= 1; crc <<= 1;
} }
@ -414,7 +421,6 @@ void fix_ac_decoding(uint8_t *input, size_t len) {
// 0 = collision? // 0 = collision?
// 32 = good response // 32 = good response
static bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool hitag_s) { static bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool hitag_s) {
uint8_t crc;
*txlen = 0; *txlen = 0;
switch (rxlen) { switch (rxlen) {
case 0: { case 0: {
@ -435,6 +441,7 @@ static bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *tx
return true; return true;
} }
case 32: { case 32: {
uint8_t crc;
if (bCollision) { if (bCollision) {
// Select card by serial from response // Select card by serial from response
tx[0] = 0x00 | rx[0] >> 5; tx[0] = 0x00 | rx[0] >> 5;
@ -1001,7 +1008,6 @@ void SniffHitag2(void) {
g_logging = false; g_logging = false;
size_t periods = 0;
uint8_t periods_bytes[4]; uint8_t periods_bytes[4];
// int16_t checked = 0; // int16_t checked = 0;
@ -1010,7 +1016,7 @@ void SniffHitag2(void) {
LED_C_ON(); LED_C_ON();
uint32_t signal_size = 10000; uint32_t signal_size = 10000;
while (!BUTTON_PRESS()) { while (BUTTON_PRESS() == false) {
// use malloc // use malloc
initSampleBufferEx(&signal_size, false); initSampleBufferEx(&signal_size, false);
@ -1035,7 +1041,7 @@ void SniffHitag2(void) {
// lf_reset_counter(); // lf_reset_counter();
// Wait "infinite" for reader modulation // Wait "infinite" for reader modulation
periods = lf_detect_gap(10000); size_t periods = lf_detect_gap(10000);
// Test if we detected the first reader modulation edge // Test if we detected the first reader modulation edge
if (periods != 0) { if (periods != 0) {
@ -1070,9 +1076,7 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) {
int response = 0; int response = 0;
uint8_t rx[HITAG_FRAME_LEN] = {0}; uint8_t rx[HITAG_FRAME_LEN] = {0};
size_t rxlen = 0;
uint8_t tx[HITAG_FRAME_LEN] = {0}; uint8_t tx[HITAG_FRAME_LEN] = {0};
size_t txlen = 0;
auth_table_len = 0; auth_table_len = 0;
auth_table_pos = 0; auth_table_pos = 0;
@ -1106,10 +1110,8 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) {
Dbprintf("| %d | %08x |", i, block); Dbprintf("| %d | %08x |", i, block);
} }
uint8_t reader_modulation;
size_t max_nrzs = 8 * HITAG_FRAME_LEN + 5; size_t max_nrzs = 8 * HITAG_FRAME_LEN + 5;
uint8_t nrz_samples[max_nrzs]; uint8_t nrz_samples[max_nrzs];
size_t nrzs = 0, periods = 0;
// uint32_t command_start = 0, command_duration = 0; // uint32_t command_start = 0, command_duration = 0;
// int16_t checked = 0; // int16_t checked = 0;
@ -1139,8 +1141,7 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) {
} }
++checked; ++checked;
*/ */
size_t rxlen = 0, txlen = 0;
rxlen = 0;
// Keep administration of the first edge detection // Keep administration of the first edge detection
bool waiting_for_first_edge = true; bool waiting_for_first_edge = true;
@ -1149,14 +1150,14 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) {
bool detected_modulation = false; bool detected_modulation = false;
// Use the current modulation state as starting point // Use the current modulation state as starting point
reader_modulation = lf_get_reader_modulation(); uint8_t reader_modulation = lf_get_reader_modulation();
// Receive frame, watch for at most max_nrzs periods // Receive frame, watch for at most max_nrzs periods
// Reset the number of NRZ samples and use edge detection to detect them // Reset the number of NRZ samples and use edge detection to detect them
nrzs = 0; size_t nrzs = 0;
while (nrzs < max_nrzs) { while (nrzs < max_nrzs) {
// Get the timing of the next edge in number of wave periods // Get the timing of the next edge in number of wave periods
periods = lf_count_edge_periods(128); size_t periods = lf_count_edge_periods(128);
// Just break out of loop after an initial time-out (tag is probably not available) // Just break out of loop after an initial time-out (tag is probably not available)
// The function lf_count_edge_periods() returns 0 when a time-out occurs // The function lf_count_edge_periods() returns 0 when a time-out occurs
@ -1336,7 +1337,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
memset(logdata_1, 0x00, 4); memset(logdata_1, 0x00, 4);
byte_value = 0; byte_value = 0;
key_no = htd->ht1auth.key_no; key_no = htd->ht1auth.key_no;
DBG Dbprintf("Authenticating using key #%d:", key_no); DBG Dbprintf("Authenticating using key #%u :", key_no);
DBG Dbhexdump(4, key, false); DBG Dbhexdump(4, key, false);
DBG DbpString("Nonce:"); DBG DbpString("Nonce:");
DBG Dbhexdump(4, nonce, false); DBG Dbhexdump(4, nonce, false);

View file

@ -41,7 +41,7 @@
// defaults to 2000ms // defaults to 2000ms
#ifndef FWT_TIMEOUT_14B #ifndef FWT_TIMEOUT_14B
# define FWT_TIMEOUT_14B 35312 # define FWT_TIMEOUT_14B 35312U
#endif #endif
// 1 tick == 1/13.56 mhz // 1 tick == 1/13.56 mhz
@ -178,7 +178,7 @@ static void CodeIso14443bAsTag(const uint8_t *cmd, int len) {
// Send TR1. // Send TR1.
// 10-11 ETU * 4times samples ONES // 10-11 ETU * 4times samples ONES
for (i = 0; i < 20; i++) { for (i = 0; i < 10; i++) {
SEND4STUFFBIT(1); SEND4STUFFBIT(1);
} }
@ -321,7 +321,7 @@ static void Demod14bInit(uint8_t *data, uint16_t max_len) {
* @param timeout is in frame wait time, fwt, measured in ETUs * @param timeout is in frame wait time, fwt, measured in ETUs
*/ */
static void iso14b_set_timeout(uint32_t timeout) { static void iso14b_set_timeout(uint32_t timeout) {
#define MAX_TIMEOUT 40542464 // 13560000Hz * 1000ms / (2^32-1) * (8*16) #define MAX_TIMEOUT 40542464U // 13560000Hz * 1000ms / (2^32-1) * (8*16)
if (timeout > MAX_TIMEOUT) if (timeout > MAX_TIMEOUT)
timeout = MAX_TIMEOUT; timeout = MAX_TIMEOUT;

View file

@ -146,9 +146,9 @@ uint32_t usart_read_ng(uint8_t *data, size_t len) {
} }
len -= packetSize; len -= packetSize;
while (packetSize--) { while (packetSize--) {
data[bytes_rcv++] = us_rxfifo[us_rxfifo_low++];
if (us_rxfifo_low == sizeof(us_rxfifo)) if (us_rxfifo_low == sizeof(us_rxfifo))
us_rxfifo_low = 0; us_rxfifo_low = 0;
data[bytes_rcv++] = us_rxfifo[us_rxfifo_low++];
} }
if (try++ == maxtry) { if (try++ == maxtry) {
// Dbprintf_usb("Dbg USART TIMEOUT"); // Dbprintf_usb("Dbg USART TIMEOUT");

View file

@ -4639,11 +4639,13 @@ void arg_print_syntax(FILE *fp, void * *argtable, const char *suffix) {
/* print GNU style [OPTION] string */ /* print GNU style [OPTION] string */
arg_print_gnuswitch(fp, table); arg_print_gnuswitch(fp, table);
size_t len = 0;
/* print remaining options in abbreviated style */ /* print remaining options in abbreviated style */
for (tabindex = 0; for (tabindex = 0;
table[tabindex] && !(table[tabindex]->flag & ARG_TERMINATOR); table[tabindex] && !(table[tabindex]->flag & ARG_TERMINATOR);
tabindex++) { tabindex++) {
char syntax[200] = ""; char syntax[400] = "";
const char *shortopts, *longopts, *datatype; const char *shortopts, *longopts, *datatype;
/* skip short options without arg values (they were printed by arg_print_gnu_switch) */ /* skip short options without arg values (they were printed by arg_print_gnu_switch) */
@ -4681,6 +4683,12 @@ void arg_print_syntax(FILE *fp, void * *argtable, const char *suffix) {
break; break;
} }
} }
len += strlen(syntax);
if (len > 60) {
fprintf(fp, "\n ");
len = 0;
}
} }
if (suffix) if (suffix)

View file

@ -433,6 +433,9 @@ cc6b3b3cd263
157c9a513fa5 157c9a513fa5
e2a5dc8e066f e2a5dc8e066f
# #
# Data from forum, schlage 9691T fob
ef1232ab18a0
#
# Data from a oyster card # Data from a oyster card
374bf468607f 374bf468607f
bfc8e353af63 bfc8e353af63
@ -1293,3 +1296,75 @@ ff9a84635bd2
f1a1239a4487 f1a1239a4487
# #
b882fd4a9f78 b882fd4a9f78
CD7FFFF81C4A
AA0857C641A3
C8AACD7CF3D1
9FFDA233B496
26B85DCA4321
D4B2D140CB2D
A7395CCB42A0
541C417E57C0
D14E615E0545
69D92108C8B5
703265497350
D75971531042
10510049D725
35C649004000
5B0C7EC83645
05F5EC05133C
521B517352C7
94B6A644DFF6
2CA4A4D68B8E
A7765C952DDF
E2F14D0A0E28
DC018FC1D126
4927C97F1D57
046154274C11
155332417E00
6B13935CD550
C151D998C669
D973D917A4C7
130662240200
9386E2A48280
52750A0E592A
541C417E57C0
D14E615E0545
075D1A4DD323
32CA52054416
460661C93045
5429D67E1F57
0C734F230E13
1F0128447C00
411053C05273
42454C4C4147
C428C4550A75
730956C72BC2
28D70900734C
4F75030AD12B
6307417353C1
D65561530174
D1F71E05AD9D
F7FA2F629BB1
0E620691B9FE
43E69C28F08C
735175696421
424C0FFBF657
D01AFEEB890A
75CCB59C9BED
4B791BEA7BCC
51E97FFF51E9
E7316853E731
5C8FF9990DA2
00460740D722
35D152154017
5D0762D13401
0F35D5660653
1170553E4304
0C4233587119
F678905568C3
50240A68D1D8
69D92108C8B5
2E71D3BD262A
540D5E6355CC
D1417E431949
4BF6DE347FB6

View file

@ -20,7 +20,7 @@ The outlined procedure is as following:
-- manchester -- manchester
-- bit rate -- bit rate
"lf t55xx write b 0 d 00008040" "lf t55xx write -b 0 -d 00008040"
"lf t55xx detect" "lf t55xx detect"
"lf t55xx info" "lf t55xx info"
@ -118,7 +118,7 @@ local function test()
elseif _ == 1 then elseif _ == 1 then
local config = pcmd:format(config1, y, config2) local config = pcmd:format(config1, y, config2)
dbg(('lf t55xx write b 0 d %s'):format(config)) dbg(('lf t55xx write -b 0 -d %s'):format(config))
local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags) local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags)
local wc = Command:newNG{cmd = cmds.CMD_LF_T55XX_WRITEBL, data = data} local wc = Command:newNG{cmd = cmds.CMD_LF_T55XX_WRITEBL, data = data}

View file

@ -14,7 +14,7 @@ The outlined procedure is as following:
--BIPHASE 00010040 --BIPHASE 00010040
-- --
"lf t55xx write b 0 d 00010040" "lf t55xx write -b 0 -d 00010040"
"lf t55xx detect" "lf t55xx detect"
"lf t55xx info" "lf t55xx info"
@ -112,7 +112,7 @@ local function test()
elseif _ == 1 then elseif _ == 1 then
local config = pcmd:format(config1, y, config2) local config = pcmd:format(config1, y, config2)
dbg(('lf t55xx write b 0 d %s'):format(config)) dbg(('lf t55xx write -b 0 -d %s'):format(config))
local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags) local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags)

View file

@ -17,7 +17,7 @@ The outlined procedure is as following:
-- FSK1 -- FSK1
-- bit rate -- bit rate
"lf t55xx write b 0 d 00007040" "lf t55xx write -b 0 -d 00007040"
"lf t55xx detect" "lf t55xx detect"
"lf t55xx info" "lf t55xx info"
@ -114,7 +114,7 @@ local function test(modulation)
elseif _ == 1 then elseif _ == 1 then
local config = pcmd:format(config1, y, modulation, config2) local config = pcmd:format(config1, y, modulation, config2)
dbg(('lf t55xx write b 0 d %s'):format(config)) dbg(('lf t55xx write -b 0 -d %s'):format(config))
local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags) local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags)
local wc = Command:newNG{cmd = cmds.CMD_LF_T55XX_WRITEBL, data = data} local wc = Command:newNG{cmd = cmds.CMD_LF_T55XX_WRITEBL, data = data}

View file

@ -11,7 +11,7 @@ desc = [[
This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00088040 This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00088040
The outlined procedure is as following: The outlined procedure is as following:
"lf t55xx write b 0 d 00088040" "lf t55xx write -b 0 -d 00088040"
"lf t55xx detect" "lf t55xx detect"
"lf t55xx info" "lf t55xx info"
@ -118,7 +118,7 @@ local function test(modulation)
dbg('Writing to T55x7 TAG') dbg('Writing to T55x7 TAG')
local config = cmd:format(bitrate, modulation, clockrate) local config = cmd:format(bitrate, modulation, clockrate)
dbg(('lf t55xx write b 0 d %s'):format(config)) dbg(('lf t55xx write -b 0 -d %s'):format(config))
local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags) local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags)

View file

@ -17,10 +17,10 @@ It will then try to detect and read back those block data and compare if read da
lf t55xx wipe lf t55xx wipe
lf t55xx detect lf t55xx detect
lf t55xx write b 1 d 00000000 lf t55xx write -b 1 -d 00000000
lf t55xx write b 2 d ffffffff lf t55xx write -b 2 -d ffffffff
lf t55xx write b 3 d 80000000 lf t55xx write -b 3 -d 80000000
lf t55xx write b 4 d 00000001 lf t55xx write -b 4 -d 00000001
Loop: Loop:
@ -278,7 +278,7 @@ local function WipeCard()
core.console('rem [ERR:DETECT:WIPED] Failed to detect after wipe') core.console('rem [ERR:DETECT:WIPED] Failed to detect after wipe')
return false return false
else else
local wipe_data_cmd = 'lf t55xx write b %s d %s' local wipe_data_cmd = 'lf t55xx write -b %s -d %s'
for _ = 1, #data_blocks_cmds do for _ = 1, #data_blocks_cmds do
local val = data_blocks_cmds[_] local val = data_blocks_cmds[_]
local c = string.format(wipe_data_cmd, _, val) local c = string.format(wipe_data_cmd, _, val)
@ -321,7 +321,7 @@ local function test(modulation)
core.clearCommandBuffer() core.clearCommandBuffer()
-- Write Config block -- Write Config block
dbg(('lf t55xx write b 0 d %s'):format(p_config_cmd)) dbg(('lf t55xx write -b 0 -d %s'):format(p_config_cmd))
local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(p_config_cmd, 32), password, block, flags) local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(p_config_cmd, 32), password, block, flags)

View file

@ -39,7 +39,10 @@ static int CmdHelp(const char *Cmd);
"9337F21C0C066FFB703D8BFCB5067F309E056772096642C2B1A8F50305D5EC33" \ "9337F21C0C066FFB703D8BFCB5067F309E056772096642C2B1A8F50305D5EC33" \
"DB7FB5A3C8AC42EB635AE3C148C910750ABAA280CE82DC2F180F49F30A1393B5" "DB7FB5A3C8AC42EB635AE3C148C910750ABAA280CE82DC2F180F49F30A1393B5"
//-------------------------------------------------------------------------------------
// Sample private RSA Key
// Following example RSA-1024 keypair, for test purposes (from common/polarssl/rsa.c) // Following example RSA-1024 keypair, for test purposes (from common/polarssl/rsa.c)
// private key - Exponent D // private key - Exponent D
#define RSA_D "24BF6185468786FDD303083D25E64EFC" \ #define RSA_D "24BF6185468786FDD303083D25E64EFC" \
"66CA472BC44D253102F8B4A9D3BFA750" \ "66CA472BC44D253102F8B4A9D3BFA750" \
@ -136,7 +139,7 @@ static int rdv4_sign_write(uint8_t *signature, uint8_t slen){
if (!resp.oldarg[0]) { if (!resp.oldarg[0]) {
PrintAndLogEx(FAILED, "Writing signature ( "_RED_("fail") ")"); PrintAndLogEx(FAILED, "Writing signature ( "_RED_("fail") ")");
} else { } else {
PrintAndLogEx(SUCCESS, "Writing signature ( "_GREEN_("ok") " ) at offset %u", FLASH_MEM_SIGNATURE_OFFSET); PrintAndLogEx(SUCCESS, "Writing signature at offset %u ( "_GREEN_("ok") " )", FLASH_MEM_SIGNATURE_OFFSET);
return PM3_SUCCESS; return PM3_SUCCESS;
} }
} }
@ -445,29 +448,39 @@ static int CmdFlashMemInfo(const char *Cmd) {
CLIParserInit(&ctx, "mem info", CLIParserInit(&ctx, "mem info",
"Collect signature and verify it from flash memory", "Collect signature and verify it from flash memory",
"mem info" "mem info"
// "mem info -s" // "mem info -s -d 0102030405060708"
); );
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
// arg_lit0("s", NULL, "create a signature"), arg_lit0("s", "sign", "create a signature"),
// arg_lit0("w", NULL, "write signature to flash memory"), arg_str0("d", NULL, "<hex>", "flash memory id, 8 hex bytes"),
// arg_lit0("w", "write", "write signature to flash memory"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
bool shall_sign = false, shall_write = false; bool shall_sign = false, shall_write = false;
// shall_sign = arg_get_lit(ctx, 1); shall_sign = arg_get_lit(ctx, 1);
// shall_write = arg_get_lit(ctx, 2);
int dlen = 0;
uint8_t id[8] = {0};
int res = CLIParamHexToBuf(arg_get_str(ctx, 2), id, sizeof(id), &dlen);
// shall_write = arg_get_lit(ctx, 3);
CLIParserFree(ctx); CLIParserFree(ctx);
// validate signature data if (dlen > 0 && dlen < sizeof(id) ) {
PrintAndLogEx(FAILED, "Error parsing flash memory id, expect 8, got %d", dlen);
return PM3_EINVARG;
}
// validate devicesignature data
rdv40_validation_t mem; rdv40_validation_t mem;
int res = rdv4_get_signature(&mem); res = rdv4_get_signature(&mem);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
return res; return res;
} }
res = rdv4_validate(&mem); res = rdv4_validate(&mem);
// Flash ID hash (sha1) // Flash ID hash (sha1)
@ -479,6 +492,11 @@ static int CmdFlashMemInfo(const char *Cmd) {
PrintAndLogEx(INFO, "--- " _CYAN_("Flash memory Information") " ---------"); PrintAndLogEx(INFO, "--- " _CYAN_("Flash memory Information") " ---------");
PrintAndLogEx(INFO, "ID................... %s", sprint_hex_inrow(mem.flashid, sizeof(mem.flashid))); PrintAndLogEx(INFO, "ID................... %s", sprint_hex_inrow(mem.flashid, sizeof(mem.flashid)));
PrintAndLogEx(INFO, "SHA1................. %s", sprint_hex_inrow(sha_hash, sizeof(sha_hash))); PrintAndLogEx(INFO, "SHA1................. %s", sprint_hex_inrow(sha_hash, sizeof(sha_hash)));
PrintAndLogEx(
(res == PM3_SUCCESS) ? SUCCESS : FAILED,
"Signature............ ( %s )",
(res == PM3_SUCCESS) ? _GREEN_("ok") : _RED_("fail")
);
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("RDV4 RSA signature") " ---------------"); PrintAndLogEx(INFO, "--- " _CYAN_("RDV4 RSA signature") " ---------------");
for (int i = 0; i < (sizeof(mem.signature) / 32); i++) { for (int i = 0; i < (sizeof(mem.signature) / 32); i++) {
@ -520,13 +538,21 @@ static int CmdFlashMemInfo(const char *Cmd) {
PrintAndLogEx(INFO, " %.64s", str_pk + 192); PrintAndLogEx(INFO, " %.64s", str_pk + 192);
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
bool is_keyok = (mbedtls_rsa_check_pubkey(&rsa) == 0 || mbedtls_rsa_check_privkey(&rsa) == 0); bool is_keyok = (mbedtls_rsa_check_pubkey(&rsa) == 0);
PrintAndLogEx( PrintAndLogEx(
(is_keyok) ? SUCCESS : FAILED, (is_keyok) ? SUCCESS : FAILED,
"RSA key validation... ( %s )", "RSA public key validation.... ( %s )",
(is_keyok) ? _GREEN_("ok") : _RED_("fail") (is_keyok) ? _GREEN_("ok") : _RED_("fail")
); );
is_keyok = (mbedtls_rsa_check_privkey(&rsa) == 0);
PrintAndLogEx(
(is_keyok) ? SUCCESS : FAILED,
"RSA private key validation... ( %s )",
(is_keyok) ? _GREEN_("ok") : _RED_("fail")
);
// to be verified // to be verified
uint8_t from_device[RRG_RSA_KEY_LEN]; uint8_t from_device[RRG_RSA_KEY_LEN];
memcpy(from_device, mem.signature, RRG_RSA_KEY_LEN); memcpy(from_device, mem.signature, RRG_RSA_KEY_LEN);
@ -537,6 +563,13 @@ static int CmdFlashMemInfo(const char *Cmd) {
// Signing (private key) // Signing (private key)
if (shall_sign) { if (shall_sign) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("Enter signing") " --------------------");
if (dlen == 8) {
mbedtls_sha1(id, sizeof(id), sha_hash);
}
PrintAndLogEx(INFO, "Signing %s", sprint_hex_inrow(sha_hash, sizeof(sha_hash)));
int is_signed = mbedtls_rsa_pkcs1_sign(&rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 20, sha_hash, sign); int is_signed = mbedtls_rsa_pkcs1_sign(&rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 20, sha_hash, sign);
PrintAndLogEx( PrintAndLogEx(
@ -555,14 +588,17 @@ static int CmdFlashMemInfo(const char *Cmd) {
} }
// Verify (public key) // Verify (public key)
int is_verified = mbedtls_rsa_pkcs1_verify(&rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 20, sha_hash, from_device); bool is_verified = (mbedtls_rsa_pkcs1_verify(&rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 20, sha_hash, from_device) == 0);
mbedtls_rsa_free(&rsa); mbedtls_rsa_free(&rsa);
PrintAndLogEx( PrintAndLogEx(
(is_verified == 0) ? SUCCESS : FAILED, (is_verified) ? SUCCESS : FAILED,
"RSA verification..... ( %s )", "RSA verification..... ( %s )",
(is_verified == 0) ? _GREEN_("ok") : _RED_("fail") (is_verified) ? _GREEN_("ok") : _RED_("fail")
); );
if (is_verified) {
PrintAndLogEx(SUCCESS, "Genuine Proxmark3 RDV4 signature detected");
}
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS; return PM3_SUCCESS;

View file

@ -23,6 +23,8 @@
#include "mifare/ndef.h" #include "mifare/ndef.h"
#include "cliparser.h" #include "cliparser.h"
#include "cmdmain.h" #include "cmdmain.h"
#include "amiibo.h" // amiiboo fcts
#include "base64.h"
#define MAX_UL_BLOCKS 0x0F #define MAX_UL_BLOCKS 0x0F
#define MAX_ULC_BLOCKS 0x2F #define MAX_ULC_BLOCKS 0x2F
@ -3717,6 +3719,13 @@ static int CmdHF14AMfuEv1CounterTearoff(const char *Cmd) {
*/ */
//
// name, identifying bytes, decode function, hints text
// identifying bits
// 1. getversion data must match.
// 2. magic bytes in the readable payload
static int CmdHF14MfuNDEF(const char *Cmd) { static int CmdHF14MfuNDEF(const char *Cmd) {
int keylen; int keylen;
@ -3845,6 +3854,25 @@ static int CmdHF14MfuNDEF(const char *Cmd) {
} }
} }
} }
char *mattel = strstr((char*)records, ".pid.mattel/");
if (mattel) {
mattel += 12;
while (mattel) {
if ((*mattel) != '/')
mattel++;
else {
mattel++;
char b64[33] = {0};
strncpy(b64, mattel, 32);
uint8_t arr[24] = {0};
size_t arrlen = 0;
mbedtls_base64_decode(arr, sizeof(arr), &arrlen, (const unsigned char *)b64, 32);
PrintAndLogEx(INFO, "decoded... %s", sprint_hex(arr, arrlen));
break;
}
}
}
free(records); free(records);
return status; return status;
@ -3893,17 +3921,57 @@ static int CmdHF14AMfuEView(const char *Cmd) {
return PM3_SUCCESS; return PM3_SUCCESS;
} }
/*
static int CmdHF14AMfUCDecryptAmiibo(const char *Cmd){
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfu decrypt",
"Tries to read all memory from amiibo tag and decrypt it",
"hf mfu decrypt"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
uint16_t elen = 0, dlen = 0;
uint8_t *encrypted = NULL;
int res = mfu_dump_tag( MAX_NTAG_215, (void **)&encrypted, &elen);
if (res == PM3_SUCCESS) {
PrintAndLogEx(INFO, "32 first bytes of tag dump");
PrintAndLogEx(INFO, "%s", sprint_hex(encrypted, 32));
PrintAndLogEx(INFO, "-----------------------");
uint8_t decrypted[NFC3D_AMIIBO_SIZE] = {0};
res = mfu_decrypt_amiibo(encrypted, elen, decrypted, &dlen);
if ( res == PM3_SUCCESS) {
for (uint8_t i = 0; i < dlen/16; i++ ) {
PrintAndLogEx(INFO, "[%d] %s", i, sprint_hex_ascii(decrypted + (i * 16), 16));
}
}
free(encrypted);
}
return PM3_SUCCESS;
}
*/
//------------------------------------ //------------------------------------
// Menu Stuff // Menu Stuff
//------------------------------------ //------------------------------------
static command_t CommandTable[] = { static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"}, {"help", CmdHelp, AlwaysAvailable, "This help"},
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("recovery") " -----------------------"}, {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("recovery") " -------------------------"},
{"keygen", CmdHF14AMfUGenDiverseKeys, AlwaysAvailable, "Generate 3DES MIFARE diversified keys"}, {"keygen", CmdHF14AMfUGenDiverseKeys, AlwaysAvailable, "Generate 3DES MIFARE diversified keys"},
{"pwdgen", CmdHF14AMfUPwdGen, AlwaysAvailable, "Generate pwd from known algos"}, {"pwdgen", CmdHF14AMfUPwdGen, AlwaysAvailable, "Generate pwd from known algos"},
{"otptear", CmdHF14AMfuOtpTearoff, IfPm3Iso14443a, "Tear-off test on OTP bits"}, {"otptear", CmdHF14AMfuOtpTearoff, IfPm3Iso14443a, "Tear-off test on OTP bits"},
// {"tear_cnt", CmdHF14AMfuEv1CounterTearoff, IfPm3Iso14443a, "Tear-off test on Ev1/NTAG Counter bits"}, // {"tear_cnt", CmdHF14AMfuEv1CounterTearoff, IfPm3Iso14443a, "Tear-off test on Ev1/NTAG Counter bits"},
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("operations") " -----------------------"}, {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("operations") " -----------------------"},
{"cauth", CmdHF14AMfUCAuth, IfPm3Iso14443a, "Authentication - Ultralight-C"}, {"cauth", CmdHF14AMfUCAuth, IfPm3Iso14443a, "Authentication - Ultralight-C"},
{"dump", CmdHF14AMfUDump, IfPm3Iso14443a, "Dump MIFARE Ultralight family tag to binary file"}, {"dump", CmdHF14AMfUDump, IfPm3Iso14443a, "Dump MIFARE Ultralight family tag to binary file"},
{"info", CmdHF14AMfUInfo, IfPm3Iso14443a, "Tag information"}, {"info", CmdHF14AMfUInfo, IfPm3Iso14443a, "Tag information"},
@ -3911,12 +3979,15 @@ static command_t CommandTable[] = {
{"rdbl", CmdHF14AMfURdBl, IfPm3Iso14443a, "Read block"}, {"rdbl", CmdHF14AMfURdBl, IfPm3Iso14443a, "Read block"},
{"restore", CmdHF14AMfURestore, IfPm3Iso14443a, "Restore a dump onto a MFU MAGIC tag"}, {"restore", CmdHF14AMfURestore, IfPm3Iso14443a, "Restore a dump onto a MFU MAGIC tag"},
{"wrbl", CmdHF14AMfUWrBl, IfPm3Iso14443a, "Write block"}, {"wrbl", CmdHF14AMfUWrBl, IfPm3Iso14443a, "Write block"},
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("simulation") " -----------------------"}, {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("simulation") " -----------------------"},
{"eload", CmdHF14AMfUeLoad, IfPm3Iso14443a, "load Ultralight .eml dump file into emulator memory"}, {"eload", CmdHF14AMfUeLoad, IfPm3Iso14443a, "load Ultralight .eml dump file into emulator memory"},
{"eview", CmdHF14AMfuEView, IfPm3Iso14443a, "View emulator memory"}, {"eview", CmdHF14AMfuEView, IfPm3Iso14443a, "View emulator memory"},
{"sim", CmdHF14AMfUSim, IfPm3Iso14443a, "Simulate MIFARE Ultralight from emulator memory"}, {"sim", CmdHF14AMfUSim, IfPm3Iso14443a, "Simulate MIFARE Ultralight from emulator memory"},
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("magic") " ----------------------------"},
{"setpwd", CmdHF14AMfUCSetPwd, IfPm3Iso14443a, "Set 3DES key - Ultralight-C"}, {"setpwd", CmdHF14AMfUCSetPwd, IfPm3Iso14443a, "Set 3DES key - Ultralight-C"},
{"setuid", CmdHF14AMfUCSetUid, IfPm3Iso14443a, "Set UID - MAGIC tags only"}, {"setuid", CmdHF14AMfUCSetUid, IfPm3Iso14443a, "Set UID - MAGIC tags only"},
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("amiibo") " ----------------------------"},
// {"decrypt", CmdHF14AMfUCDecryptAmiibo, IfPm3Iso14443a, "Decrypt a amiibo tag"},
{NULL, NULL, NULL, NULL} {NULL, NULL, NULL, NULL}
}; };

View file

@ -113,19 +113,6 @@ static int usage_hitag_writer(void) {
PrintAndLogEx(NORMAL, " 27 <password> <page> <byte0...byte3> Write page, password mode. Default: 4D494B52 (\"MIKR\")"); PrintAndLogEx(NORMAL, " 27 <password> <page> <byte0...byte3> Write page, password mode. Default: 4D494B52 (\"MIKR\")");
return PM3_SUCCESS; return PM3_SUCCESS;
} }
static int usage_hitag_checkchallenges(void) {
PrintAndLogEx(NORMAL, "Check challenges, load a file with save hitag crypto challenges and test them all.");
PrintAndLogEx(NORMAL, "The file should be 8 * 60 bytes long, the file extension defaults to " _YELLOW_("`.cc`"));
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf hitag cc [h] f <filename w/o extension>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help");
PrintAndLogEx(NORMAL, " f <filename> Load data from BIN file");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf hitag cc f lf-hitag-challenges");
return PM3_SUCCESS;
}
static int CmdLFHitagList(const char *Cmd) { static int CmdLFHitagList(const char *Cmd) {
char args[128] = {0}; char args[128] = {0};
@ -614,50 +601,46 @@ static int CmdLFHitagReader(const char *Cmd) {
static int CmdLFHitagCheckChallenges(const char *Cmd) { static int CmdLFHitagCheckChallenges(const char *Cmd) {
char filename[FILE_PATH_SIZE] = { 0x00 }; CLIParserContext *ctx;
size_t datalen = 0; CLIParserInit(&ctx, "lf hitag cc",
int res = 0; "Check challenges, load a file with saved hitag crypto challenges and test them all.\n"
bool file_given = false; "The file should be 8 * 60 bytes long, the file extension defaults to " _YELLOW_("`.cc`") " ",
bool errors = false; "lf hitag cc -f my_hitag_challenges"
uint8_t cmdp = 0; );
uint8_t *data = calloc(8 * 60, sizeof(uint8_t));
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { void *argtable[] = {
switch (tolower(param_getchar(Cmd, cmdp))) { arg_param_begin,
case 'h': arg_str0("f", "filename", "<fn w/o ext>", "filename to load from"),
free(data); arg_param_end
return usage_hitag_checkchallenges(); };
case 'f': CLIExecWithReturn(ctx, Cmd, argtable, true);
//file with all the challenges to try
param_getstr(Cmd, cmdp + 1, filename, sizeof(filename));
res = loadFile(filename, ".cc", data, 8 * 60, &datalen);
if (res > 0) {
errors = true;
break;
}
file_given = true;
cmdp += 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
//Validations int fnlen = 0;
if (errors || strlen(Cmd) == 0) { char filename[FILE_PATH_SIZE] = {0};
free(data); CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
return usage_hitag_checkchallenges();
} CLIParserFree(ctx);
clearCommandBuffer(); clearCommandBuffer();
if (file_given)
SendCommandOLD(CMD_LF_HITAGS_TEST_TRACES, 1, 0, 0, data, datalen);
else
SendCommandMIX(CMD_LF_HITAGS_TEST_TRACES, 0, 0, 0, NULL, 0);
free(data); if (fnlen > 0) {
uint8_t *data = NULL;
size_t datalen = 0;
int res = loadFile_safe(filename, ".cc", (void **)&data, &datalen);
if (res == PM3_SUCCESS) {
if (datalen == (8 * 60) ) {
SendCommandOLD(CMD_LF_HITAGS_TEST_TRACES, 1, 0, 0, data, datalen);
} else {
PrintAndLogEx(ERR, "Error, file length mismatch. Expected %d, got %d", 8*60, datalen);
}
}
if (data) {
free(data);
}
} else {
SendCommandMIX(CMD_LF_HITAGS_TEST_TRACES, 0, 0, 0, NULL, 0);
}
return PM3_SUCCESS; return PM3_SUCCESS;
} }

File diff suppressed because it is too large Load diff

View file

@ -32,6 +32,7 @@
#define T55X7_NORALSY_CONFIG_BLOCK 0x00088C6A // ASK, compat mode, (NORALSY - KCP3000), data rate 32, 3 data blocks #define T55X7_NORALSY_CONFIG_BLOCK 0x00088C6A // ASK, compat mode, (NORALSY - KCP3000), data rate 32, 3 data blocks
#define T55X7_PRESCO_CONFIG_BLOCK 0x00088088 // ASK, data rate 32, Manchester, 4 data blocks, STT #define T55X7_PRESCO_CONFIG_BLOCK 0x00088088 // ASK, data rate 32, Manchester, 4 data blocks, STT
#define T55X7_SECURAKEY_CONFIG_BLOCK 0x000C8060 // ASK, Manchester, data rate 40, 3 data blocks #define T55X7_SECURAKEY_CONFIG_BLOCK 0x000C8060 // ASK, Manchester, data rate 40, 3 data blocks
#define T55X7_UNK_CONFIG_BLOCK 0x000880FA // ASK, Manchester, data rate 32, 7 data blocks STT, Inverse ...
// FDXB requires data inversion and BiPhase 57 is simply BiPhase 50 inverted, so we can either do it using the modulation scheme or the inversion flag // FDXB requires data inversion and BiPhase 57 is simply BiPhase 50 inverted, so we can either do it using the modulation scheme or the inversion flag
// we've done both below to prove that it works either way, and the modulation value for BiPhase 50 in the Atmel data sheet of binary "10001" (17) is a typo, // we've done both below to prove that it works either way, and the modulation value for BiPhase 50 in the Atmel data sheet of binary "10001" (17) is a typo,
@ -126,10 +127,10 @@ typedef struct {
uint8_t offset; uint8_t offset;
uint32_t block0; uint32_t block0;
enum { enum {
notSet = 0x00, NOTSET = 0x00,
autoDetect = 0x01, AUTODETECT = 0x01,
userSet = 0x02, USERSET = 0x02,
tagRead = 0x03, TAGREAD = 0x03,
} block0Status; } block0Status;
enum { enum {
RF_8 = 0x00, RF_8 = 0x00,

View file

@ -412,7 +412,7 @@ static void flash_suggest_update_bootloader(void) {
PrintAndLogEx(ERR, _RED_("reboot the Proxmark3 then only update the main firmware") "\n"); PrintAndLogEx(ERR, _RED_("reboot the Proxmark3 then only update the main firmware") "\n");
PrintAndLogEx(ERR, "Follow these steps :"); PrintAndLogEx(ERR, "Follow these steps :");
PrintAndLogEx(ERR, " 1) ./pm3-flash-bootrom"); PrintAndLogEx(ERR, " 1) ./pm3-flash-bootrom");
PrintAndLogEx(ERR, " 2) ./pm3-flash-flash-all"); PrintAndLogEx(ERR, " 2) ./pm3-flash-all");
PrintAndLogEx(ERR, " 3) ./pm3"); PrintAndLogEx(ERR, " 3) ./pm3");
PrintAndLogEx(INFO, "--------------------------------------------------------"); PrintAndLogEx(INFO, "--------------------------------------------------------");
g_printed_msg = true; g_printed_msg = true;

View file

@ -130,7 +130,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
portstr = colon + 1; portstr = colon + 1;
*colon = '\0'; *colon = '\0';
} else { } else {
portstr = "7901"; portstr = "18888";
} }
struct addrinfo info; struct addrinfo info;

View file

@ -483,6 +483,9 @@ static bool Pack_C15001(wiegand_card_t *card, wiegand_message_t *packed, bool pr
if (card->IssueLevel > 0) return false; // Not used in this format if (card->IssueLevel > 0) return false; // Not used in this format
if (card->OEM > 0x000003FF) return false; // Can't encode OEM. if (card->OEM > 0x000003FF) return false; // Can't encode OEM.
if (card->OEM == 0)
card->OEM = 900;
packed->Length = 36; // Set number of bits packed->Length = 36; // Set number of bits
set_linear_field(packed, card->OEM, 1, 10); set_linear_field(packed, card->OEM, 1, 10);
set_linear_field(packed, card->FacilityCode, 11, 8); set_linear_field(packed, card->FacilityCode, 11, 8);

View file

@ -1,8 +1,9 @@
# T5577 Introduction Guide # T5577 Introduction Guide
### Based on RRG proxmark3 fork. ### Based on RRG/Iceman Proxmark3 repo
### Ver.1 8 Sep 2019 ### Ver.1 8 Sep 2019
### Ver.2 7 March 2021
| Contents | | Contents |
| ----------------------------------------------------------------------------------- | | ----------------------------------------------------------------------------------- |
@ -79,14 +80,16 @@ examples shown, it will be assumed you have run the detect command.
``` ```
You should see a results simular to the following: You should see a results simular to the following:
``` ```
Chip Type : T55x7 [=] Chip type......... T55x7
Modulation : ASK [=] Modulation........ ASK
Bit Rate : 2 - RF/32 [=] Bit rate.......... 2 - RF/32
Inverted : No [=] Inverted.......... No
Offset : 32 [=] Offset............ 33
Seq. Term. : Yes [=] Seq. terminator... Yes
Block0 : 0x000880E0 [=] Block0............ 000880E0 (auto detect)
Downlink Mode : default/fixed bit length [=] Downlink mode..... default/fixed bit length
[=] Password set...... No
``` ```
Now that the proxmark3 has detected a T55x7 chip, and found some Now that the proxmark3 has detected a T55x7 chip, and found some
information about it, we should be able to see all the data on the chip. information about it, we should be able to see all the data on the chip.
@ -140,7 +143,7 @@ can see the card)
as, run a low frequency (lf) command for the T55xx chip (t55xx) and as, run a low frequency (lf) command for the T55xx chip (t55xx) and
read block (b) number 1. read block (b) number 1.
``` ```
[usb] pm3 --> lf t55xx read b 1 [usb] pm3 --> lf t55xx read -b 1
``` ```
result: result:
``` ```
@ -156,7 +159,7 @@ can see the card)
We use the d option to supply the data 12345678 We use the d option to supply the data 12345678
``` ```
[usb] pm3 --> lf t55xx write b 1 d 12345678 [usb] pm3 --> lf t55xx write -b 1 -d 12345678
``` ```
result: result:
``` ```
@ -164,7 +167,7 @@ can see the card)
``` ```
3) Now, lets check if the data was written. 3) Now, lets check if the data was written.
``` ```
[usb] pm3 --> lf t55xx read b 1 [usb] pm3 --> lf t55xx read -b 1
``` ```
result: result:
``` ```
@ -202,7 +205,7 @@ can see the card)
Lets try and write 89ABCDEF Lets try and write 89ABCDEF
``` ```
[usb] pm3 --> lf t55xx write b 1 d 89abcdef [usb] pm3 --> lf t55xx write -b 1 -d 89abcdef
``` ```
result: result:
``` ```
@ -210,7 +213,7 @@ can see the card)
``` ```
and check and check
``` ```
[usb] pm3 --> lf t55xx read b 1 [usb] pm3 --> lf t55xx read -b 1
``` ```
result: result:
``` ```
@ -272,9 +275,10 @@ required, please do not proceed.
``` ```
Result: Result:
``` ```
[=] Begin wiping T55x7 tag [=] Target T55x7 tag
[=] Default configuration block 000880E0
[=] Default configation block 000880E0 [=] Begin wiping...
[=] Writing page 0 block: 00 data: 0x000880E0 [=] Writing page 0 block: 00 data: 0x000880E0
[=] Writing page 0 block: 01 data: 0x00000000 [=] Writing page 0 block: 01 data: 0x00000000
[=] Writing page 0 block: 02 data: 0x00000000 [=] Writing page 0 block: 02 data: 0x00000000
@ -291,14 +295,15 @@ required, please do not proceed.
``` ```
result: result:
``` ```
Chip Type : T55x7 [=] Chip type......... T55x7
Modulation : ASK [=] Modulation........ ASK
Bit Rate : 2 - RF/32 [=] Bit rate.......... 2 - RF/32
Inverted : No [=] Inverted.......... No
Offset : 32 [=] Offset............ 33
Seq. Term. : Yes [=] Seq. terminator... Yes
Block0 : 0x000880E0 [=] Block0............ 000880E0 (auto detect)
Downlink Mode : default/fixed bit length [=] Downlink mode..... default/fixed bit length
[=] Password set...... No
``` ```
If block 0 does not hold the hex data **0x00088040 resolve this If block 0 does not hold the hex data **0x00088040 resolve this
@ -309,7 +314,7 @@ required, please do not proceed.
The password is saved in block 7 of page 0. The password is saved in block 7 of page 0.
``` ```
[usb] pm3 --> lf t55xx write b 7 d 12345678 [usb] pm3 --> lf t55xx write -b 7 -d 12345678
``` ```
result: result:
``` ```
@ -389,7 +394,7 @@ required, please do not proceed.
If you have completed all steps and have the exact same results, we are If you have completed all steps and have the exact same results, we are
ready to apply the new configuration. ready to apply the new configuration.
``` ```
[usb] pm3 --> lf t55xx write b 0 d 00088050 [usb] pm3 --> lf t55xx write -b 0 -d 00088050
``` ```
result: result:
``` ```
@ -412,23 +417,25 @@ required, please do not proceed.
Lets try again, but this time supply the password. We use the option Lets try again, but this time supply the password. We use the option
p followed by the password. p followed by the password.
``` ```
[usb] pm3 --> lf t55 detect p 12345678 [usb] pm3 --> lf t55 detect -p 12345678
``` ```
result: result:
``` ```
Chip Type : T55x7 [=] Chip type......... T55x7
Modulation : ASK [=] Modulation........ ASK
Bit Rate : 2 - RF/32 [=] Bit rate.......... 2 - RF/32
Inverted : No [=] Inverted.......... No
Offset : 32 [=] Offset............ 33
Seq. Term. : Yes [=] Seq. terminator... Yes
Block0 : 0x00088050 [=] Block0............ 00088050 (auto detect)
Downlink Mode : default/fixed bit length [=] Downlink mode..... default/fixed bit length
[=] Password set...... Yes
[=] Password.......... 00000000
``` ```
7) Write a block of data with a password 7) Write a block of data with a password
``` ```
[usb] pm3 --> lf t55xx write b 1 d 1234abcd p 12345678 [usb] pm3 --> lf t55xx write -b 1 -d 1234abcd -p 12345678
``` ```
result: result:
``` ```
@ -445,7 +452,7 @@ required, please do not proceed.
The proxmark3 has a safety check\! The proxmark3 has a safety check\!
``` ```
[usb] pm3 --> lf t55xx read b 1 p 12345678 [usb] pm3 --> lf t55xx read -b 1 -p 12345678
``` ```
result: result:
``` ```
@ -453,6 +460,7 @@ required, please do not proceed.
[+] blk | hex data | binary | ascii [+] blk | hex data | binary | ascii
[+] ----+----------+----------------------------------+------- [+] ----+----------+----------------------------------+-------
[!] Safety check: Could not detect if PWD bit is set in config block. Exits. [!] Safety check: Could not detect if PWD bit is set in config block. Exits.
[?] Consider using the override parameter to force read.
``` ```
Note that the proxmark3 did not read the block, the safty kicked in Note that the proxmark3 did not read the block, the safty kicked in
@ -460,7 +468,7 @@ required, please do not proceed.
Lets try again with the o option as we know the password is set. Lets try again with the o option as we know the password is set.
``` ```
[usb] pm3 --> lf t55xx read b 1 p 12345678 o [usb] pm3 --> lf t55xx read -b 1 -p 12345678 -o
``` ```
result: result:
``` ```
@ -486,7 +494,7 @@ required, please do not proceed.
In our examples we know what it should be : 00088040 In our examples we know what it should be : 00088040
``` ```
[usb] pm3 --> lf t55xx write b 0 d 00088040 p 12345678 [usb] pm3 --> lf t55xx write -b 0 -d 00088040 -p 12345678
``` ```
result: result:
``` ```
@ -498,14 +506,15 @@ required, please do not proceed.
``` ```
result: result:
``` ```
Chip Type : T55x7 [=] Chip type......... T55x7
Modulation : ASK [=] Modulation........ ASK
Bit Rate : 2 - RF/32 [=] Bit rate.......... 2 - RF/32
Inverted : No [=] Inverted.......... No
Offset : 32 [=] Offset............ 33
Seq. Term. : Yes [=] Seq. terminator... Yes
Block0 : 0x00088040 [=] Block0............ 00088040 (auto detect)
Downlink Mode : default/fixed bit length [=] Downlink mode..... default/fixed bit length
[=] Password set...... No
``` ```
Yes we can and we can see Block 0 is the correct config 00088040 Yes we can and we can see Block 0 is the correct config 00088040
@ -571,14 +580,16 @@ password set (if not, review and get you card back to this state).
1) Lets turn you T5577 into an EM4100 with ID 1122334455 1) Lets turn you T5577 into an EM4100 with ID 1122334455
``` ```
[usb] pm3 --> lf em 410x_write 1122334455 1 [usb] pm3 --> lf em 410x clone --id 1122334455
``` ```
result: result:
``` ```
[+] Writing T55x7 tag with UID 0x1122334455 (clock rate: 64) [+] Preparing to clone EM4102 to T55x7 tag with ID 0F0368568B (RF/64)
#db# Started writing T55x7 tag ... [#] Clock rate: 64
#db# Clock rate: 64 [#] Tag T55x7 written with 0xff83c03322a646e4
#db# Tag T55x7 written with 0xff8c65298c94a940
[+] Done
[?] Hint: try `lf em 410x reader` to verify
``` ```
2) Check this has work. 2) Check this has work.
@ -592,36 +603,32 @@ password set (if not, review and get you card back to this state).
[=] False Positives ARE possible [=] False Positives ARE possible
[=] [=]
[=] Checking for known tags... [=] Checking for known tags...
[=]
[+] EM410x pattern found [+] EM 410x ID 0F0368568B
[+] EM410x ( RF/64 )
EM TAG ID : 1122334455 [=] -------- Possible de-scramble patterns ---------
[+] Unique TAG ID : F0C0166AD1
Possible de-scramble patterns [=] HoneyWell IdentKey
[+] DEZ 8 : 06837899
Unique TAG ID : 8844CC22AA [+] DEZ 10 : 0057169547
HoneyWell IdentKey { [+] DEZ 5.5 : 00872.22155
DEZ 8 : 03359829 [+] DEZ 3.5A : 015.22155
DEZ 10 : 0573785173 [+] DEZ 3.5B : 003.22155
DEZ 5.5 : 08755.17493 [+] DEZ 3.5C : 104.22155
DEZ 3.5A : 017.17493 [+] DEZ 14/IK2 : 00064481678987
DEZ 3.5B : 034.17493 [+] DEZ 15/IK3 : 001034014845649
DEZ 3.5C : 051.17493 [+] DEZ 20/ZK : 15001200010606101301
DEZ 14/IK2 : 00073588229205 [=]
DEZ 15/IK3 : 000585269781162 [+] Other : 22155_104_06837899
DEZ 20/ZK : 08080404121202021010 [+] Pattern Paxton : 259822731 [0xF7C948B]
} [+] Pattern 1 : 9750181 [0x94C6A5]
Other : 17493_051_03359829 [+] Pattern Sebury : 22155 104 6837899 [0x568B 0x68 0x68568B]
Pattern Paxton : 289899093 [0x11478255] [=] ------------------------------------------------
Pattern 1 : 5931804 [0x5A831C]
Pattern Sebury : 17493 51 3359829 [0x4455 0x33 0x334455]
[+] Valid EM410x ID found! [+] Valid EM410x ID found!
[+] Chipset detection: T55xx
[+] Chipset detection : T55xx found [?] Hint: try `lf t55xx` commands
[+] Try `lf t55xx` commands
``` ```
Looks good. Looks good.
@ -631,15 +638,15 @@ password set (if not, review and get you card back to this state).
``` ```
result: result:
``` ```
[usb] pm3 --> lf t55 detect [=] Chip type......... T55x7
Chip Type : T55x7 [=] Modulation........ ASK
Modulation : ASK [=] Bit rate.......... 5 - RF/64
Bit Rate : 5 - RF/64 [=] Inverted.......... No
Inverted : No [=] Offset............ 33
Offset : 32 [=] Seq. terminator... Yes
Seq. Term. : Yes [=] Block0............ 00148040 (auto detect)
Block0 : 0x00148040 [=] Downlink mode..... default/fixed bit length
Downlink Mode : default/fixed bit length [=] Password set...... No
``` ```
``` ```
[usb] pm3 --> lf t55xx info [usb] pm3 --> lf t55xx info
@ -647,28 +654,27 @@ password set (if not, review and get you card back to this state).
result: result:
``` ```
-- T55x7 Configuration & Tag Information -------------------- [=] --- T55x7 Configuration & Information ---------
------------------------------------------------------------- [=] Safer key : 0
Safer key : 0 [=] reserved : 0
reserved : 0 [=] Data bit rate : 5 - RF/64
Data bit rate : 5 - RF/64 [=] eXtended mode : No
eXtended mode : No [=] Modulation : 8 - Manchester
Modulation : 8 - Manchester [=] PSK clock frequency : 0 - RF/2
PSK clock frequency : 0 - RF/2 [=] AOR - Answer on Request : No
AOR - Answer on Request : No [=] OTP - One Time Pad : No
OTP - One Time Pad : No [=] Max block : 2
Max block : 2 [=] Password mode : No
Password mode : No [=] Sequence Terminator : No
Sequence Terminator : No [=] Fast Write : No
Fast Write : No [=] Inverse data : No
Inverse data : No [=] POR-Delay : No
POR-Delay : No [=] -------------------------------------------------------------
------------------------------------------------------------- [=] Raw Data - Page 0, block 0
Raw Data - Page 0 [=] 00148040 - 00000000000101001000000001000000
Block 0 : 0x00148040 00000000000101001000000001000000 [=] --- Fingerprint ------------
[+] Config block match : EM unique, Paxton
Config block match : EM unique, Paxton
-------------------------------------------------------------
``` ```
We can see that the info gave us more information and confirmed what We can see that the info gave us more information and confirmed what
we decoded by hand. But remember, the detect is still needed so the we decoded by hand. But remember, the detect is still needed so the

View file

@ -32,7 +32,6 @@ data print
data samples data samples
data setdebugmode data setdebugmode
data tune data tune
hf 14b sriwrite
hf 15 dump hf 15 dump
hf 15 info hf 15 info
hf 15 raw hf 15 raw
@ -94,12 +93,4 @@ lf hitag sim
lf hitag writer lf hitag writer
lf hitag dump lf hitag dump
lf hitag cc lf hitag cc
lf t55xx config
lf t55xx dump
lf t55xx info
lf t55xx read
lf t55xx resetread
lf t55xx restore
lf t55xx trace
lf t55xx write
script run script run

View file

@ -60,8 +60,8 @@ Standard password is normally (for T55xx): AA55BBBB
# Restore page1 data # Restore page1 data
``` ```
lf t55xx write b 1 d E0150A48 1 lf t55xx write -b 1 -d E0150A48 --pg1
If t55xx write b 2 d 2D782308 1 If t55xx write -b 2 -d 2D782308 --pg1
``` ```
# Sniffing the comms # Sniffing the comms

View file

@ -39,8 +39,8 @@ Page 3:
* used by Proxmark3 RDV4 specific functions: flash signature and keys dictionaries, see below for details * used by Proxmark3 RDV4 specific functions: flash signature and keys dictionaries, see below for details
* to dump it: `mem dump f page3_dump o 196608 l 65536` * to dump it: `mem dump f page3_dump o 196608 l 65536`
* to erase it: * to erase it:
* **Beware** it will erase your flash signature (see below) so better to back it up first as you won't be able to regenerate it by yourself! * **Beware** it will erase your flash signature so better to back it up first as you won't be able to regenerate it by yourself!
* It's possible to erase completely page 3 by erase the entire flash memory with the voluntarily undocumented command `mem wipe i`. * edit the source code to enable Page 3 as a valid input in the `mem wipe` command.
* Updating keys dictionaries doesn't require to erase page 3. * Updating keys dictionaries doesn't require to erase page 3.
## Page3 Layout ## Page3 Layout
@ -64,7 +64,7 @@ Page3 is used as follows by the Proxmark3 RDV4 firmware:
* length: 1 sector (actually only a few bytes are used to store `t55xx_config` structure) * length: 1 sector (actually only a few bytes are used to store `t55xx_config` structure)
* **RSA SIGNATURE**, see below for details * **RSA SIGNATURE**, see below for details
* offset: page 3 sector 15 (0xF) offset 0xF7F @ 3*0x10000+15*0x1000+0xF7F=0x3FF7F * offset: page 3 sector 15 (0xF) offset 0xF7F @ 3*0x10000+15*0x1000+0xF7F=0x3FF7F (decimal 262015)
* length: 128 bytes * length: 128 bytes
* offset should have been 0x3FF80 but historically it's one byte off and therefore the last byte of the flash is unused * offset should have been 0x3FF80 but historically it's one byte off and therefore the last byte of the flash is unused
@ -73,23 +73,39 @@ Page3 is used as follows by the Proxmark3 RDV4 firmware:
To ensure your Proxmark3 RDV4 is not a counterfeit product, its external flash contains a RSA signature of the flash unique ID. To ensure your Proxmark3 RDV4 is not a counterfeit product, its external flash contains a RSA signature of the flash unique ID.
You can verify it with: `mem info` You can verify it with: `mem info`
Here below is a sample output of a RDV4 device.
``` ```
[usb] pm3 --> mem info [usb] pm3 --> mem info
[=] --- Flash memory Information --------- [=] --- Flash memory Information ---------
[=] ID................... 25AD99A782A867D5
[=] SHA1................. 67C3B9BA2FA90AD4B283926B70017066C082C156
[+] Signature............ ( ok )
[=] ------------------------------------------------------------- [=] --- RDV4 RSA signature ---------------
[=] ID | xx xx xx xx xx xx xx xx [=] C7C7DF7FA3A2391A2B36E97D227C746ED8BB475E8766F54A13BAA9AAB29299BE
[=] SHA1 | xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx [=] 37546AACCC29157ABF8AFBF3A1CFB24275442D565F7E996C6B08090528ADE25E
[=] RSA SIGNATURE | [=] ED1498E3089C72C68348D83CBD13F1247327BDBC9D75B09ECE3E051E19FE19BB
[00] | xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx [=] 98CB038757F2EDFD2DC5060D05C3296BC19A6F768290D555DFD50407E0E13A70
[01] | xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
[02] | xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx [=] --- RDV4 RSA Public key --------------
[03] | xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx [=] Len.................. 128
[=] KEY length | 128 [=] Exponent............. 010001
[+] RSA key validation ok [=] Public key modulus N
[+] RSA Verification ok [=] E28D809BF323171D11D1ACA4C32A5B7E0A8974FD171E75AD120D60E9B76968FF
[=] 4B0A6364AE50583F9555B8EE1A725F279E949246DF0EFCE4C02B9F3ACDCC623F
[=] 9337F21C0C066FFB703D8BFCB5067F309E056772096642C2B1A8F50305D5EC33
[=] DB7FB5A3C8AC42EB635AE3C148C910750ABAA280CE82DC2F180F49F30A1393B5
[+] RSA public key validation.... ( ok )
[+] RSA private key validation... ( ok )
[+] RSA verification..... ( ok )
[+] Genuine Proxmark3 RDV4 signature detected
``` ```
For a backup of the signature: `mem dump p f flash_signature_dump o 262015 l 128` # backup first!
To make a backup of the signature to file:
`mem dump p f flash_signature_dump o 262015 l 128`

View file

@ -50,7 +50,7 @@ typedef struct {
} PACKED rht2d_crypto; } PACKED rht2d_crypto;
typedef struct { typedef struct {
bool key_no; uint8_t key_no;
uint8_t logdata_0[4]; uint8_t logdata_0[4];
uint8_t logdata_1[4]; uint8_t logdata_1[4];
uint8_t nonce[4]; uint8_t nonce[4];

View file

@ -130,7 +130,8 @@ def selftests():
{'name': "ICODE DNA, ICODE SLIX2", {'name': "ICODE DNA, ICODE SLIX2",
# ! tag UID is considered inverted: E0040118009B5FEE => EE5F9B00180104E0 # ! tag UID is considered inverted: E0040118009B5FEE => EE5F9B00180104E0
# TODO one more ICODE-DNA... # TODO one more ICODE-DNA...
'samples': ["EE5F9B00180104E0", "32D9E7579CD77E6F1FA11419231E874826984C5F189FDE1421684563A9663377"], 'samples': ["EE5F9B00180104E0", "32D9E7579CD77E6F1FA11419231E874826984C5F189FDE1421684563A9663377",
"838ED22A080104E0", "CAE8183CB4823C765AFDEB78C9D66C959990FD52A5820E76E1D6E025D76EAD79"],
'pk': "048878A2A2D3EEC336B4F261A082BD71F9BE11C4E2E896648B32EFA59CEA6E59F0"}, 'pk': "048878A2A2D3EEC336B4F261A082BD71F9BE11C4E2E896648B32EFA59CEA6E59F0"},
# {'name': "Minecraft Earth", # {'name': "Minecraft Earth",
# # uses secp256r1?, SHA-256, # # uses secp256r1?, SHA-256,

View file

@ -89,4 +89,5 @@
|hf_14a_mfu.trace |Reading of a password-protected MFU| |hf_14a_mfu.trace |Reading of a password-protected MFU|
|hf_14a_mfu-sim.trace |Trace seen from a Proxmark3 simulating a MFU| |hf_14a_mfu-sim.trace |Trace seen from a Proxmark3 simulating a MFU|
|hf_14b_reader.trace |Execution of `hf 14b reader` against a card| |hf_14b_reader.trace |Execution of `hf 14b reader` against a card|
|hf_14b_cryptorf_select.trace |Sniff of libnfc select / anticollision ofa cryptoRF tag|
|hf_15_reader.trace |Execution of `hf 15 reader` against a card| |hf_15_reader.trace |Execution of `hf 15 reader` against a card|

Binary file not shown.