MIFARE_DESFIRE(3)
πΈ mifare_desfire(3) β Mifare DESFire Manipulation Functions πΈ
okay bestie, sit down, hydrate, because we're about to talk about the Mifare DESFire manipulation functions from libfreefare. this is the good stuff. this is the main character of contactless card libraries. β¨
π NAME
mifare_desfire_connect, mifare_desfire_disconnect, mifare_desfire_authenticate, mifare_desfire_authenticate_aes, mifare_desfire_authenticate_iso, mifare_desfire_change_key_settings, mifare_desfire_get_key_settings, mifare_desfire_change_key, mifare_desfire_get_key_version, mifare_desfire_create_application, mifare_desfire_create_application_3k3des, mifare_desfire_create_application_aes, mifare_desfire_create_application_iso, mifare_desfire_create_application_3k3des_iso, mifare_desfire_create_application_aes_iso, mifare_desfire_delete_application, mifare_desfire_get_application_ids, mifare_desfire_free_application_ids, mifare_desfire_get_df_names, mifare_desfire_select_application, mifare_desfire_format_picc, mifare_desfire_get_version, mifare_desfire_free_mem, mifare_desfire_set_configuration, mifare_desfire_set_default_key, mifare_desfire_set_ats, mifare_desfire_get_card_uid, mifare_desfire_get_file_ids, mifare_desfire_get_iso_file_ids, mifare_desfire_get_file_settings, mifare_desfire_change_file_settings, mifare_desfire_create_std_data_file, mifare_desfire_create_std_data_file_iso, mifare_desfire_create_backup_data_file, mifare_desfire_create_backup_data_file_iso, mifare_desfire_create_value_file, mifare_desfire_create_linear_record_file, mifare_desfire_create_linear_record_file_iso, mifare_desfire_create_cyclic_record_file, mifare_desfire_create_cyclic_record_file_iso, mifare_desfire_delete_file, mifare_desfire_read_data, mifare_desfire_read_data_ex, mifare_desfire_write_data, mifare_desfire_write_data_ex, mifare_desfire_get_value, mifare_desfire_get_value_ex, mifare_desfire_credit, mifare_desfire_credit_ex, mifare_desfire_debit, mifare_desfire_debit_ex, mifare_desfire_limited_credit, mifare_desfire_limited_credit_ex, mifare_desfire_write_record, mifare_desfire_write_record_ex, mifare_desfire_read_records, mifare_desfire_read_records_ex, mifare_desfire_clear_record_file, mifare_desfire_commit_transaction, mifare_desfire_abort_transaction
β aka Mifare DESFire Manipulation Functions. that's the whole squad, fr fr. π«Ά
π LIBRARY
Mifare card manipulation library β that's libfreefare, and you link it with -lfreefare. that's it, that's the vibe. π
β¨ SYNOPSIS β¨
first thing's first, bestie β you gotta invite the header to the party:
#include <freefare.h>
and now, the whole cast, in order, exactly as they show up:
int
mifare_desfire_connect(MifareTag tag);
int
mifare_desfire_disconnect(MifareTag tag);
int
mifare_desfire_authenticate(MifareTag tag, uint8_t key_no,
MifareDESFireKey key);
int
mifare_desfire_authenticate_aes(MifareTag tag, uint8_t key_no,
MifareDESFireKey key);
int
mifare_desfire_authenticate_iso(MifareTag tag, uint8_t key_no,
MifareDESFireKey key);
int
mifare_desfire_change_key_settings(MifareTag tag, uint8_t settings);
int
mifare_desfire_get_key_settings(MifareTag tag, uint8_t *settings,
uint8_t *max_keys);
int
mifare_desfire_change_key(MifareTag tag, uint8_t key_no,
MifareDESFireKey new_key, MifareDESFireKey old_key);
int
mifare_desfire_get_key_version(MifareTag tag, uint8_t key_no,
uint8_t *version);
int
mifare_desfire_create_application(MifareTag tag, MifareDESFireAID aid,
uint8_t settings, uint8_t key_no);
int
mifare_desfire_create_application_aes(MifareTag tag,
MifareDESFireAID aid, uint8_t settings, uint8_t key_no);
int
mifare_desfire_create_application_3k3des(MifareTag tag,
MifareDESFireAID aid, uint8_t settings, uint8_t key_no);
int
mifare_desfire_create_application_iso(MifareTag tag,
MifareDESFireAID aid, uint8_t settings, uint8_t key_no,
int want_iso_file_identifiers, uint16_t iso_file_id,
uint8_t *iso_file_name, size_t iso_file_name_len);
int
mifare_desfire_create_application_3k3des_iso(MifareTag tag,
MifareDESFireAID aid, uint8_t settings, uint8_t key_no,
int want_iso_file_identifiers, uint16_t iso_file_id,
uint8_t *iso_file_name, size_t iso_file_name_len);
int
mifare_desfire_create_application_aes_iso(MifareTag tag,
MifareDESFireAID aid, uint8_t settings, uint8_t key_no,
int want_iso_file_identifiers, uint16_t iso_file_id,
uint8_t *iso_file_name, size_t iso_file_name_len);
int
mifare_desfire_delete_application(MifareTag tag, MifareDESFireAID aid);
int
mifare_desfire_get_application_ids(MifareTag tag,
MifareDESFireAID *aids[], size_t *count);
void
mifare_desfire_free_application_ids(MifareDESFireAID aids[]);
int
mifare_desfire_get_df_names(MifareTag tag, MifareDESFireDF *dfs[],
size_t *count);
int
mifare_desfire_select_application(MifareTag tag, MifareDESFireAID aid);
int
mifare_desfire_format_picc(MifareTag tag);
int
mifare_desfire_get_version(MifareTag tag,
struct mifare_desfire_version_info *version_info);
int
mifare_desfire_free_mem(MifareTag tag, uint32_t *size);
int
mifare_desfire_set_configuration(MifareTag tag, bool disable_format,
bool enable_random_uid);
int
mifare_desfire_set_default_key(MifareTag tag, MifareDESFireKey key);
int
mifare_desfire_set_ats(MifareTag tag, uint8_t *ats);
int
mifare_desfire_get_card_uid(MifareTag tag, char **uid);
int
mifare_desfire_get_file_ids(MifareTag tag, uint8_t *files[],
size_t *count);
int
mifare_desfire_get_iso_file_ids(MifareTag tag, uint16_t *files[],
size_t *count);
int
mifare_desfire_get_file_settings(MifareTag tag, uint8_t file_no,
struct mifare_desfire_file_settings *settings);
int
mifare_desfire_change_file_settings(MifareTag tag, uint8_t file_no,
uint8_t communication_settings, uint16_t access_rights);
int
mifare_desfire_create_std_data_file(MifareTag tag, uint8_t file_no,
uint8_t communication_settings, uint16_t access_rights,
uint32_t file_size);
int
mifare_desfire_create_std_data_file_iso(MifareTag tag, uint8_t file_no,
uint8_t communication_settings, uint16_t access_rights,
uint32_t file_size, uint16_t iso_file_id);
int
mifare_desfire_create_backup_data_file(MifareTag tag, uint8_t file_no,
uint8_t communication_settings, uint16_t access_rights,
uint32_t file_size);
int
mifare_desfire_create_backup_data_file_iso(MifareTag tag,
uint8_t file_no, uint8_t communication_settings,
uint16_t access_rights, uint32_t file_size, uint16_t iso_file_id);
int
mifare_desfire_create_value_file(MifareTag tag, uint8_t file_no,
uint8_t communication_settings, uint16_t access_rights,
int32_t lower_limit, int32_t upper_limit, int32_t value,
uint8_t limited_credit_enable);
int
mifare_desfire_create_linear_record_file(MifareTag tag, uint8_t file_no,
uint8_t communication_settings, uint16_t access_rights,
uint32_t record_size, uint32_t max_number_of_records);
int
mifare_desfire_create_linear_record_file_iso(MifareTag tag,
uint8_t file_no, uint8_t communication_settings,
uint16_t access_rights, uint32_t record_size,
uint32_t max_number_of_records);
int
mifare_desfire_create_cyclic_record_file(MifareTag tag, uint8_t file_no,
uint8_t communication_settings, uint16_t access_rights,
uint32_t record_size, uint32_t max_number_of_records,
uint16_t iso_file_id);
int
mifare_desfire_create_cyclic_record_file_iso(MifareTag tag,
uint8_t file_no, uint8_t communication_settings,
uint16_t access_rights, uint32_t record_size,
uint32_t max_number_of_records, uint16_t iso_file_id);
int
mifare_desfire_delete_file(MifareTag tag, uint8_t file_no);
ssize_t
mifare_desfire_read_data(MifareTag tag, uint8_t file_no, off_t offset,
size_t length, void *data);
ssize_t
mifare_desfire_read_data_ex(MifareTag tag, uint8_t file_no,
off_t offset, size_t length, void *data, int cs);
ssize_t
mifare_desfire_write_data(MifareTag tag, uint8_t file_no, off_t offset,
size_t length, void *data);
ssize_t
mifare_desfire_write_data_ex(MifareTag tag, uint8_t file_no,
off_t offset, size_t length, void *data, int cs);
int
mifare_desfire_get_value(MifareTag tag, uint8_t file_no,
int32_t *value);
int
mifare_desfire_get_value_ex(MifareTag tag, uint8_t file_no,
int32_t *value, int cs);
int
mifare_desfire_credit(MifareTag tag, uint8_t file_no, int32_t amount);
int
mifare_desfire_credit_ex(MifareTag tag, uint8_t file_no, int32_t amount,
int cs);
int
mifare_desfire_debit(MifareTag tag, uint8_t file_no, int32_t amount);
int
mifare_desfire_debit_ex(MifareTag tag, uint8_t file_no, int32_t amount,
int cs);
int
mifare_desfire_limited_credit(MifareTag tag, uint8_t file_no,
int32_t amount);
int
mifare_desfire_limited_credit_ex(MifareTag tag, uint8_t file_no,
int32_t amount, int cs);
ssize_t
mifare_desfire_write_record(MifareTag tag, uint8_t file_no,
off_t offset, size_t length, void *data);
ssize_t
mifare_desfire_write_record_ex(MifareTag tag, uint8_t file_no,
off_t offset, size_t length, void *data, int cs);
ssize_t
mifare_desfire_read_records(MifareTag tag, uint8_t file_no,
off_t offset, size_t length, void *data);
ssize_t
mifare_desfire_read_records_ex(MifareTag tag, uint7_t file_no,
off_t offset, size_t length, void *data, int cs);
int
mifare_desfire_clear_record_file(MifareTag tag, uint8_t file_no);
int
mifare_desfire_commit_transaction(MifareTag tag);
int
mifare_desfire_abort_transaction(MifareTag tag);
π bestie, real talk, no cap: look at thatmifare_desfire_read_records_exsignature. the original page literally saysuint7_t file_no. that is not a typo i made up, that's what's written, anduint7_tis not a real type, so write that one down exactly as-is and don't let anyone gaslight you about it. it's giving "someone's typo got enshrined in the docs" and honestly? iconic. π
and that's just the cast list, bestie β the lore, the options, and all the juicy behavioral details are coming up in part 2. don't go anywhere. π
β¨ DESCRIPTION β¨
okay bestie, so the mifare_desfire_*() functions are literally your whole toolkit for managing Mifare DESFire tags. like, everything. let's go group by group π
π Card-level operations π
mifare_desfire_connect()andmifare_desfire_disconnect()β these two activate and deactivate the tag you handed over. and lowkey important: everymifare_desfire_*()function that operates on a tag needs that tag to be activated first. no activation, no vibes. π₯- After activation, the application that's selected is the master application. wanna pick a different one? that's
mifare_desfire_select_application()(more on that below π). mifare_desfire_get_version()β pulls a whole info dump about the tag: UID, batch number, production date, plus hardware and software info. head to thefreefare.hheader file if you wanna know the deets about theversion_infofield.mifare_desfire_free_mem()β returns the size of the free memory on the PICC, in bytes. free space check, slay.mifare_desfire_set_configuration()β two uses: you can turn off the format function by settingdisable_formatto anything that isn't0, or you can flip the card into using a random UDI by settingenable_random_uidto a non-zero value. β¨mifare_desfire_set_default_keyβ sets thekeyargument as the default key for new applications.mifare_desfire_set_atsβ replaces the ATS bytes that the PICC returns when it's selected.mifare_desfire_get_card_uidβ for a PICC that's configured to use a random UID, this is the one that gets you the original UID of the target. π΅οΈmifare_desfire_format_picc()β resets the tag back to factory defaults. β οΈ for this one to work you need to have authenticated with the card master key beforehand. no key, no reset.
π¦ Application-level operations π¦
mifare_desfire_select_application()β makes the application identified byaidthe active one, and every file operation after that happens inside this application's context. aftermifare_desfire_connect, the default is the card master application. wanna go back to it? callmifare_desfire_select_application()again, either with anaidthat has all its fields set to0, or by passingNULLas theaid. easy. πmifare_desfire_authenticate()β does an authentication using key numberkey_noon the card and the key (3)DES key on the tag.mifare_desfire_authenticate_aes()β same vibe, but the key is an AES key.mifare_desfire_authenticate_iso()β ISO authentication, using either a 3DES or a 3K3DES key.mifare_desfire_get_key_settings()β hands you the settings plus the number of keysmax_keysof the selected application.mifare_desfire_change_key_settings()β changes the selected application's settings tosettings. heads up: the application's number of keys cannot be changed once the application has been created. periodt.mifare_desfire_change_key()β changes keykey_nofromold_keytonew_keyon the tag. depending on the application's settings, you may need a previous authentication with that same key or with a different one. iykyk.mifare_desfire_get_key_version()β retrieves the version of the key numberedkey_noin the selected application.mifare_desfire_create_application()β creates an application with AIDaid, the key settingssettings, andkey_noauthentication keys. fun fact: authentication keys get set to0after creation.mifare_desfire_create_application_3k3des()andmifare_desfire_create_application_aes()β behave exactly likemifare_desfire_create_application(), except the whole application is configured to use 3K3DES or AES keys respectively. and yes, you can get the same result with plainmifare_desfire_create_application()by ORing thekey_noargument withAPPLICATION_CRYPTO_3K3DESorAPPLICATION_CRYPTO_AES. two paths, one destiny β¨mifare_desfire_create_application_iso()β acts likemifare_desfire_create_application(), but lets you say whether the files created inside the application should have an ISO file identifier, by settingwant_iso_file_identifiersto a non-NULLvalue. you can also provide a DF viaiso_file_id, along with an optional file nameiso_file_nameof lengthiso_file_name_len(in bytes). πmifare_desfire_create_application_3k3des_iso()andmifare_desfire_create_application_aes_iso()β act like the regularmifare_desfire_create_application_3k3des()andmifare_desfire_create_application_aes()functions, with the exact same extra ISO parameters thatmifare_desfire_create_application_iso()gives you.mifare_desfire_delete_application()β deletes the application identified by AIDaid. bye bestie πmifare_desfire_get_application_ids()β returns a list of all applications on the card. π¨ theaidsarray has to be freed after you're done, by callingmifare_desfire_free_application_ids(). don't leak, it's not the vibe.mifare_desfire_get_df_names()β retrieves the list of DFdfsfrom the tag and setscountto the number of items in the allocated array. the memory has to be freed by the user withfree(3). yes you, bestie. π
πΈ File-level operations πΈ
mifare_desfire_get_file_ids()β returns the list ofcountfiles in the selected application, asfiles. the memory allocated forfileshas to be reclaimed usingfree(3).mifare_desfire_get_iso_file_ids()β returns the list ofcountfile ISO identifiers, asfiles. again: memory allocated forfilesgets reclaimed withfree(3).mifare_desfire_get_file_settings()β retrieves the settings of filefile_noin the selected application of the tag.mifare_desfire_change_file_settings()β changes thecommunication_settingsandaccess_rightsof filefile_noin the selected application of the tag.- The
mifare_desfire_create_*()family of functions creates a new filefile_nowith thecommunication_settingsandaccess_rightsyou provide, on the tag. the whole squad:mifare_desfire_create_std_data_file()β creates a standard data file of sizefile_size.mifare_desfire_create_backup_data_file()β creates a backup data file of sizefile_size.mifare_desfire_create_value_file()β creates a value file with valuevalue, constrained to the rangelower_limittoupper_limit, with thelimited_credit_enablesettings.mifare_desfire_create_linear_record_file()β creates a linear record file that can holdmax_number_of_recordsrecords, each of sizerecord_size.mifare_desfire_create_cyclic_record_file()β creates a cyclic record file that can holdmax_number_of_recordsrecords, each of sizerecord_size.
- The
mifare_desfire_create_*_iso()family acts exactly like the versions without the_isosuffix, but they give you one extra argument:iso_file_id. π mifare_desfire_delete_file()β removes filefile_nofrom the selected application of the tag. gone, not sorry.
π Data-level operations π
mifare_desfire_read_data()β readslengthbytes of data starting atoffsetfrom filefile_noand copies it intodata. iflengthis set to0, the file gets read all the way to the end. it returns the number of bytes read. πmifare_desfire_write_data()β writeslengthbytes of data fromoffsetinto filefile_no, taking it fromdata. returns the number of bytes written. βοΈmifare_desfire_get_value()β reads the value of filefile_noin the selected application.mifare_desfire_credit()β addsamountto the value of filefile_noin the selected application.mifare_desfire_debit()β subtractsamountfrom the value of filefile_noin the selected application.
ngl there's a lil orphan fragment sitting right here in the original that just reads: to the value of the file file_no of the selected application. β i'm keeping it, word for word, so nothing goes missing. mystery line, iconic behaviour π
mifare_desfire_limited_credit()β addsamountto the value of filefile_noin the selected application.mifare_desfire_write_record()β writeslengthrecords starting at recordoffsetofdatainto filefile_no, and returns the number of bytes written.mifare_desfire_read_records()β readslengthrecords starting at recordoffsetfrom filefile_noand copies them intodata, returning the number of bytes read.mifare_desfire_clear_record_file()β erases all records from filefile_noin the selected application. wipe the slate clean β¨mifare_desfire_commit_transaction()β validates the set of pending changes on the tag, whilemifare_desfire_abort_transaction()rolls them back. one says yes, the other says sike.
and okay, super important bit for the advanced girlies: every data-manipulation function that reads from or writes to files has an *_ex() variant (for example mifare_desfire_read_data_ex()), and that variant takes an extra parameter cs which defines the communication settings to use. if you don't pass it, the library tries to read this value out of the file's configuration. and because reading that information might be denied, the *_ex() variant of functions still lets you use the library for advanced usage. so when the normal path gets blocked, the _ex path is your main character moment. π
π₯ RETURN VALUES π₯
Unless it says otherwise somewhere, every other function returns a value greater than or equal to 0 on success, or -1 on failure.
π SEE ALSO π
π AUTHORS π
Romain Tartiere <romain@il4p.org>
aaaand that's the whole page bestie, we ate and left no crumbs π«Ά this lil beauty shipped as part of the Debian project, dated March 26, 2011, and it lives under the name MIFARE_DESFIRE(3). go forth and desfire responsibly πππ¦
π¦ where this page comes from
- debian bookworm: libfreefare-doc 0.4.0-2.1 Β· LGPL-3.0-or-later
- debian trixie: libfreefare-doc 0.4.0-2.3 Β· LGPL-3.0-or-later
- nixos 26.05: libfreefare 0.4.0
- nixpkgs unstable: libfreefare 0.4.0
- ubuntu jammy: libfreefare-doc 0.4.0-2.1build1 Β· LGPL-3.0-or-later
- ubuntu noble: libfreefare-doc 0.4.0-2.3build2 Β· LGPL-3.0-or-later
- ubuntu questing: libfreefare-doc 0.4.0-2.3build2
- ubuntu resolute: libfreefare-doc 0.4.0-2.3build3 Β· LGPL-3.0-or-later
- ubuntu stonking: libfreefare-doc 0.4.0-2.4build1 Β· LGPL-3.0-or-later
- Copyright (C) 2010,2011 Romain Tartiere
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms