MIFARE_CLASSIC(3)

πŸŽ€ NAME πŸŽ€

hiii bestie, welcome to mifare_classic(3) β€” the manual page for the Mifare Classic Manipulation Functions πŸ’– this is the whole squad, no cap:

  • mifare_classic_connect
  • mifare_classic_disconnect
  • mifare_classic_authenticate
  • mifare_classic_read
  • mifare_classic_init_value
  • mifare_classic_read_value
  • mifare_classic_write
  • mifare_classic_increment
  • mifare_classic_decrement
  • mifare_classic_restore
  • mifare_classic_transfer
  • mifare_classic_get_trailer_block_permission
  • mifare_classic_get_data_block_permission
  • mifare_classic_format_sector
  • mifare_classic_trailer_block
  • mifare_classic_block_sector
  • mifare_classic_sector_first_block
  • mifare_classic_sector_block_count
  • mifare_classic_sector_last_block

✨ LIBRARY ✨

Mifare card manipulation library, aka libfreefare, and you link it with -lfreefare 🫢


🌸 SYNOPSIS 🌸

#include <freefare.h>

int
mifare_classic_connect(MifareTag tag);

int
mifare_classic_disconnect(MifareTag tag);

int
mifare_classic_authenticate(MifareTag tag,
    const MifareClassicBlockNumber block, const MifareClassicKey key,
    const MifareClassicKeyType key_type);

int
mifare_classic_read(MifareTag tag, const MifareClassicBlockNumber block,
    MifareClassicBlock *data);

int
mifare_classic_init_value(MifareTag tag,
    const MifareClassicBlockNumber block, const int32_t value,
    const MifareClassicBlockNumber adr);

int
mifare_classic_read_value(MifareTag tag,
    const MifareClassicBlockNumber block, int32_t *value,
    MifareClassicBlockNumber *adr);

int
mifare_classic_write(MifareTag tag,
    const MifareClassicBlockNumber block,
    const MifareClassicBlock data);

int
mifare_classic_increment(MifareTag tag,
    const MifareClassicBlockNumber block, const uint32_t amount);

int
mifare_classic_decrement(MifareTag tag,
    const MifareClassicBlockNumber block, const uint32_t amount);

int
mifare_classic_restore(MifareTag tag,
    const MifareClassicBlockNumber block);

int
mifare_classic_transfer(MifareTag tag,
    const MifareClassicBlockNumber block);

int
mifare_classic_get_trailer_block_permission(MifareTag tag,
    const MifareClassicBlockNumber block, const uint16_t permission,
    const MifareClassicKeyType key_type);

int
mifare_classic_get_data_block_permission(MifareTag tag,
    const MifareClassicBlockNumber block,
    const unsigned char permission,
    const MifareClassicKeyType key_type);

int
mifare_classic_format_sector(MifareTag tag,
    const MifareClassicSectorNumber sector);

void
mifare_classic_trailer_block(MifareClassicBlock *block,
    const MifareClassicKey key_a, const uint8_t ab_0,
    const uint8_t ab_1, const uint8_t ab_2, const uint8_t ab_tb,
    const uint8_t gpb, const MifareClassicKey key_b);

MifareClassicSectorNumber
mifare_classic_block_sector(MifareClassicBlockNumber block);

MifareClassicBlockNumber
mifare_classic_sector_first_block(MifareClassicSectorNumber sector);

size_t
mifare_classic_sector_block_count(MifareClassicSectorNumber sector);

MifareClassicBlockNumber
mifare_classic_sector_last_block(MifareClassicSectorNumber sector);

πŸ’… DESCRIPTION πŸ’…

okay so the whole mifare_classic_*() family is here to let you mess with both Mifare Classic 1k and Mifare Classic 4k cards. iconic behavior honestly.

  • You activate a tag with mifare_classic_connect(), and you deactivate it with mifare_classic_disconnect(). open and close, like a lil door πŸšͺ
  • Once you're successfully connected, you still need to authenticate for a block using a key of type key_type β€” which is either MFC_KEY_A or MFC_KEY_B β€” via mifare_classic_authenticate(). only then can you do literally anything else.
  • Once you're successfully authenticated, you can read a block's data with mifare_classic_read() and write it with mifare_classic_write() πŸ’–
  • Value-blocks are lowkey the easy ones β€” hit them with mifare_classic_read_value() and mifare_classic_init_value(). There's more where that came from for these blocks: mifare_classic_increment() and mifare_classic_decrement() bump the value of the given block up or down by amount, and they stash the result in the target's internal data register. That register value can also be loaded from another block using mifare_classic_restore(). And when you want to write the target's internal data register back out to a block, you ask for it with mifare_classic_transfer().
  • Wanna know what you're allowed to do with a data block? mifare_classic_get_data_block_permission(). The access permission you're checking for key key_type is one of MCAB_R, MCAB_W, MCAB_I or MCAB_D β€” respectively read, write, increment and decrement permissions. the receipts, fr fr 🧾
  • mifare_classic_get_trailer_block_permission() is giving mifare_classic_get_data_block_permission() energy, except the permissions available are MCAB_READ_KEYA, MCAB_READ_KEYB, MCAB_READ_ACCESS_BITS, MCAB_WRITE_ACCESS_BITS, MCAB_READ_KEYB and MCAB_WRITE_KEYB.
  • Reset a whole sector back to factory defaults with mifare_classic_format_sector(). factory reset, but make it a sector 🌈
  • mifare_classic_trailer_block() is the convenience function for building a trailer block β€” you hand it a A key key_a, the access bits for the blocks of the sector ab_0, ab_1 and ab_2, and a B key key_b. and it just... builds it for you. king behavior πŸ‘‘
  • The mifare_classic_block_sector() function returns the number of the sector holding block.
  • Then mifare_classic_sector_first_block(), mifare_classic_sector_block_count(), mifare_classic_sector_last_block() are the complement of the mifare_classic_block_sector() function, and they return various block-level info about the sector you gave them.

⭐ RETURN VALUES ⭐

Unless it says otherwise, every single function here returns a value greater than or equal to 0 on success, or -1 on failure. that's it, that's the whole vibe check. 😭


πŸ¦‹ SEE ALSO πŸ¦‹

freefare(3), mad(3)


πŸ‘‘ AUTHORS πŸ‘‘

  • Romain Tartiere <romain@blogreen.org>
  • Romuald Conty <romuald@libnfc.org>

and that's the page bestie, no notes πŸ’… this one's from Debian, dated March 30, 2010, and it lives in the manual as MIFARE_CLASSIC(3) β€” go forth and manipulate some Mifare Classic cards, you've got this 🫢✨