int explain_application (MifareTag tag, MifareDESFireAID aid, MifareDESFireKey key) { char buffer[1024]; if (mifare_desfire_select_application (tag, aid) < 0) { fprintf (stderr, "mifare_desfire_select_application() failed\n"); return -1; } if (mifare_desfire_authenticate (tag, USER_ACCESS_KEYNO, key) < 0) { freefare_perror (tag, "mifare_desfire_authenticate_des"); return -1; } ssize_t len = mifare_desfire_read_data_ex (tag, UCARD_METDATA_FILENO, 0, 0, buffer, USER_ACCESS_COMMUNICATION_MODE); if (len < 0) { fprintf (stderr, "mifare_desfire_read_data_ex() failed\n"); return -1; } char *p = buffer; fprintf (stdout, " Application \"%s\" with AID 0x%06x has the following files:\n", p, mifare_desfire_aid_get_aid (aid)); p = strchr (p, '\0'); p++; int file_no = 0; while (*p) { fprintf (stdout, " File %2d - %s\n", file_no++, p); p = strchr (p, '\0'); p++; if (UCARD_METDATA_FILENO == file_no) file_no++; } return 0; }
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); }
ssize_t mifare_desfire_read_data (MifareTag tag, uint8_t file_no, off_t offset, size_t length, void *data) { return mifare_desfire_read_data_ex (tag, file_no, offset, length, data, madame_soleil_get_read_communication_settings (tag, file_no)); }
void test_mifare_desfire_free_read (void) { int res; mifare_desfire_auto_authenticate (tag, 0); /* Wipeout the card */ res = mifare_desfire_format_picc (tag); cut_assert_success ("mifare_desfire_format_picc()"); mifare_desfire_auto_authenticate (tag, 0); MifareDESFireKey key = mifare_desfire_des_key_new_with_version (key_data_null); res = mifare_desfire_change_key (tag, 0, key, NULL); cut_assert_success ("mifare_desfire_change_key()"); res = mifare_desfire_authenticate (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate()"); MifareDESFireAID aid = mifare_desfire_aid_new (0x00123456); res = mifare_desfire_create_application (tag, aid, 0xFF, 2); cut_assert_success ("mifare_desfire_create_application()"); res = mifare_desfire_select_application (tag, aid); cut_assert_success ("mifare_desfire_select_application"); free (aid); res = mifare_desfire_authenticate (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate()"); res = mifare_desfire_create_std_data_file (tag, 1, MDCM_MACED, 0x0000, 20); cut_assert_success ("mifare_desfire_create_std_data_file()"); char *s= "Hello World"; res = mifare_desfire_write_data (tag, 1, 0, strlen (s), s); cut_assert_success ("mifare_desfire_write_data()"); res = mifare_desfire_change_file_settings (tag, 1, MDCM_ENCIPHERED, 0xEFFF); cut_assert_success ("mifare_desfire_change_file_settings"); char buffer[20]; res = mifare_desfire_read_data (tag, 1, 0, 0, buffer); cut_assert_equal_int (sizeof (buffer), res, cut_message ("Data with free access should be read in PLAIN mode only.")); cut_assert_equal_int (OPERATION_OK, mifare_desfire_last_pcd_error (tag), cut_message ("Wrong PCD error")); res = mifare_desfire_read_data_ex (tag, 1, 0, 0, buffer, MDCM_MACED); cut_assert_equal_int (-1, res, cut_message ("Data with free access should be read in PLAIN mode only.")); cut_assert_equal_int (CRYPTO_ERROR, mifare_desfire_last_pcd_error (tag), cut_message ("Wrong PCD error")); res = mifare_desfire_read_data_ex (tag, 1, 0, 0, buffer, MDCM_ENCIPHERED); cut_assert_equal_int (-1, res, cut_message ("Data with free access should be read in PLAIN mode only.")); cut_assert_equal_int (CRYPTO_ERROR, mifare_desfire_last_pcd_error (tag), cut_message ("Wrong PCD error")); /* Wipeout the card */ mifare_desfire_select_application (tag, NULL); cut_assert_equal_int (OPERATION_OK, mifare_desfire_last_pcd_error (tag), cut_message ("Wrong PCD error")); res = mifare_desfire_authenticate (tag, 0, key); res = mifare_desfire_format_picc (tag); cut_assert_success ("mifare_desfire_format_picc()"); mifare_desfire_key_free (key); }