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));
if (value) {
set_single_ssr_bit(ssr, bit_index);
}
else {
} else {
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) {
ASSERT(k96 != 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
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;
// 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));
ssr->Raw <<= 1; // starts the process ... it's now an unstable value
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 ---^^
ASSERT(ssr != nullptr);
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_b)) result.Raw |= (1u << 18);
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₃₉
// 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₈₈
// ...
@ -821,8 +822,7 @@ static void retro_generator_impl(
const ID48LIB_NONCE *n,
ID48LIB_FRN *frn28_out,
ID48LIB_GRN *grn20_out
)
{
) {
ASSERT(k != nullptr);
ASSERT(n != nullptr);
ASSERT(frn28_out != nullptr);
@ -834,7 +834,8 @@ static void retro_generator_impl(
// get 55-bit successor state input
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++) {
ASSERT(is_ssr_state_stable(&ssr));
@ -867,7 +868,8 @@ static void retro_generator_impl(
// internal function
ID48LIBX_SUCCESSOR_RESULT id48libx_retro003_successor(const ID48LIBX_STATE_REGISTERS *initial_state, uint8_t input_bit) {
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;
bool output_bit = calculate_successor_state(&s, !!input_bit);
r.state.Raw = s.Raw;
@ -880,7 +882,8 @@ ID48LIBX_STATE_REGISTERS id48libx_retro003_init(const ID48LIB_KEY* key, const I
ASSERT(nonce != nullptr);
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;
return result;
}
@ -891,7 +894,6 @@ void id48lib_generator(
const ID48LIB_NONCE *n,
ID48LIB_FRN *frn28_out,
ID48LIB_GRN *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[ 1] :== O₃₆ .. O₄₃
// grn[ 2] :== O₄₄..O₄₇ 0000
EXPECTED_OUTPUT_BITS result; result.Raw = 0u;
result.Raw <<= 4; 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₂₈
EXPECTED_OUTPUT_BITS result;
result.Raw = 0u;
result.Raw <<= 4;
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 <<= 8; 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₀₀
result.Raw <<= 4;
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[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;
}
/// <summary>
@ -224,8 +232,7 @@ static void init(
const ID48LIB_NONCE *input_nonce,
const ID48LIB_FRN *input_frn,
const ID48LIB_GRN *input_grn
)
{
) {
memset(&g_S, 0, sizeof(RECOVERY_STATE));
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];
@ -271,8 +278,7 @@ static bool get_next_potential_key(
g_S.is_fresh_initialization = false;
k_low.Raw = 0ull;
current_key_bit_shift = 47;
}
else {
} else {
// by definition, a returned potential key had all the bits defined
current_key_bit_shift = 0;
k_low = g_S.last_returned_potential_key;
@ -421,8 +427,7 @@ void id48lib_key_recovery_init(
const ID48LIB_NONCE *input_nonce,
const ID48LIB_FRN *input_frn,
const ID48LIB_GRN *input_grn
)
{
) {
init(input_partial_key, input_nonce, input_frn, input_grn);
}
bool id48lib_key_recovery_next(

View file

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

View file

@ -3061,7 +3061,7 @@
},
"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": [
"hf list --frame -> show frame delay times",
"hf list -1 -> use trace buffer"
@ -7084,6 +7084,20 @@
],
"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": {
"command": "hf mfu wrbl",
"description": "Write a block. It autodetects card type.",
@ -7722,6 +7736,28 @@
],
"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": {
"command": "hf xerox dump",
"description": "Dump all memory from a Fuji/Xerox tag ISO/IEC 14443 type B based communications",
@ -8039,9 +8075,10 @@
"offline": false,
"options": [
"-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": {
"command": "hw status",
@ -8889,7 +8926,7 @@
},
"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": [
"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 A090A0A02080 --rnd 3FFE1FB6CC513F --frn F355F1A0 --grn 609D60 (research paper key)"
],
"offline": false,
"offline": true,
"options": [
"-h, --help This help",
"--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>"
},
"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": {
"command": "lf em 4x70 unlock",
"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>"
},
"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": {
"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",
@ -12529,8 +12566,8 @@
}
},
"metadata": {
"commands_extracted": 723,
"commands_extracted": 725,
"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 tamper `|N |`NTAG 213TT - Configure the tamper feature`
|`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 eload `|N |`Upload file into emulator memory`
|`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 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
{ Fuji/Xerox cartridge RFIDs... }
@ -960,8 +971,8 @@ Check column "offline" for their availability.
|`lf em 4x70 write `|N |`Write EM4x70`
|`lf em 4x70 unlock `|N |`Unlock EM4x70 for writing`
|`lf em 4x70 auth `|N |`Authenticate EM4x70`
|`lf em 4x70 setpin `|N |`Write new PIN`
|`lf em 4x70 setkey `|N |`Write new key`
|`lf em 4x70 setpin `|N |`Write PIN`
|`lf em 4x70 setkey `|N |`Write key`
|`lf em 4x70 recover `|Y |`Recover remaining key from partial key`
|`lf em 4x70 autorecover `|N |`Recover entire key from writable tag`