void freefare_perror (FreefareTag tag, const char *string) { fprintf (stderr, "%s: %s\n", string, freefare_strerror (tag)); }
int main(int argc, const char *argv[]) { nfc_device *pnd; // nfc_target nt; // static mifare_param mp; int i, j; MifareTag *tags = NULL; int error = 0; MifareClassicBlock dablock; // MifareClassicBlock mydata = {0x00,0x00,0x00,0x42, 0xff,0xff,0xff,0xbd, 0x00,0x00,0x00,0x42, 0,0xff,0x00,0xff}; MifareClassicBlock my_trailer_block; MifareClassicKey my_key_A = { 0xff,0xff,0xff,0xff,0xff,0xff }; MifareClassicKey my_key_B = { 0xff,0xff,0xff,0xff,0xff,0xff }; // Allocate only a pointer to nfc_context nfc_context *context; // Initialize libnfc and set the nfc_context nfc_init(&context); if (context == NULL) { printf("Unable to init libnfc (malloc)\n"); exit(EXIT_FAILURE); } // Display libnfc version const char *acLibnfcVersion = nfc_version(); (void)argc; printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion); // Open, using the first available NFC device which can be in order of selection: // - default device specified using environment variable or // - first specified device in libnfc.conf (/etc/nfc) or // - first specified device in device-configuration directory (/etc/nfc/devices.d) or // - first auto-detected (if feature is not disabled in libnfc.conf) device pnd = nfc_open(context, NULL); if (pnd == NULL) { printf("ERROR: %s\n", "Unable to open NFC device."); exit(EXIT_FAILURE); } // Set opened NFC device to initiator mode if (nfc_initiator_init(pnd) < 0) { nfc_perror(pnd, "nfc_initiator_init"); exit(EXIT_FAILURE); } printf("NFC reader: %s opened\n", nfc_device_get_name(pnd)); // Poll for a ISO14443A (MIFARE) tag /* const nfc_modulation nmMifare = { .nmt = NMT_ISO14443A, .nbr = NBR_106, }; if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) > 0) { printf("The following (NFC) ISO14443A tag was found:\n"); printf(" ATQA (SENS_RES): "); print_hex(nt.nti.nai.abtAtqa, 2); printf(" UID (NFCID%c): ", (nt.nti.nai.abtUid[0] == 0x08 ? '3' : '1')); print_hex(nt.nti.nai.abtUid, nt.nti.nai.szUidLen); printf(" SAK (SEL_RES): "); print_hex(&nt.nti.nai.btSak, 1); if (nt.nti.nai.szAtsLen) { printf(" ATS (ATR): "); print_hex(nt.nti.nai.abtAts, nt.nti.nai.szAtsLen); } } */ tags = freefare_get_tags(pnd); if (!tags) { printf("no Mifare classic\n"); } else { for (i = 0; (!error) && tags[i]; i++) { if (freefare_get_tag_type(tags[i]) == CLASSIC_1K) printf("%u : Mifare 1k (S50)\n",i); if (freefare_get_tag_type(tags[i]) == CLASSIC_4K) printf("%u : Mifare 4k (S70)\n",i); } if(mifare_classic_connect(tags[0])==0) { printf("connected\n"); if(mifare_classic_authenticate(tags[0], 1,keys[0],MFC_KEY_B) == OPERATION_OK) { printf("Authenticated !\n"); if(mifare_classic_read (tags[0], 1, &dablock) == OPERATION_OK) { printf("Block readed\n"); for(j=0; j<16; j++) { printf("%02X ", dablock[j]); } printf("\n"); } else { printf("Auth error : %s\n", freefare_strerror(tags[0])); } if(mifare_classic_get_data_block_permission (tags[0], 1, MCAB_R, MFC_KEY_A)) printf("i can READ this block with B\n"); if(mifare_classic_get_data_block_permission (tags[0], 1, MCAB_W, MFC_KEY_A)) printf("i can WRITE this block with B\n"); if(mifare_classic_get_data_block_permission (tags[0], 1, MCAB_I, MFC_KEY_A)) printf("i can INC this block with B\n"); if(mifare_classic_get_data_block_permission (tags[0], 1, MCAB_D, MFC_KEY_A)) printf("i can DEC this block with B\n"); printf("---\n"); /* trailer = ((block) / 4) * 4 + 3; */ if(mifare_classic_get_trailer_block_permission (tags[0], 3, MCAB_READ_KEYA, MFC_KEY_A)) printf("i can READ KEY A in trailer\n"); if(mifare_classic_get_trailer_block_permission (tags[0], 3, MCAB_WRITE_KEYA, MFC_KEY_A)) printf("i can WRITE KEY A in trailer\n"); if(mifare_classic_get_trailer_block_permission (tags[0], 3, MCAB_READ_ACCESS_BITS, MFC_KEY_A)) printf("i can READ ACCESS BITS in trailer\n"); if(mifare_classic_get_trailer_block_permission (tags[0], 3, MCAB_WRITE_ACCESS_BITS, MFC_KEY_A)) printf("i can WRITE ACCESS BITS in trailer\n"); if(mifare_classic_get_trailer_block_permission (tags[0], 3, MCAB_READ_KEYB, MFC_KEY_A)) printf("i can READ KEYB in trailer\n"); if(mifare_classic_get_trailer_block_permission (tags[0], 3, MCAB_WRITE_KEYB, MFC_KEY_A)) printf("i can WRITE KEYB in trailer\n"); /* if(mifare_classic_write (tags[0], 1, mydata) == 0) { printf("write ok\n"); } */ if(mifare_classic_init_value (tags[0], 1, 0x42, 00) == 0) { printf("init value bloc ok\n"); } /* compose trailer block */ /* ab0 ab1 ab2 abt gpb */ /* abt = C_100 = 4 = 100 = c3c2c1 != datasheet c1c2c3*/ //mifare_classic_trailer_block (&my_trailer_block, my_key_A, C_000, C_011, C_000, C_100, 0x69, my_key_B); mifare_classic_trailer_block (&my_trailer_block, my_key_A, C_000, C_000, C_000, C_100, 0x69, my_key_B); for(j=0; j<16; j++) { printf("%02X ", my_trailer_block[j]); } printf("\n"); if(mifare_classic_write (tags[0], 3, my_trailer_block) == 0) { printf("trailer write ok\n"); } /* if(mifare_classic_decrement(tags[0], 1, 1) == OPERATION_OK) { printf("decrement ok\n"); } else { printf("Decrement error : %s\n", freefare_strerror(tags[0])); } if(mifare_classic_transfer (tags[0], 1) == OPERATION_OK) { printf("transfer ok\n"); } else { printf("Transfert error : %s\n", freefare_strerror(tags[0])); } if(mifare_classic_read(tags[0], 1, &dablock) == OPERATION_OK) { printf("Block readed\n"); for(j=0; j<16; j++) { printf("%02X ", dablock[j]); } printf("\n"); } else { printf("Read error : %s\n", freefare_strerror(tags[0])); } */ } else { printf("Erreur : %s\n", freefare_strerror(tags[0])); } mifare_classic_disconnect(tags[0]); } } /* for(i=0; i<1; i++) { for(j=0; j<8; j++) { memcpy(mp.mpa.abtKey, &keys[j*6], 6); res = nfc_initiator_mifare_cmd(pnd, MC_AUTH_B, 0, &mp); if(res) { printf("sector %u / key %u : yes\n", i, j); continue; } else { printf("sector %u / key %u : no\n", i, j); } } } */ /* // mifare parameters memcpy(mp.mpa.abtAuthUid,nt.nti.nai.abtUid,4); memcpy(mp.mpa.abtKey, &keys[0*6], 6); // block res = nfc_initiator_mifare_cmd(pnd, MC_AUTH_A, 0, &mp); if(res) { printf("Auth success\n"); } else { printf("Auth failed\n"); } for(i=0; i<4; i++) { res = nfc_initiator_mifare_cmd(pnd, MC_READ, i, &mp); if(res) { print_hex(mp.mpd.abtData,16); } else { printf("Read failed\n"); } } */ // Close NFC device nfc_close(pnd); // Release the context nfc_exit(context); exit(EXIT_SUCCESS); }
int freefare_strerror_r (FreefareTag tag, char *buffer, size_t len) { return (snprintf (buffer, len, "%s", freefare_strerror (tag)) < 0) ? -1 : 0; }
int main (int argc, char *argv[]) { /* * Collect information */ bool f_flag = false; char *p; char ch; while ((ch = getopt (argc, argv, "f")) != -1) { switch (ch) { case 'f': f_flag = true; break; default: usage (argv[0]); exit (EXIT_FAILURE); break; } } char issuer_address[BUFSIZ]; fprintf (stderr, "Card issuer address: "); fgets (issuer_address, BUFSIZ, stdin); if ((p = strchr (issuer_address, '\n'))) *p = '\0'; char issuer_password[BUFSIZ]; read_password ("Issuer password", issuer_password, BUFSIZ); fprintf (stderr, "\n"); uint8_t issuer_password_data[16]; ucard_derivate_password (issuer_password, strlen (issuer_password), 16, issuer_password_data); memset (issuer_password, '\0', strlen (issuer_password)); MifareDESFireKey card_issuer_key = mifare_desfire_aes_key_new (issuer_password_data); char owner_full_name[BUFSIZ]; fprintf (stderr, "Card owner full user name: "); fgets (owner_full_name, BUFSIZ, stdin); if ((p = strchr (owner_full_name, '\n'))) *p = '\0'; char user_password[BUFSIZ]; read_password ("User password", user_password, BUFSIZ); fprintf (stderr, "\n"); uint8_t user_key_data[16]; ucard_derivate_password (user_password, strlen (user_password), 16, user_key_data); memset (user_password, '\0', strlen (user_password)); MifareDESFireKey user_key = mifare_desfire_aes_key_new_with_version (user_key_data, UCARD_AES_KEY_VERSION); char admin_password[BUFSIZ]; read_password ("Admin password", admin_password, BUFSIZ); fprintf (stderr, "\n"); uint8_t admin_key_data[16]; ucard_derivate_password (admin_password, strlen (admin_password), 16, admin_key_data); memset (admin_password, '\0', strlen (admin_password)); MifareDESFireKey admin_key = mifare_desfire_aes_key_new_with_version (admin_key_data, UCARD_AES_KEY_VERSION); uint8_t null_key_data[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; MifareDESFireKey null_des_key = mifare_desfire_des_key_new (null_key_data); MifareDESFireKey null_aes_key = mifare_desfire_aes_key_new (null_key_data); nfc_connstring nfc_devices[8]; size_t nfc_device_count; nfc_device_count = nfc_list_devices (NULL, nfc_devices, 8); for (size_t n = 0; n < nfc_device_count; n++) { nfc_device *nfc_device = nfc_open(NULL, nfc_devices[n]); MifareTag *tags = freefare_get_tags (nfc_device); for (int i = 0; tags[i]; i++) { MifareTag tag = tags[i]; if (DESFIRE == freefare_get_tag_type (tag)) { /* Actually setup the card */ printf ("Fond Mifare DESFire with UID: %s\n", freefare_get_tag_uid (tag)); /* * Master Application * * Key 0: Card owner 'user' private key */ MifareDESFireAID ucard_info_aid = mifare_desfire_aid_new (UCARD_INFO_AID); int res = mifare_desfire_connect (tag); if (f_flag) { if (0 == res) res = mifare_desfire_authenticate_aes (tag, 0, user_key); if (0 == res) res = mifare_desfire_format_picc (tag); } else { if (0 == res) res = mifare_desfire_authenticate (tag, 0, null_des_key); if (0 == res) res = mifare_desfire_change_key (tag, 0, user_key, NULL); if (0 == res) res = mifare_desfire_authenticate_aes (tag, 0, user_key); } if (0 == res) res = mifare_desfire_create_application (tag, ucard_info_aid, 0x0F, 0x83); if (!f_flag) { if (0 == res) res = mifare_desfire_change_key_settings (tag, 0x01); } /* * Card information application * * Key 0: Card owner 'admin' private key * Key 1: Card issuer private key * Key 2: Anonymous access public key * * File 9: Card issuer information * File 10: Card owner information * File 11: Keyring */ if (0 == res) res = mifare_desfire_select_application (tag, ucard_info_aid); if (0 == res) res = mifare_desfire_authenticate_aes (tag, 0, null_aes_key); if (0 == res) res = mifare_desfire_change_key (tag, 0, admin_key, NULL); if (0 == res) res = mifare_desfire_authenticate_aes (tag, 0, admin_key); if (0 == res) res = mifare_desfire_change_key (tag, 1, card_issuer_key, NULL); if (0 == res) res = mifare_desfire_create_std_data_file (tag, 9, MDCM_ENCIPHERED, 0x0000, strlen (issuer_address)); if (0 == res) res = mifare_desfire_write_data (tag, 9, 0, strlen (issuer_address), issuer_address); if (strlen (issuer_address) == (size_t) res) res = mifare_desfire_change_file_settings (tag, 9, MDCM_ENCIPHERED, 0x2F11); if (0 == res) res = mifare_desfire_create_std_data_file (tag, 10, MDCM_ENCIPHERED, 0x0000, strlen (owner_full_name)); if (0 == res) res = mifare_desfire_write_data (tag, 10, 0, strlen (owner_full_name), owner_full_name); if (strlen (owner_full_name) == (size_t) res) res = mifare_desfire_change_file_settings (tag, 10, MDCM_ENCIPHERED, 0x0F11); if (0 == res) res = mifare_desfire_create_linear_record_file (tag, 11, MDCM_ENCIPHERED, 0xF20F, 3 + 16, 24); if (0 == res) res = mifare_desfire_change_key_settings (tag, 0x01); if (res < 0) { fprintf (stderr, "Oops, something went wrong! (%s)\n", freefare_strerror (tag)); } mifare_desfire_disconnect (tag); free (ucard_info_aid); } } nfc_close (nfc_device); } mifare_desfire_key_free (admin_key); mifare_desfire_key_free (user_key); mifare_desfire_key_free (card_issuer_key); mifare_desfire_key_free (null_aes_key); mifare_desfire_key_free (null_des_key); exit(EXIT_SUCCESS); }