int explain_tag (MifareTag tag) { bool aborting = false; mifare_desfire_connect (tag); MifareDESFireAID ucard_info_aid = mifare_desfire_aid_new (UCARD_INFO_AID); if (mifare_desfire_select_application (tag, ucard_info_aid) < 0) { freefare_perror (tag, "mifare_desfire_select_application"); return -1; } free (ucard_info_aid); MifareDESFireKey key = mifare_desfire_aes_key_new (admin_key_data); if (mifare_desfire_authenticate_aes (tag, 0, key) < 0) { freefare_perror (tag, "mifare_desfire_authenticate_aes"); return -1; } uint8_t records[(3+16)*32]; int records_length; records_length = mifare_desfire_read_records_ex (tag, USER_KEYRING_FILENO, 0, 0, records, USER_KEYRING_COMMUNICATION_MODE); if (records_length < 0) { if (BOUNDARY_ERROR == mifare_desfire_last_picc_error (tag)) { warnx ("Card is empty"); return 0; } freefare_perror (tag, "mifare_desfire_read_records_ex"); return -1; } for (int i = 0; (!aborting) && (i < records_length); i += (3+16)) { uint32_t raw_aid = records[i] << 16 | records[i+1] << 8 | records[i+2]; MifareDESFireAID aid = mifare_desfire_aid_new (raw_aid); MifareDESFireKey key = mifare_desfire_des_key_new (records + i + 3); if (explain_application (tag, aid, key) < 0) aborting = true; mifare_desfire_key_free (key); free (aid); } mifare_desfire_disconnect (tag); return (aborting) ? -1 : 0; }
int mifare_desfire_auto_authenticate (FreefareTag tag, uint8_t key_no, MifareDESFireKey key) { /* Determine which key is currently the master one */ uint8_t key_version; int res = mifare_desfire_get_key_version (tag, key_no, &key_version); printf("key_version: %x\n", key_version); switch (key_version) { case 0x00: key = mifare_desfire_des_key_new_with_version (key_data_null); break; case 0x42: key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version); break; case 0xAA: key = mifare_desfire_des_key_new_with_version (key_data_des); break; case 0xC7: key = mifare_desfire_3des_key_new_with_version (key_data_3des); break; case 0x55: key = mifare_desfire_3k3des_key_new_with_version (key_data_3k3des); break; } /* Authenticate with this key */ switch (key_version) { case 0x00: case 0xAA: case 0xC7: res = mifare_desfire_authenticate (tag, key_no, key); break; case 0x55: res = mifare_desfire_authenticate_iso (tag, key_no, key); break; case 0x42: res = mifare_desfire_authenticate_aes (tag, key_no, key); break; } return res; }
void test_mifare_desfire_ev1_aes2 (void) { int res; MifareDESFireKey key; mifare_desfire_auto_authenticate (tag, 0); // Setup the AES key key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version); res = mifare_desfire_change_key (tag, 0x80, key, NULL); cut_assert_success ("mifare_desfire_change_key"); mifare_desfire_key_free (key); // Authenticate with the AES key key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version); res = mifare_desfire_authenticate_aes (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate"); mifare_desfire_key_free (key); res = mifare_desfire_format_picc (tag); cut_assert_success ("mifare_desfire_format_picc()"); key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version); res = mifare_desfire_authenticate_aes (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate"); mifare_desfire_key_free (key); uint32_t size; res = mifare_desfire_free_mem (tag, &size); cut_assert_success ("mifare_desfire_free_mem"); // Do some commands to check CMAC is properly handled res = mifare_desfire_free_mem (tag, &size); cut_assert_success ("mifare_desfire_free_mem"); struct mifare_desfire_version_info info; res = mifare_desfire_get_version (tag, &info); cut_assert_success ("mifare_desfire_get_version"); res = mifare_desfire_change_key_settings (tag, 0x0F); cut_assert_success ("mifare_desfire_change_key_settings"); res = mifare_desfire_free_mem (tag, &size); cut_assert_success ("mifare_desfire_free_mem"); MifareDESFireAID aid = mifare_desfire_aid_new (0x112233); mifare_desfire_delete_application (tag, aid); res = mifare_desfire_create_application (tag, aid, 0xff, 0x81); cut_assert_success ("mifare_desfire_create_application"); res = mifare_desfire_select_application (tag, aid); cut_assert_success ("mifare_desfire_select_application"); key = mifare_desfire_aes_key_new (key_data_aes); res = mifare_desfire_authenticate_aes (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate"); free (key); key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version); res = mifare_desfire_change_key (tag, 0x00, key, NULL); cut_assert_success ("mifare_desfire_change_key"); mifare_desfire_key_free (key); key = mifare_desfire_aes_key_new (key_data_aes); res = mifare_desfire_authenticate_aes (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate"); free (key); res = mifare_desfire_create_std_data_file (tag, 1, MDCM_MACED, 0x0000, 512); if ((mifare_desfire_last_picc_error (tag) != DUPLICATE_ERROR) && (mifare_desfire_last_picc_error(tag) != OPERATION_OK)) cut_assert_success ("mifare_desfire_create_std_data_file"); char sample_data[] = "Hello World! I'm a string that is probably too long " "to feet in a single frame. For this reason, it will be split and like" "ly, some failure in the algorirthm should trigger an error in this uni" "t test."; res = mifare_desfire_write_data_ex (tag, 1, 0, strlen (sample_data), sample_data, MDCM_MACED); cut_assert_success ("mifare_desfire_write_data"); char buffer[1024]; res = mifare_desfire_read_data_ex (tag, 1, 0, 27, buffer, MDCM_MACED); cut_assert_success ("mifare_desfire_read_data"); cut_assert_equal_memory (buffer, res, sample_data, 27, cut_message ("AES crypto failed")); uint8_t s, c; res = mifare_desfire_get_key_settings (tag, &s, &c); cut_assert_success ("mifare_desfire_get__key_settings"); res = mifare_desfire_read_data_ex (tag, 1, 27, 27, buffer, MDCM_MACED); cut_assert_success ("mifare_desfire_read_data"); cut_assert_equal_memory (buffer, res, sample_data + 27, 27, cut_message ("AES crypto failed")); res = mifare_desfire_read_data_ex (tag, 1, 0, 0, buffer, MDCM_MACED); cut_assert_success ("mifare_desfire_read_data"); cut_assert_equal_memory (buffer, strlen (buffer), sample_data, strlen (sample_data), cut_message ("AES crypto failed")); // Revert to the default DES key res = mifare_desfire_select_application (tag, NULL); cut_assert_success ("mifare_desfire_select_application"); key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version); res = mifare_desfire_authenticate_aes (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate"); mifare_desfire_key_free (key); key = mifare_desfire_des_key_new (key_data_null); res = mifare_desfire_change_key (tag, 0x00, key, NULL); cut_assert_success ("mifare_desfire_change_key"); mifare_desfire_key_free (key); }
int main (void) { uint8_t issuer_key_data[16]; 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)) { printf ("Fond Mifare DESFire with UID: %s\n", freefare_get_tag_uid (tag)); printf ("Issuer private key: "); char buffer[BUFSIZ]; system ("stty -echo"); fgets (buffer, BUFSIZ, stdin); system ("stty echo"); char *p; if ((p = strchr (buffer, '\n'))) *p = '\0'; ucard_derivate_password (buffer, strlen (buffer), 16, issuer_key_data); memset (buffer, '\0', strlen (buffer)); MifareDESFireKey key = mifare_desfire_aes_key_new (issuer_key_data); MifareDESFireAID ucard_info_aid = mifare_desfire_aid_new (UCARD_INFO_AID); int res = mifare_desfire_connect (tag); res = mifare_desfire_select_application (tag, ucard_info_aid); if (res < 0) { freefare_perror (tag, "mifare_desfire_select_application"); goto end; } res = mifare_desfire_authenticate_aes (tag, 1, key); if (res < 0) { freefare_perror (tag, "mifare_desfire_authenticate_aes"); goto end; } char owner_info[BUFSIZ]; res = mifare_desfire_read_data_ex (tag, 10, 0, 0, owner_info, MDCM_ENCIPHERED); if (res < 0) { freefare_perror (tag, "mifare_desfire_read_data"); goto end; } owner_info[res] = '\0'; printf ("Owner: %s\n", owner_info); end: mifare_desfire_disconnect (tag); mifare_desfire_key_free (key); free (ucard_info_aid); } } nfc_close (nfc_device); } exit(EXIT_SUCCESS); }
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); }