Recovering iClass Legacy flexClass picopass

HID iClass Legacy / flexClass

iClass legacy chips (the picopass family in flexClass implants) don’t really get “bricked” the way a magic Mifare can. They can be soft-locked when block 3 (the auth key block) gets written with the wrong value, leaving you unable to authenticate with any dictionary key. This section covers two recovery paths.

Important concepts before you start:

  • Block 3 holds the diversified auth key. Every iClass legacy card stores its working auth key in block 3. The card has two operating modes:
    • Personalization mode: block 1 fuses are intact. Writes to block 3 land directly. New block 3 = data you wrote.
    • Application mode: block 1 fuses are blown (this is the state of every issued card you’ll encounter). Writes to block 3 are XOR’d with the current contents. New block 3 = data XOR current_blk3. This is what makes recovery counter-intuitive.
  • Run hf ic info first to determine which mode you’re in. The output explicitly tells you.
  • Document every write you do. The recovery procedure for a soft-locked application mode card requires the exact data you last wrote and the exact key you last used to authenticate. Without those, you can’t get back.

This procedure is for standard (non-elite) HID iClass legacy only. Elite keys and SE cards are out of scope.

Scenario 1: Switching keys (default ↔ master)

You have a card on a known key (typically the HID default), and you want to switch it to a different key (e.g., the HID master key for a working reader).

hf ic chk -f iclass_default_keys.dic

Note the keyslot of the matching key, and hf ic managekeys -p to see the slot table. Then:

hf ic calcnewkey --oki <current_keyslot> --nki <target_keyslot>

This prints both New div key and Xor div key. Which one to write to block 3 depends on the mode:

  • Application mode: write Xor div key to block 3, authenticated with the current keyslot:
    hf ic wrbl -b 3 -d <Xor_div_key> --ki <current_keyslot>
    
  • Personalization mode: write New div key to block 3 instead:
    hf ic wrbl -b 3 -d <New_div_key> --ki <current_keyslot>
    

Verify with hf ic chk -f iclass_default_keys.dic again. The matching keyslot should now be the target.

Scenario 2: Soft-locked block 3 (App mode, with logs)

You wrote the wrong value to block 3 and now no dictionary key works. Don’t write anything else yet. Find your last write command in the proxmark3 logs (client/.proxmark3/logs/) — you need the data you wrote (-d ...) and the raw key you used to authenticate (-k ... if you used --raw, or the diversified value of the keyslot you used).

Step 1) Reconstruct what’s actually in block 3 right now:

current_blk3 = last_data XOR last_raw_key

Use a hex calculator (Windows Calculator in programmer mode works). Each byte XOR’d byte-by-byte. If the result has fewer than 16 hex digits, pad with leading zeros.

Step 2) Verify the reconstruction is correct by reading any block:

hf ic rdbl -b 7 -k <current_blk3> --raw

If this returns block 7 cleanly, your reconstruction is correct and the card is recoverable.

Step 3) Pick the key you want to be on after recovery (typically the default key, slot 0). Compute the diversified version of that key for this specific card:

hf ic calcnewkey --old 0000000000000000 --nki 0

The New div key from the output is what you want sitting in block 3.

Step 4 — compute the data you need to write to make that happen. App mode XOR semantics again:

write_data = current_blk3 XOR new_div_key

Step 5) Write it, authenticated with current_blk3 as a raw key:

hf ic wrbl -b 3 -d <write_data> -k <current_blk3> --raw

Step 6) Verify:

hf ic chk -f iclass_default_keys.dic
hf ic dump --ki 0

If chk reports the default key in slot 0 and dump succeeds, you’re back. If not, repeat the procedure using the data you wrote in Step 5 as the new last_data and current_blk3 as the new last_raw_key.

Soft-locked block 3 (Personalization mode)

Perso mode is simpler since there is no XOR. Whatever you last wrote IS what’s in block 3. Use it as the raw key directly:

hf ic rdbl -b 7 -k <last_data> --raw

To restore the default key, calcnewkey for default and write the New div key directly with -k <last_data> --raw.

When recovery is not possible

  • You don’t have logs of the last write. Without the data + raw key pair, App-mode block 3 is unrecoverable because you can’t guess your way out of 64 bits.
  • The card is iClass SE or Seos. These use HID’s private keys for authentication; recovery is not possible without those keys.
  • The card is iClass Elite and you don’t have the elite master. Out of scope here; see hf ic calcnewkey --elite and the loclass attack if you have reader access. If you do have reader access, you may also want to check the errata section below on “Elite iClass Hacking”.

Final notes

  • Every wrong block 3 write in App mode XORs you further from the working key. Stop and document before each retry.
  • Do not change the mode (Personalization → Application) intentionally. You give up future flexibility for nothing.
  • The default HID iClass authentication key (AE A6 84 A6 DA B2 32 78) ships with iclass_default_keys.dic. The HID master is not bundled and must be sniffed from a working reader (hf iclass sim -t 2) or supplied by another means.

Errata; Elite iClass Hacking

Elite iClass Hacking.pdf (13.4 MB)

2 Likes