Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hf mfdes value can't credit/debit value files when communication mode isn't plain #2712

Open
Lolbird123 opened this issue Jan 9, 2025 · 3 comments

Comments

@Lolbird123
Copy link

Describe the bug
the hf mfdes value command with -o credit or -o debit fails with Desfire ValueFileOperations (0x0c) command ( error ) Result: -20
however, the hf mfdes write command (optionally with --debit) can do so just fine

To Reproduce
Steps to reproduce the behavior:

  1. create an application on a desfire card with hf mfdes createapp --aid 000001
  2. create a value file in the application with hf mfdes createvaluefile --aid 000001 --fid 01 --lower 00000000 --upper 7fffffff --value 00000000
  3. attempt (and fail) to credit the file with hf mfdes value --aid 000001 --fid 01 -o credit -d 00000001
  4. read back the value file with hf mfdes value --aid 000001 --fid 01 -o get to see it is still 0
  5. attempt (and succeed) to credit the file with hf mfdes write --aid 000001 --fid 01 -d 00000064
  6. read back the value file with hf mfdes value --aid 000001 --fid 01 -o get to see it was credited successfully

Expected behavior
the value file would be successfully credited/debited by the given value

Screenshots
Commands and responses listed previously

Desktop (please complete the following information):
OS: Arch Linux

 [usb] pm3 --> hw version

 [ Proxmark3 RFID instrument ]

 [ Client ]
  Iceman/master/v4.19552-189-g6b26afe85-suspect 2025-01-08 16:24:50 f5481f0c5
  compiled with............. GCC 14.2.1 20240910
  platform.................. Linux / x86_64
  Readline support.......... present
  QT GUI support............ present
  native BT support......... present
  Python script support..... present ( 3.13.1 )
  Python SWIG support....... present
  Lua script support........ present ( 5.4.7 )
  Lua SWIG support.......... present

 [ Proxmark3 ]
  device.................... RDV4
  firmware.................. RDV4
  external flash............ present
  smartcard reader.......... present
  FPC USART for BT add-on... absent

 [ ARM ]
  bootrom: Iceman/master/v4.19552-189-g6b26afe85-suspect 2025-01-08 16:24:43 f5481f0c5
       os: Iceman/master/v4.19552-189-g6b26afe85-suspect 2025-01-08 16:24:54 f5481f0c5
  compiled with GCC 14.2.0

 [ FPGA ] 
 fpga_pm3_hf.ncd image 2s30vq100 2024-02-03 15:12:20
 fpga_pm3_lf.ncd image 2s30vq100 2024-02-03 15:12:10
 fpga_pm3_felica.ncd image 2s30vq100 2024-02-03 15:12:41
 fpga_pm3_hf_15.ncd image 2s30vq100 2024-02-03 15:12:31

 [ Hardware ]
  --= uC: AT91SAM7S512 Rev B
  --= Embedded Processor: ARM7TDMI
  --= Internal SRAM size: 64K bytes
  --= Architecture identifier: AT91SAM7Sxx Series
  --= Embedded flash memory 512K bytes ( 73% used )
[usb] pm3 --> hw status
[#] Memory
[#]   BigBuf_size............. 39420
[#]   Available memory........ 39420
[#] Tracing
[#]   tracing ................ 1
[#]   traceLen ............... 451
[#] Current FPGA image
[#]   mode.................... fpga_pm3_hf.ncd image 2s30vq100 2024-02-03 15:12:20
[#] Flash memory
[#]   Baudrate................ 24 MHz
[#]   Init.................... ok
[#]   Mfr ID / Dev ID......... EF / 11
[#]   JEDEC Mfr ID / Dev ID... EF / 3012
[#]   Memory size............. 256 kB (4 pages * 64k)
[#]   Unique ID (be).......... 0x2BCA3D63922861D5
[#] Smart card module (ISO 7816)
[#]   version................. v4.42 ( ok )
[#] LF Sampling config
[#]   [q] divisor............. 95 ( 125.00 kHz )
[#]   [b] bits per sample..... 8
[#]   [d] decimation.......... 1
[#]   [a] averaging........... yes
[#]   [t] trigger threshold... 0
[#]   [s] samples to skip..... 0 
[#] 
[#] LF T55XX config
[#]            [r]               [a]   [b]   [c]   [d]   [e]   [f]   [g]
[#]            mode            |start|write|write|write| read|write|write
[#]                            | gap | gap |  0  |  1  | gap |  2  |  3
[#] ---------------------------+-----+-----+-----+-----+-----+-----+------
[#] fixed bit length (default) |  29 |  17 |  15 |  47 |  15 | n/a | n/a | 
[#]     long leading reference |  29 |  17 |  15 |  47 |  15 | n/a | n/a | 
[#]               leading zero |  29 |  17 |  15 |  40 |  15 | n/a | n/a | 
[#]    1 of 4 coding reference |  29 |  17 |  15 |  31 |  15 |  47 |  63 | 
[#] 
[#] HF 14a config
[#]   [a] Anticol override.... std    ( follow standard )
[#]   [b] BCC override........ std    ( follow standard )
[#]   [2] CL2 override........ std    ( follow standard )
[#]   [3] CL3 override........ std    ( follow standard )
[#]   [r] RATS override....... std    ( follow standard )
[#] Transfer Speed
[#]   Sending packets to client...
[#]   Time elapsed................... 500ms
[#]   Bytes transferred.............. 343040
[#]   Transfer Speed PM3 -> Client... 686080 bytes/s
[#] Various
[#]   Max stack usage......... 3984 / 8480 bytes
[#]   Debug log level......... 1 ( error )
[#]   ToSendMax............... 75
[#]   ToSend BUFFERSIZE....... 2308
[#]   Slow clock.............. 32778 Hz
[#] Installed StandAlone Mode
[#]   LF HID26 standalone - aka SamyRun (Samy Kamkar)
[#] Flash memory dictionary loaded
[#]   Mifare.................. 2311 keys (spiffs: dict_mf.bin)
[#]   T55xx................... 125 keys (spiffs: dict_t55xx.bin)
[#]   iClass.................. 29 keys (spiffs: dict_iclass.bin)
[usb] pm3 --> hw tune

[=] -------- Reminder ----------------------------
[=] `hw tune` doesn't actively tune your antennas.
[=] It's only informative.
[=] Measuring antenna characteristics...
 🕛   9

[=] -------- LF Antenna ----------
[+] 125.00 kHz ........... 72.38 V
[+] 134.83 kHz ........... 33.93 V
[+] 125.00 kHz optimal.... 72.38 V
[+] 
[+] Approx. Q factor measurement
[+] Frequency bandwidth... 11.9
[+] Peak voltage.......... 12.6
[+] LF antenna............ ok

[=] -------- HF Antenna ----------
[+] 13.56 MHz............. 45.86 V
[+] 
[+] Approx. Q factor measurement
[+] Peak voltage.......... 8.0
[+] HF antenna ( ok )

[=] -------- LF tuning graph ------------
[+] Orange line - divisor 95 / 125.00 kHz
[+] Blue line - divisor   88 / 134.83 kHz

Additional context
confirmed by other members of the discord in the desfire channel
verbose output from the value and write commands:

[usb] pm3 --> hf mfdes value --aid 000001 --fid 01 -o credit -d 00000001 -v -a
[=] Key num: 0 Key algo: des Key[8]: 00 00 00 00 00 00 00 00 
[=] Secure channel: n/a Command set: niso Communication mode: mac
[+] Setting ISODEP -> inactive
[+] >>>> 90 5A 00 00 03 01 00 00 00 
[+] Setting ISODEP -> inactive
[+] Setting ISODEP -> NFC-A
[+] <<<< 91 00 
[=] AID 000001 is selected
[=] Auth: cmd: 0x1a keynum: 0x00
[+] >>>> 90 1A 00 00 01 00 00 
[+] <<<< 81 C4 8C 86 7C 18 3F CB 91 AF 
[+] >>>> 90 AF 00 00 10 C2 CE 2C 22 5F 4C BC 1D EA EF 7C 50 94 F2 B4 94 00 
[+] <<<< 71 E5 B9 40 BC 7A D5 41 91 00 
[=] Session key : 01 02 03 04 49 9D CC E8 
[=] Desfire  authenticated
[=] AID 000001 file 01 operation: credit value: 0x00000001
[+] >>>> 90 0C 00 00 0D 01 01 00 00 00 0D 32 74 64 B2 73 FE A7 00 
[+] <<<< 91 7E 
[!!] 🚨 APDU(900c) ERROR: [0x917E] Length of command string invalid
[!!] 🚨 Desfire ValueFileOperations (0x0c) command ( error ) Result: -20
[+] Setting ISODEP -> inactive
[usb] pm3 --> hf mfdes write --aid 000001 --fid 01 -d 00000001 -a -v
[=] Key num: 0 Key algo: des Key[8]: 00 00 00 00 00 00 00 00 
[=] Secure channel: n/a Command set: niso Communication mode: mac
[+] Setting ISODEP -> inactive
[+] >>>> 90 5A 00 00 03 01 00 00 00 
[+] Setting ISODEP -> inactive
[+] Setting ISODEP -> NFC-A
[+] <<<< 91 00 
[=] AID 000001 is selected
[=] Auth: cmd: 0x1a keynum: 0x00
[+] >>>> 90 1A 00 00 01 00 00 
[+] <<<< A4 61 50 64 7B 81 53 00 91 AF 
[+] >>>> 90 AF 00 00 10 50 4E DD 5A C4 99 2A 38 0C B0 EC 16 80 8F 7B F0 00 
[+] <<<< 6F 76 63 6B F2 E1 43 C8 91 00 
[=] Session key : 01 02 03 04 13 C8 0E 90 
[=] Desfire  authenticated
[+] >>>> 90 F5 00 00 01 01 00 
[+] <<<< 02 00 00 00 00 00 00 00 FF FF FF 7F 01 00 00 00 00 66 03 AE 8B A7 7E 86 0D 91 00 
[=] Received MAC OK
[=] Got file type: Value. Option: value. comm mode: plain
[+] >>>> 90 0C 00 00 05 01 01 00 00 00 00 
[+] <<<< 5C 2F 6A 99 40 72 95 1F 91 00 
[=] Received MAC OK
[=] Credit value file 01 (credit)  success
[+] >>>> 90 C7 00 00 00 
[+] <<<< 54 30 F2 D6 E1 36 0C 6E 91 00 
[=] Received MAC OK
[=] Commit ( ok )
[=] Write value file 01 success
[+] Setting ISODEP -> inactive
@hornet-hacker
Copy link

hornet-hacker commented Jan 10, 2025

The added context above is mine. I ran those commands intentionally with the command flags -v -a so as to show APDUs and verbose output. It appears that the process flow used by hf mfdes value is missing steps that are included in hf mfdes write, namely it appears that hf mfdes write queries the air/file to retrieve the value first, and then performs a commit after the value transaction.

@Eltrick
Copy link
Contributor

Eltrick commented Jan 10, 2025

This is the result of mismatched default communication modes.
hf mfdes createvaluefile with no set communication mode for the created file defaults to plain mode, while hf mfdes value with no set communication mode defaults to mac.
Please specify the communication mode to use for hf mfdes value

@Lolbird123
Copy link
Author

Lolbird123 commented Jan 10, 2025

crediting/debiting with hf mfdes value does work if the file is set to plain access mode and you manually specify that with the value command (hf mfdes value --cmode plain).

[usb] pm3 --> hf mfd createvaluefile --aid 000001 --fid 01 --amode plain --lower 00000000 --upper 7fffffff --value 00000000
[=] ---- Create file settings ----
[+] File type        : Value
[+] File number      : 0x01 (1)
[+] File comm mode   : Plain
[+] Additional access: No
[+] Access rights    : EEEE
[+]   read......... free
[+]   write........ free
[+]   read/write... free
[+]   change....... free
[=] Lower limit... 0 / 0x00000000
[=] Upper limit... 2147483647 / 0x7FFFFFFF
[=] Value............ 0 / 0x00000000
[=] Limited credit... 0 - disabled
[=] GetValue access... Not Free
[+] Value file 01 in the app 000001 created successfully
[usb] pm3 --> hf mfd value --aid 000001 --fid 01 --cmode plain -o get
[+] Value: 0 (0x00000000)
[usb] pm3 --> hf mfd value --aid 000001 --fid 01 --cmode plain -o credit -d 00000001 -av
[=] Key num: 0 Key algo: des Key[8]: 00 00 00 00 00 00 00 00 
[=] Secure channel: n/a Command set: niso Communication mode: plain
[+] Setting ISODEP -> inactive
[+] >>>> 90 5A 00 00 03 01 00 00 00 
[+] Setting ISODEP -> inactive
[+] Setting ISODEP -> NFC-A
[+] <<<< 91 00 
[=] AID 000001 is selected
[=] Auth: cmd: 0x1a keynum: 0x00
[+] >>>> 90 1A 00 00 01 00 00 
[+] <<<< 38 AB C4 1F 2C 71 CD 23 91 AF 
[+] >>>> 90 AF 00 00 10 B1 D7 CF 56 DD 7A 94 80 8C A0 CD 05 3E 0A E0 9A 00 
[+] <<<< E4 8C 45 4B 10 09 E7 42 91 00 
[=] Session key : 01 02 03 04 A2 71 48 24 
[=] Desfire  authenticated
[=] AID 000001 file 01 operation: credit value: 0x00000001
[+] >>>> 90 0C 00 00 05 01 01 00 00 00 00 
[+] <<<< BA B9 91 39 41 5D 6A F7 91 00 
[=] Received MAC OK
[=] Operation ( credit )ok
[+] >>>> 90 C7 00 00 00 
[+] <<<< D1 DF D3 39 DD 80 CC E4 91 00 
[=] Received MAC OK
[=] Commit ( ok )
[+] Value changed successfully
[+] Setting ISODEP -> inactive
[usb] pm3 --> hf mfd value --aid 000001 --fid 01 --cmode plain -o get
[+] Value: 1 (0x00000001)

however when the file is using any other access mode (mac or encrypt), it fails with APDU(900c) ERROR: [0x917E] Length of command string invalid, additionally the encrypt access mode has a crc32 error when retrieving the value, though it still reads it successfully

with mac access mode:

[usb] pm3 --> hf mfd createvaluefile --aid 000001 --fid 02 --amode mac --lower 00000000 --upper 7fffffff --value 00000000
[=] ---- Create file settings ----
[+] File type        : Value
[+] File number      : 0x02 (2)
[+] File comm mode   : MAC
[+] Additional access: No
[+] Access rights    : EEEE
[+]   read......... free
[+]   write........ free
[+]   read/write... free
[+]   change....... free
[=] Lower limit... 0 / 0x00000000
[=] Upper limit... 2147483647 / 0x7FFFFFFF
[=] Value............ 0 / 0x00000000
[=] Limited credit... 0 - disabled
[=] GetValue access... Not Free
[+] Value file 02 in the app 000001 created successfully
[usb] pm3 --> hf mfd value --aid 000001 --fid 02 --cmode mac -o get
[+] Value: 0 (0x00000000)
[usb] pm3 --> hf mfd value --aid 000001 --fid 02 --cmode mac -o credit -d 00000001 -av
[=] Key num: 0 Key algo: des Key[8]: 00 00 00 00 00 00 00 00 
[=] Secure channel: n/a Command set: niso Communication mode: mac
[+] Setting ISODEP -> inactive
[+] >>>> 90 5A 00 00 03 01 00 00 00 
[+] Setting ISODEP -> inactive
[+] Setting ISODEP -> NFC-A
[+] <<<< 91 00 
[=] AID 000001 is selected
[=] Auth: cmd: 0x1a keynum: 0x00
[+] >>>> 90 1A 00 00 01 00 00 
[+] <<<< 85 92 5A 55 E0 0D 07 55 91 AF 
[+] >>>> 90 AF 00 00 10 32 59 25 06 D1 64 9C B6 DD 7A A6 D9 49 20 44 DD 00 
[+] <<<< A6 25 75 1E 94 D6 F2 DE 91 00 
[=] Session key : 01 02 03 04 10 36 29 51 
[=] Desfire  authenticated
[=] AID 000001 file 02 operation: credit value: 0x00000001
[+] >>>> 90 0C 00 00 0D 02 01 00 00 00 7C B1 54 64 78 55 8E 3A 00 
[+] <<<< 91 7E 
[!!] 🚨 APDU(900c) ERROR: [0x917E] Length of command string invalid
[!!] 🚨 Desfire ValueFileOperations (0x0c) command ( error ) Result: -20
[+] Setting ISODEP -> inactive
[usb] pm3 --> hf mfd value --aid 000001 --fid 02 --cmode mac -o get
[+] Value: 0 (0x00000000)

with encrypt/full access mode:

[usb] pm3 --> hf mfd createvaluefile --aid 000001 --fid 03 --amode encrypt --lower 00000000 --upper 7fffffff --value 00000000
[=] ---- Create file settings ----
[+] File type        : Value
[+] File number      : 0x03 (3)
[+] File comm mode   : Full
[+] Additional access: No
[+] Access rights    : EEEE
[+]   read......... free
[+]   write........ free
[+]   read/write... free
[+]   change....... free
[=] Lower limit... 0 / 0x00000000
[=] Upper limit... 2147483647 / 0x7FFFFFFF
[=] Value............ 0 / 0x00000000
[=] Limited credit... 0 - disabled
[=] GetValue access... Not Free
[+] Value file 03 in the app 000001 created successfully
[usb] pm3 --> hf mfd value --aid 000001 --fid 03 --cmode encrypt -o get -av
[=] Key num: 0 Key algo: des Key[8]: 00 00 00 00 00 00 00 00 
[=] Secure channel: n/a Command set: niso Communication mode: encrypt
[+] Setting ISODEP -> inactive
[+] >>>> 90 5A 00 00 03 01 00 00 00 
[+] Setting ISODEP -> inactive
[+] Setting ISODEP -> NFC-A
[+] <<<< 91 00 
[=] AID 000001 is selected
[=] Auth: cmd: 0x1a keynum: 0x00
[+] >>>> 90 1A 00 00 01 00 00 
[+] <<<< A7 70 14 E9 B8 50 52 9B 91 AF 
[+] >>>> 90 AF 00 00 10 CD D9 7D C8 5F 14 05 41 85 53 91 73 B5 CC AD 41 00 
[+] <<<< 6E 5D 9D E1 1E BB 55 B3 91 00 
[=] Session key : 01 02 03 04 C6 1D 82 77 
[=] Desfire  authenticated
[=] AID 000001 file 03 operation: get value: 0x00000000
[+] >>>> 90 6C 00 00 01 03 00 
[+] <<<< 00 00 00 00 C7 FA A3 EB 84 36 B0 38 91 00 
[!] ⚠  CRC32 error.
[=] Operation ( get )ok
[+] Value: 0 (0x00000000)
[+] Setting ISODEP -> inactive
[usb] pm3 --> hf mfd value --aid 000001 --fid 03 --cmode encrypt -o credit -d 00000001 -av
[=] Key num: 0 Key algo: des Key[8]: 00 00 00 00 00 00 00 00 
[=] Secure channel: n/a Command set: niso Communication mode: encrypt
[+] Setting ISODEP -> inactive
[+] >>>> 90 5A 00 00 03 01 00 00 00 
[+] Setting ISODEP -> inactive
[+] Setting ISODEP -> NFC-A
[+] <<<< 91 00 
[=] AID 000001 is selected
[=] Auth: cmd: 0x1a keynum: 0x00
[+] >>>> 90 1A 00 00 01 00 00 
[+] <<<< 16 AB 9C CD 7D 24 DD 48 91 AF 
[+] >>>> 90 AF 00 00 10 4E E6 16 56 7F 0D 6F 06 D2 3E DA B0 8C 75 92 86 00 
[+] <<<< 0C CC 1E 1B 60 86 D6 10 91 00 
[=] Session key : 01 02 03 04 24 F2 C7 BE 
[=] Desfire  authenticated
[=] AID 000001 file 03 operation: credit value: 0x00000001
[+] >>>> 90 0C 00 00 09 03 07 86 A7 FF 2A C6 8A 7E 00 
[+] <<<< 91 7E 
[!!] 🚨 APDU(900c) ERROR: [0x917E] Length of command string invalid
[!!] 🚨 Desfire ValueFileOperations (0x0c) command ( error ) Result: -20
[+] Setting ISODEP -> inactive
[usb] pm3 --> hf mfd value --aid 000001 --fid 03 --cmode encrypt -o get
[!] ⚠  CRC32 error.
[+] Value: 0 (0x00000000)

so the problem appears to be in the command's handling of those 2 communication modes

@Lolbird123 Lolbird123 changed the title hf mfdes value can't credit/debit value files hf mfdes value can't credit/debit value files when communication mode isn't plain Jan 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants