This commit is contained in:
iceman1001 2024-03-14 11:26:06 +01:00
commit 94c3bdd91c
17 changed files with 355 additions and 297 deletions

View file

@ -252,8 +252,7 @@ static inline void assign_single_ssr_bit ( ID48LIBX_STATE_REGISTERS* ssr, s
ASSERT(bit_index < (sizeof(uint64_t) * 8)); ASSERT(bit_index < (sizeof(uint64_t) * 8));
if (value) { if (value) {
set_single_ssr_bit(ssr, bit_index); set_single_ssr_bit(ssr, bit_index);
} } else {
else {
clear_single_ssr_bit(ssr, bit_index); clear_single_ssr_bit(ssr, bit_index);
} }
} }
@ -406,7 +405,8 @@ static inline void g_successor(ID48LIBX_STATE_REGISTERS* ssr) {
static inline ID48LIBX_STATE_REGISTERS init_id48libx_state_register(const ID48LIB_KEY *k96, const ID48LIB_NONCE *n56) { static inline ID48LIBX_STATE_REGISTERS init_id48libx_state_register(const ID48LIB_KEY *k96, const ID48LIB_NONCE *n56) {
ASSERT(k96 != nullptr); ASSERT(k96 != nullptr);
ASSERT(n56 != nullptr); ASSERT(n56 != nullptr);
ID48LIBX_STATE_REGISTERS result; result.Raw = 0; ID48LIBX_STATE_REGISTERS result;
result.Raw = 0;
ID48LIBX_STATE_REGISTERS *const ssr = &result; // the pointer is constant ... not the value it points to ID48LIBX_STATE_REGISTERS *const ssr = &result; // the pointer is constant ... not the value it points to
const uint64_t p55_p00 = calculate__p55_p00(k96, n56); const uint64_t p55_p00 = calculate__p55_p00(k96, n56);
@ -447,8 +447,7 @@ static inline ID48LIBX_STATE_REGISTERS init_id48libx_state_register(const ID48LI
ssr->Raw |= 1u; ssr->Raw |= 1u;
// G(g,0,j) twenty times, using q19, q18, ... q00 for `j` // G(g,0,j) twenty times, using q19, q18, ... q00 for `j`
for (uint8_t ix = 0; ix < 20; ++ix) for (uint8_t ix = 0; ix < 20; ++ix) {
{
ASSERT(is_ssr_state_stable(ssr)); ASSERT(is_ssr_state_stable(ssr));
ssr->Raw <<= 1; // starts the process ... it's now an unstable value ssr->Raw <<= 1; // starts the process ... it's now an unstable value
ASSERT(!is_ssr_state_stable(ssr)); ASSERT(!is_ssr_state_stable(ssr));
@ -658,7 +657,8 @@ static inline OUTPUT_INDEX2 calculate_output_index(const ID48LIBX_STATE_REGISTER
// msb 19 ---^ lsb 00 ---^^ // msb 19 ---^ lsb 00 ---^^
ASSERT(ssr != nullptr); ASSERT(ssr != nullptr);
ASSERT(!is_ssr_state_stable(ssr)); ASSERT(!is_ssr_state_stable(ssr));
OUTPUT_INDEX2 result; result.Raw = 0; OUTPUT_INDEX2 result;
result.Raw = 0;
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_a)) result.Raw |= (1u << 19); if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_a)) result.Raw |= (1u << 19);
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_b)) result.Raw |= (1u << 18); if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_b)) result.Raw |= (1u << 18);
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_c)) result.Raw |= (1u << 17); if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_c)) result.Raw |= (1u << 17);
@ -755,7 +755,8 @@ static inline INPUT_BITS2 get_key_input_bits(const ID48LIB_KEY* k) {
// So, what should end up in result is: 0²⁴ k₀₀..K₃₉ // So, what should end up in result is: 0²⁴ k₀₀..K₃₉
// This allows simply shifting the lsb out each cycle.... // This allows simply shifting the lsb out each cycle....
INPUT_BITS2 result; result.Raw = 0; INPUT_BITS2 result;
result.Raw = 0;
// k[ 0] :== K₉₅..K₈₈ // k[ 0] :== K₉₅..K₈₈
// ... // ...
@ -821,8 +822,7 @@ static void retro_generator_impl(
const ID48LIB_NONCE *n, const ID48LIB_NONCE *n,
ID48LIB_FRN *frn28_out, ID48LIB_FRN *frn28_out,
ID48LIB_GRN *grn20_out ID48LIB_GRN *grn20_out
) ) {
{
ASSERT(k != nullptr); ASSERT(k != nullptr);
ASSERT(n != nullptr); ASSERT(n != nullptr);
ASSERT(frn28_out != nullptr); ASSERT(frn28_out != nullptr);
@ -834,7 +834,8 @@ static void retro_generator_impl(
// get 55-bit successor state input // get 55-bit successor state input
INPUT_BITS2 inputs = get_key_input_bits(k); INPUT_BITS2 inputs = get_key_input_bits(k);
OUTPUT_BITS2 outputs; outputs.Raw = 0ull; OUTPUT_BITS2 outputs;
outputs.Raw = 0ull;
for (uint8_t ix = 0; ix < 55; ix++) { for (uint8_t ix = 0; ix < 55; ix++) {
ASSERT(is_ssr_state_stable(&ssr)); ASSERT(is_ssr_state_stable(&ssr));
@ -867,7 +868,8 @@ static void retro_generator_impl(
// internal function // internal function
ID48LIBX_SUCCESSOR_RESULT id48libx_retro003_successor(const ID48LIBX_STATE_REGISTERS *initial_state, uint8_t input_bit) { ID48LIBX_SUCCESSOR_RESULT id48libx_retro003_successor(const ID48LIBX_STATE_REGISTERS *initial_state, uint8_t input_bit) {
ASSERT(initial_state != nullptr); ASSERT(initial_state != nullptr);
ID48LIBX_SUCCESSOR_RESULT r; memset(&r, 0, sizeof(ID48LIBX_SUCCESSOR_RESULT)); ID48LIBX_SUCCESSOR_RESULT r;
memset(&r, 0, sizeof(ID48LIBX_SUCCESSOR_RESULT));
ID48LIBX_STATE_REGISTERS s = *initial_state; ID48LIBX_STATE_REGISTERS s = *initial_state;
bool output_bit = calculate_successor_state(&s, !!input_bit); bool output_bit = calculate_successor_state(&s, !!input_bit);
r.state.Raw = s.Raw; r.state.Raw = s.Raw;
@ -880,7 +882,8 @@ ID48LIBX_STATE_REGISTERS id48libx_retro003_init(const ID48LIB_KEY* key, const I
ASSERT(nonce != nullptr); ASSERT(nonce != nullptr);
ID48LIBX_STATE_REGISTERS ssr = init_id48libx_state_register(key, nonce); ID48LIBX_STATE_REGISTERS ssr = init_id48libx_state_register(key, nonce);
ID48LIBX_STATE_REGISTERS result; memset(&result, 0, sizeof(ID48LIBX_STATE_REGISTERS)); ID48LIBX_STATE_REGISTERS result;
memset(&result, 0, sizeof(ID48LIBX_STATE_REGISTERS));
result.Raw = ssr.Raw; result.Raw = ssr.Raw;
return result; return result;
} }
@ -891,7 +894,6 @@ void id48lib_generator(
const ID48LIB_NONCE *n, const ID48LIB_NONCE *n,
ID48LIB_FRN *frn28_out, ID48LIB_FRN *frn28_out,
ID48LIB_GRN *grn20_out ID48LIB_GRN *grn20_out
) ) {
{
retro_generator_impl(k, n, frn28_out, grn20_out); retro_generator_impl(k, n, frn28_out, grn20_out);
} }

View file

@ -162,15 +162,23 @@ static EXPECTED_OUTPUT_BITS create_expected_output_bits(const ID48LIB_FRN* input
// grn[ 0] :== O₂₈ .. O₃₅ // grn[ 0] :== O₂₈ .. O₃₅
// grn[ 1] :== O₃₆ .. O₄₃ // grn[ 1] :== O₃₆ .. O₄₃
// grn[ 2] :== O₄₄..O₄₇ 0000 // grn[ 2] :== O₄₄..O₄₇ 0000
EXPECTED_OUTPUT_BITS result; result.Raw = 0u; EXPECTED_OUTPUT_BITS result;
result.Raw <<= 4; result.Raw |= reverse_bits_08(input_grn->grn[2] & 0xF0u); // adds grn₁₉..grn₁₆ aka O₄₇..O₄₄ result.Raw = 0u;
result.Raw <<= 8; result.Raw |= reverse_bits_08(input_grn->grn[1] & 0xFFu); // adds grn₁₅..grn₀₈ aka O₄₃..O₃₆ result.Raw <<= 4;
result.Raw <<= 8; result.Raw |= reverse_bits_08(input_grn->grn[0] & 0xFFu); // adds grn₀₇..grn₀₀ aka O₃₅..O₂₈ result.Raw |= reverse_bits_08(input_grn->grn[2] & 0xF0u); // adds grn₁₉..grn₁₆ aka O₄₇..O₄₄
result.Raw <<= 8;
result.Raw |= reverse_bits_08(input_grn->grn[1] & 0xFFu); // adds grn₁₅..grn₀₈ aka O₄₃..O₃₆
result.Raw <<= 8;
result.Raw |= reverse_bits_08(input_grn->grn[0] & 0xFFu); // adds grn₀₇..grn₀₀ aka O₃₅..O₂₈
result.Raw <<= 4; result.Raw |= reverse_bits_08(input_frn->frn[3] & 0xF0u); // adds frn₂₇..frn₂₄ aka O₂₇..O₂₄ result.Raw <<= 4;
result.Raw <<= 8; result.Raw |= reverse_bits_08(input_frn->frn[2] & 0xFFu); // adds frn₂₃..frn₁₆ aka O₂₃..O₁₆ result.Raw |= reverse_bits_08(input_frn->frn[3] & 0xF0u); // adds frn₂₇..frn₂₄ aka O₂₇..O₂₄
result.Raw <<= 8; result.Raw |= reverse_bits_08(input_frn->frn[1] & 0xFFu); // adds frn₁₅..frn₀₈ aka O₁₅..O₀₈ result.Raw <<= 8;
result.Raw <<= 8; result.Raw |= reverse_bits_08(input_frn->frn[0] & 0xFFu); // adds frn₀₇..frn₀₀ aka O₀₇..O₀₀ result.Raw |= reverse_bits_08(input_frn->frn[2] & 0xFFu); // adds frn₂₃..frn₁₆ aka O₂₃..O₁₆
result.Raw <<= 8;
result.Raw |= reverse_bits_08(input_frn->frn[1] & 0xFFu); // adds frn₁₅..frn₀₈ aka O₁₅..O₀₈
result.Raw <<= 8;
result.Raw |= reverse_bits_08(input_frn->frn[0] & 0xFFu); // adds frn₀₇..frn₀₀ aka O₀₇..O₀₀
return result; return result;
} }
/// <summary> /// <summary>
@ -224,8 +232,7 @@ static void init(
const ID48LIB_NONCE *input_nonce, const ID48LIB_NONCE *input_nonce,
const ID48LIB_FRN *input_frn, const ID48LIB_FRN *input_frn,
const ID48LIB_GRN *input_grn const ID48LIB_GRN *input_grn
) ) {
{
memset(&g_S, 0, sizeof(RECOVERY_STATE)); memset(&g_S, 0, sizeof(RECOVERY_STATE));
memset(&(g_S.states[0]), 0xAA, sizeof(ID48LIBX_STATE_REGISTERS) * MAXIMUM_STATE_HISTORY); memset(&(g_S.states[0]), 0xAA, sizeof(ID48LIBX_STATE_REGISTERS) * MAXIMUM_STATE_HISTORY);
g_S.known_k95_to_k48.k[0] = input_partial_key->k[0]; g_S.known_k95_to_k48.k[0] = input_partial_key->k[0];
@ -271,8 +278,7 @@ static bool get_next_potential_key(
g_S.is_fresh_initialization = false; g_S.is_fresh_initialization = false;
k_low.Raw = 0ull; k_low.Raw = 0ull;
current_key_bit_shift = 47; current_key_bit_shift = 47;
} } else {
else {
// by definition, a returned potential key had all the bits defined // by definition, a returned potential key had all the bits defined
current_key_bit_shift = 0; current_key_bit_shift = 0;
k_low = g_S.last_returned_potential_key; k_low = g_S.last_returned_potential_key;
@ -421,8 +427,7 @@ void id48lib_key_recovery_init(
const ID48LIB_NONCE *input_nonce, const ID48LIB_NONCE *input_nonce,
const ID48LIB_FRN *input_frn, const ID48LIB_FRN *input_frn,
const ID48LIB_GRN *input_grn const ID48LIB_GRN *input_grn
) ) {
{
init(input_partial_key, input_nonce, input_frn, input_grn); init(input_partial_key, input_nonce, input_frn, input_grn);
} }
bool id48lib_key_recovery_next( bool id48lib_key_recovery_next(

View file

@ -423,6 +423,7 @@ const static vocabulary_t vocabulary[] = {
{ 0, "hf mfu restore" }, { 0, "hf mfu restore" },
{ 0, "hf mfu tamper" }, { 0, "hf mfu tamper" },
{ 1, "hf mfu view" }, { 1, "hf mfu view" },
{ 0, "hf mfu wipe" },
{ 0, "hf mfu wrbl" }, { 0, "hf mfu wrbl" },
{ 0, "hf mfu eload" }, { 0, "hf mfu eload" },
{ 0, "hf mfu esave" }, { 0, "hf mfu esave" },
@ -512,6 +513,8 @@ const static vocabulary_t vocabulary[] = {
{ 1, "hf vas help" }, { 1, "hf vas help" },
{ 0, "hf vas reader" }, { 0, "hf vas reader" },
{ 1, "hf vas decrypt" }, { 1, "hf vas decrypt" },
{ 1, "hf waveshare help" },
{ 1, "hf waveshare load" },
{ 1, "hf xerox help" }, { 1, "hf xerox help" },
{ 1, "hf xerox list" }, { 1, "hf xerox list" },
{ 0, "hf xerox info" }, { 0, "hf xerox info" },

View file

@ -3061,7 +3061,7 @@
}, },
"hf help": { "hf help": {
"command": "hf help", "command": "hf help",
"description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } fudan { Fudan RFIDs... } gallagher { Gallagher DESFire RFIDs... } iclass { ICLASS RFIDs... } ict { ICT MFC/DESfire RFIDs... } jooki { Jooki RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } tesla { TESLA Cards... } texkom { Texkom RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } vas { Apple Value Added Service } xerox { Fuji/Xerox cartridge RFIDs... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags --------------------------------------------------------------------------------------- hf list available offline: yes Alias of `trace list -t raw` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } fudan { Fudan RFIDs... } gallagher { Gallagher DESFire RFIDs... } iclass { ICLASS RFIDs... } ict { ICT MFC/DESfire RFIDs... } jooki { Jooki RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } tesla { TESLA Cards... } texkom { Texkom RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } vas { Apple Value Added Service } waveshare { Waveshare NFC ePaper... } xerox { Fuji/Xerox cartridge RFIDs... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags --------------------------------------------------------------------------------------- hf list available offline: yes Alias of `trace list -t raw` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol",
"notes": [ "notes": [
"hf list --frame -> show frame delay times", "hf list --frame -> show frame delay times",
"hf list -1 -> use trace buffer" "hf list -1 -> use trace buffer"
@ -7084,6 +7084,20 @@
], ],
"usage": "hf mfu view [-hvz] -f <fn>" "usage": "hf mfu view [-hvz] -f <fn>"
}, },
"hf mfu wipe": {
"command": "hf mfu wipe",
"description": "Wipe card to zeros. It will ignore block0,1,2,3 you will need to call it with password in order to wipe the config and sett default pwd/pack Abort by pressing a key New password... FFFFFFFF",
"notes": [
"hf mfu wipe"
],
"offline": false,
"options": [
"-h, --help This help",
"-k, --key <hex> Key for authentication (UL-C 16 bytes, EV1/NTAG 4 bytes)",
"-l Swap entered key's endianness"
],
"usage": "hf mfu wipe [-hl] [-k <hex>]"
},
"hf mfu wrbl": { "hf mfu wrbl": {
"command": "hf mfu wrbl", "command": "hf mfu wrbl",
"description": "Write a block. It autodetects card type.", "description": "Write a block. It autodetects card type.",
@ -7722,6 +7736,28 @@
], ],
"usage": "hf vas reader [-h@v] [--pid <str>] [-f <fn>] [--url <str>]" "usage": "hf vas reader [-h@v] [--pid <str>] [-f <fn>] [--url <str>]"
}, },
"hf waveshare help": {
"command": "hf waveshare help",
"description": "help This help load Load image file to Waveshare NFC ePaper --------------------------------------------------------------------------------------- hf waveshare load available offline: yes Load image file to Waveshare NFC ePaper",
"notes": [
"hf waveshare load -f myfile -m 0 -> 2.13 inch e-paper ( 122, 250 )",
"hf waveshare load -f myfile -m 1 -> 2.9 inch e-paper ( 296, 128 )",
"hf waveshare load -f myfile -m 2 -> 4.2 inch e-paper ( 400, 300 )",
"hf waveshare load -f myfile -m 3 -> 7.5 inch e-paper ( 800, 480 )",
"hf waveshare load -f myfile -m 4 -> 2.7 inch e-paper ( 176, 276 )",
"hf waveshare load -f myfile -m 5 -> 2.13 inch e-paper B (with red) ( 104, 212 )",
"hf waveshare load -f myfile -m 6 -> 1.54 inch e-paper B (with red) ( 200, 200 )",
"hf waveshare load -f myfile -m 7 -> 7.5 inch e-paper HD ( 880, 528 )"
],
"offline": true,
"options": [
"-h, --help This help",
"-m <nr> model number [0 - 7] of your tag",
"-f, --file <fn> specify image to upload to tag",
"-s, --save <fn> save paletized version in file"
],
"usage": "hf waveshare load [-h] -m <nr> -f <fn> [-s <fn>]"
},
"hf xerox dump": { "hf xerox dump": {
"command": "hf xerox dump", "command": "hf xerox dump",
"description": "Dump all memory from a Fuji/Xerox tag ISO/IEC 14443 type B based communications", "description": "Dump all memory from a Fuji/Xerox tag ISO/IEC 14443 type B based communications",
@ -8039,9 +8075,10 @@
"offline": false, "offline": false,
"options": [ "options": [
"-h, --help This help", "-h, --help This help",
"-a, --arg <dec> argument byte" "-a, --arg <dec> argument byte",
"-b <str> UniSniff arg: 14a, 14b, 15, iclass"
], ],
"usage": "hw standalone [-h] [-a <dec>]" "usage": "hw standalone [-h] [-a <dec>] [-b <str>]"
}, },
"hw status": { "hw status": {
"command": "hw status", "command": "hw status",
@ -8889,7 +8926,7 @@
}, },
"lf em 4x70 help": { "lf em 4x70 help": {
"command": "lf em 4x70 help", "command": "lf em 4x70 help",
"description": "help This help --------------------------------------------------------------------------------------- lf em 4x70 brute available offline: no Optimized partial key-update attack of 16-bit key block 7, 8 or 9 of an EM4x70 This attack does NOT write anything to the tag. Before starting this attack, 0000 must be written to the 16-bit key block: 'lf em 4x70 write -b 9 -d 0000'. After success, the 16-bit key block have to be restored with the key found: 'lf em 4x70 write -b 9 -d c0de'", "description": "help This help recover Recover remaining key from partial key --------------------------------------------------------------------------------------- lf em 4x70 brute available offline: no Optimized partial key-update attack of 16-bit key block 7, 8 or 9 of an EM4x70 This attack does NOT write anything to the tag. Before starting this attack, 0000 must be written to the 16-bit key block: 'lf em 4x70 write -b 9 -d 0000'. After success, the 16-bit key block have to be restored with the key found: 'lf em 4x70 write -b 9 -d c0de'",
"notes": [ "notes": [
"lf em 4x70 brute -b 9 --rnd 45F54ADA252AAC --frn 4866BB70 -> bruteforcing key bits k95...k80" "lf em 4x70 brute -b 9 --rnd 45F54ADA252AAC --frn 4866BB70 -> bruteforcing key bits k95...k80"
], ],
@ -8925,7 +8962,7 @@
"lf em 4x70 recover --key F32AA98CF5BE --rnd 45F54ADA252AAC --frn 4866BB70 --grn 9BD180 (pm3 test key)", "lf em 4x70 recover --key F32AA98CF5BE --rnd 45F54ADA252AAC --frn 4866BB70 --grn 9BD180 (pm3 test key)",
"lf em 4x70 recover --key A090A0A02080 --rnd 3FFE1FB6CC513F --frn F355F1A0 --grn 609D60 (research paper key)" "lf em 4x70 recover --key A090A0A02080 --rnd 3FFE1FB6CC513F --frn F355F1A0 --grn 609D60 (research paper key)"
], ],
"offline": false, "offline": true,
"options": [ "options": [
"-h, --help This help", "-h, --help This help",
"--par Add parity bit when sending commands", "--par Add parity bit when sending commands",
@ -8936,6 +8973,36 @@
], ],
"usage": "lf em 4x70 recover [-h] [--par] -k <hex> --rnd <hex> --frn <hex> --grn <hex>" "usage": "lf em 4x70 recover [-h] [--par] -k <hex> --rnd <hex> --frn <hex> --grn <hex>"
}, },
"lf em 4x70 setkey": {
"command": "lf em 4x70 setkey",
"description": "Write new 96-bit key to tag",
"notes": [
"lf em 4x70 setkey -k F32AA98CF5BE4ADFA6D3480B (pm3 test key)",
"lf em 4x70 setkey -k A090A0A02080000000000000 (research paper key)"
],
"offline": false,
"options": [
"-h, --help This help",
"--par Add parity bit when sending commands",
"-k, --key <hex> Key as 12 hex bytes"
],
"usage": "lf em 4x70 setkey [-h] [--par] -k <hex>"
},
"lf em 4x70 setpin": {
"command": "lf em 4x70 setpin",
"description": "Write new PIN",
"notes": [
"lf em 4x70 setpin -p 11223344 -> Write new PIN",
"lf em 4x70 setpin -p 11223344 --par -> Write new PIN using parity commands"
],
"offline": false,
"options": [
"-h, --help This help",
"--par Add parity bit when sending commands",
"-p, --pin <hex> pin, 4 bytes"
],
"usage": "lf em 4x70 setpin [-h] [--par] -p <hex>"
},
"lf em 4x70 unlock": { "lf em 4x70 unlock": {
"command": "lf em 4x70 unlock", "command": "lf em 4x70 unlock",
"description": "Unlock EM4x70 by sending PIN Default pin may be: AAAAAAAA 00000000", "description": "Unlock EM4x70 by sending PIN Default pin may be: AAAAAAAA 00000000",
@ -8967,36 +9034,6 @@
], ],
"usage": "lf em 4x70 write [-h] [--par] -b <dec> -d <hex>" "usage": "lf em 4x70 write [-h] [--par] -b <dec> -d <hex>"
}, },
"lf em 4x70 setkey": {
"command": "lf em 4x70 setkey",
"description": "Write new 96-bit key to tag",
"notes": [
"lf em 4x70 setkey -k F32AA98CF5BE4ADFA6D3480B (pm3 test key)",
"lf em 4x70 setkey -k A090A0A02080000000000000 (research paper key)"
],
"offline": false,
"options": [
"-h, --help This help",
"--par Add parity bit when sending commands",
"-k, --key <hex> Key as 12 hex bytes"
],
"usage": "lf em 4x70 setkey [-h] [--par] -k <hex>"
},
"lf em 4x70 setpin": {
"command": "lf em 4x70 setpin",
"description": "Write PIN",
"notes": [
"lf em 4x70 setpin -p 11223344 -> Write new PIN",
"lf em 4x70 setpin -p 11223344 --par -> Write new PIN using parity commands"
],
"offline": false,
"options": [
"-h, --help This help",
"--par Add parity bit when sending commands",
"-p, --pin <hex> pin, 4 bytes"
],
"usage": "lf em 4x70 setpin [-h] [--par] -p <hex>"
},
"lf em help": { "lf em help": {
"command": "lf em help", "command": "lf em help",
"description": "help This help 410x { EM 4102 commands... } 4x05 { EM 4205 / 4305 / 4369 / 4469 commands... } 4x50 { EM 4350 / 4450 commands... } 4x70 { EM 4070 / 4170 commands... } ======================================================================================= lf em 410x { EM 4102 commands... } --------------------------------------------------------------------------------------- lf em 410x help available offline: yes help This help demod demodulate a EM410x tag from the GraphBuffer --------------------------------------------------------------------------------------- lf em 410x demod available offline: yes Try to find EM 410x preamble, if found decode / descramble data", "description": "help This help 410x { EM 4102 commands... } 4x05 { EM 4205 / 4305 / 4369 / 4469 commands... } 4x50 { EM 4350 / 4450 commands... } 4x70 { EM 4070 / 4170 commands... } ======================================================================================= lf em 410x { EM 4102 commands... } --------------------------------------------------------------------------------------- lf em 410x help available offline: yes help This help demod demodulate a EM410x tag from the GraphBuffer --------------------------------------------------------------------------------------- lf em 410x demod available offline: yes Try to find EM 410x preamble, if found decode / descramble data",
@ -12529,8 +12566,8 @@
} }
}, },
"metadata": { "metadata": {
"commands_extracted": 723, "commands_extracted": 725,
"extracted_by": "PM3Help2JSON v1.00", "extracted_by": "PM3Help2JSON v1.00",
"extracted_on": "2024-03-12T00:21:47" "extracted_on": "2024-03-14T10:14:29"
} }
} }

View file

@ -610,6 +610,7 @@ Check column "offline" for their availability.
|`hf mfu restore `|N |`Restore a dump file onto a tag` |`hf mfu restore `|N |`Restore a dump file onto a tag`
|`hf mfu tamper `|N |`NTAG 213TT - Configure the tamper feature` |`hf mfu tamper `|N |`NTAG 213TT - Configure the tamper feature`
|`hf mfu view `|Y |`Display content from tag dump file` |`hf mfu view `|Y |`Display content from tag dump file`
|`hf mfu wipe `|N |`Wipe card to zeros and default key`
|`hf mfu wrbl `|N |`Write block` |`hf mfu wrbl `|N |`Write block`
|`hf mfu eload `|N |`Upload file into emulator memory` |`hf mfu eload `|N |`Upload file into emulator memory`
|`hf mfu esave `|N |`Save emulator memory to file` |`hf mfu esave `|N |`Save emulator memory to file`
@ -773,6 +774,16 @@ Check column "offline" for their availability.
|`hf vas decrypt `|Y |`Decrypt a previously captured VAS cryptogram` |`hf vas decrypt `|Y |`Decrypt a previously captured VAS cryptogram`
### hf waveshare
{ Waveshare NFC ePaper... }
|command |offline |description
|------- |------- |-----------
|`hf waveshare help `|Y |`This help`
|`hf waveshare load `|Y |`Load image file to Waveshare NFC ePaper`
### hf xerox ### hf xerox
{ Fuji/Xerox cartridge RFIDs... } { Fuji/Xerox cartridge RFIDs... }
@ -960,8 +971,8 @@ Check column "offline" for their availability.
|`lf em 4x70 write `|N |`Write EM4x70` |`lf em 4x70 write `|N |`Write EM4x70`
|`lf em 4x70 unlock `|N |`Unlock EM4x70 for writing` |`lf em 4x70 unlock `|N |`Unlock EM4x70 for writing`
|`lf em 4x70 auth `|N |`Authenticate EM4x70` |`lf em 4x70 auth `|N |`Authenticate EM4x70`
|`lf em 4x70 setpin `|N |`Write new PIN` |`lf em 4x70 setpin `|N |`Write PIN`
|`lf em 4x70 setkey `|N |`Write new key` |`lf em 4x70 setkey `|N |`Write key`
|`lf em 4x70 recover `|Y |`Recover remaining key from partial key` |`lf em 4x70 recover `|Y |`Recover remaining key from partial key`
|`lf em 4x70 autorecover `|N |`Recover entire key from writable tag` |`lf em 4x70 autorecover `|N |`Recover entire key from writable tag`