int create_applications (MifareTag tag) { int res = 0; MifareDESFireKey key = mifare_desfire_des_key_new_with_version (initial_key); res = mifare_desfire_authenticate (tag, 0, key); if (res < 0) errx (EXIT_FAILURE, "Authentication to master application failed"); mifare_desfire_key_free (key); printf ("Creating Application #1...\n"); MifareDESFireAID aid = mifare_desfire_aid_new (0x1); res = mifare_desfire_create_application (tag, aid, 0x0f, 0x2); if (res < 0) errx (EXIT_FAILURE, "Application #1 creation failed, try erasing the card before retrying."); free(aid); printf ("Creating Application #2...\n"); aid = mifare_desfire_aid_new (0x2); res = mifare_desfire_create_application (tag, aid, 0x0f, 0x2); if (res < 0) errx (EXIT_FAILURE, "Application #2 creation failed, try erasing the card before retrying."); free(aid); return res; }
int create_files (MifareTag tag) { int res = 0; MifareDESFireAID aid = mifare_desfire_aid_new (0x1); res = mifare_desfire_select_application(tag, aid); if (res < 0) errx (EXIT_FAILURE, "Application selection failed"); free (aid); MifareDESFireKey key = mifare_desfire_des_key_new_with_version (initial_key); res = mifare_desfire_authenticate (tag, 0, key); if (res < 0) errx (EXIT_FAILURE, "Authentication to application 1 failed"); mifare_desfire_key_free (key); /* FIXME: Check the accessrights ... */ printf ("Creating std_data_file 0x01...\n"); res = mifare_desfire_create_std_data_file(tag, 0x01,0x03,0xe1ff,0x80); if (res < 0) errx (EXIT_FAILURE, "CreateStdDataFile failed"); /* FIXME: Check the accessrights (See section 3.3 of the datasheet)... */ printf ("Creating std_data_file 0x02...\n"); res = mifare_desfire_create_std_data_file(tag, 0x02,0x03,0xe111,0x80); if (res < 0) errx (EXIT_FAILURE, "CreateStdDataFile failed"); aid = mifare_desfire_aid_new (0x2); res = mifare_desfire_select_application(tag, aid); if (res < 0) errx (EXIT_FAILURE, "Application selection failed"); free (aid); key = mifare_desfire_des_key_new_with_version (initial_key); res = mifare_desfire_authenticate (tag, 0, key); if (res < 0) errx (EXIT_FAILURE, "Authentication to application 2 failed"); mifare_desfire_key_free (key); /* FIXME: Check the accessrights ... */ printf ("Creating std_data_file 0x01...\n"); res = mifare_desfire_create_std_data_file(tag, 0x01,0x03, 0xe110, 0x20); if (res < 0) errx (EXIT_FAILURE, "CreateValueFile failed"); /* FIXME: Check the accessrights ... */ printf ("Creating std_data_file 0x02...\n"); res = mifare_desfire_create_std_data_file(tag, 0x02,0x03, 0xf110, 0x7e0); if (res < 0) errx (EXIT_FAILURE, "CreateLinearRecordFile failed"); return EXIT_SUCCESS; }
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 write_encrypted_tag_key (MifareTag tag, keyvault_t *kv, RSA *global_public, RSA *shop_public, RSA *shop_private, size_t len) { int res = 0; uint8_t *crypted = malloc (RSA_size(global_public)); res = RSA_public_encrypt (len, (unsigned char*) kv->k, (unsigned char*) crypted, global_public, RSA_PKCS1_PADDING); if (res < 0) fprintf (stderr, "Something went wrong while ciphering\n"); printf ("Encrypted key has length %d\n", RSA_size(global_public)); unsigned int siglen = RSA_size (shop_private); unsigned int digestlen = RSA_size(global_public); unsigned char *digest = digest_message (crypted, &digestlen); uint8_t *signature = malloc (siglen); res = RSA_sign (NID_sha1, digest, digestlen, (unsigned char *) signature, &siglen , shop_private); if (res <= 0) fprintf (stderr, "Something went wrong while signing\n"); res = RSA_verify (NID_sha1, (unsigned char*) digest, digestlen, (unsigned char *) signature, siglen, shop_public); if (res <= 0) fprintf (stderr, "Something went wrong while signing, can't verify the thing with our pubkey\n"); MifareDESFireAID aid = mifare_desfire_aid_new (0x1); res = mifare_desfire_select_application(tag, aid); if (res < 0) errx (EXIT_FAILURE, "Application selection failed"); free (aid); MifareDESFireKey key = mifare_desfire_3des_key_new_with_version (kv->k_w_1); mifare_desfire_key_set_version (key, 0x01); res = mifare_desfire_authenticate (tag, 1, key); if (res < 0) freefare_perror(tag, "Authentication to application #1 failed"); mifare_desfire_key_free (key); ssize_t written = mifare_desfire_write_data (tag, 0x01, 0x0, 0x80, crypted); if (written < 0) freefare_perror(tag, "Writing data to tag"); else printf ("Wrote %ld bytes E(K) to card ...\n", written); written = mifare_desfire_write_data (tag, 0x02, 0x0, 0x80, signature); if (written < 0) freefare_perror(tag, "Writing data to tag"); else printf ("Wrote %ld bytes Sign(E(K)) to card ...\n", written); free (crypted); free (signature); free (digest); return res; }
nfc_device *rfid_init(void) { nfc_init(&nfc_ctx); if(!nfc_ctx) { log("initializing libnfc failed"); return NULL; } door_aid = mifare_desfire_aid_new(0x2305CA); nfc_connstring devices[NFC_MAX_DEVICES]; int device_count = nfc_list_devices(nfc_ctx, devices, NFC_MAX_DEVICES); if(device_count <= 0) { log("no NFC devices found"); return NULL; } log("found %u NFC devices:", device_count); for(int i = 0; i < device_count; i++) log(" - %s", devices[i]); int selected_device = -1; const char *conf_connstring = getenv("RFID_CONNSTRING"); if(conf_connstring) { for(int i = 0; i < device_count; i++) if(strstr(devices[i], conf_connstring)) { selected_device = i; break; } } else { log("no connection string supplied, using first device"); selected_device = 0; } if(selected_device == -1) { log("could not find requested device"); return NULL; } log("using device %s", devices[selected_device]); nfc_device *dev = nfc_open(nfc_ctx, devices[selected_device]); if(!dev) { log("opening NFC device failed"); return NULL; } if(nfc_initiator_init(dev) < 0) { nfc_perror(dev, "configuring NFC device as initiator failed"); return NULL; } return dev; }
void test_mifare_desfire_des_macing (void) { int res; 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, 1); 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()"); char buffer[50]; res = mifare_desfire_read_data (tag, 1, 0, 0, buffer); cut_assert_success ("mifare_desfire_read_data()"); cut_assert_equal_int (20, res, cut_message ("retval")); cut_assert_equal_string (s, buffer, cut_message ("value")); res = mifare_desfire_select_application (tag, NULL); cut_assert_success ("mifare_desfire_select_application"); res = mifare_desfire_authenticate (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate()"); /* Wipeout the card */ res = mifare_desfire_format_picc (tag); cut_assert_success ("mifare_desfire_format_picc()"); mifare_desfire_key_free (key); }
void test_mifare_desfire_ev1_3des (void) { int res; /* Select the master application */ res = mifare_desfire_select_application (tag, NULL); cut_assert_success ("mifare_desfire_select_application()"); /* Get version information */ struct mifare_desfire_version_info version_info; res = mifare_desfire_get_version (tag, &version_info); cut_assert_success ("mifare_desfire_get_version()"); mifare_desfire_auto_authenticate (tag, 0); /* * This unit test change key settings to more restrictive ones, so reset * them to factory defaults in case the previous run failed unexpectedly. */ res = mifare_desfire_change_key_settings (tag, 0xF); cut_assert_success ("mifare_desfire_change_key_settings()"); res = mifare_desfire_change_key_settings (tag, 0xF); cut_assert_success ("mifare_desfire_change_key_settings()"); /* Change master key to AES */ MifareDESFireKey key = mifare_desfire_3des_key_new_with_version (key_data_3des); mifare_desfire_change_key (tag, 0, key, NULL); cut_assert_success ("mifare_desfire_change_key()"); res = mifare_desfire_authenticate_iso (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); /* Wipeout the card */ res = mifare_desfire_format_picc (tag); cut_assert_success ("mifare_desfire_format_picc()"); /* Create 3 applications */ res = mifare_desfire_select_application (tag, NULL); cut_assert_success ("mifare_desfire_select_application()"); key = mifare_desfire_3des_key_new_with_version (key_data_3des); res = mifare_desfire_authenticate_iso (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); uint8_t key_version; res = mifare_desfire_get_key_version (tag, 0, &key_version); cut_assert_success ("mifare_desfire_get_key_version()"); cut_assert_equal_int (0x55, 0x55, cut_message ("Wrong key_version value.")); uint32_t size; res = mifare_desfire_free_mem (tag, &size); cut_assert_success ("mifare_desfire_free_mem()"); MifareDESFireAID aid_a = mifare_desfire_aid_new (0x00AAAAAA); //cut_assert_not_null (aid_a, cut_message ("Cannot allocate AID")); res = mifare_desfire_create_application (tag, aid_a, 0xFF, 0); cut_assert_success ("mifare_desfire_create_application()"); MifareDESFireAID aid_b = mifare_desfire_aid_new (0x00BBBBBB); cut_assert_not_null (aid_b, cut_message ("Cannot allocate AID")); res = mifare_desfire_create_application (tag, aid_b, 0xEF, 6); cut_assert_success ("mifare_desfire_create_application()"); MifareDESFireAID aid_c = mifare_desfire_aid_new (0x00CCCCCC); cut_assert_not_null (aid_c, cut_message ("Cannot allocate AID")); res = mifare_desfire_create_application (tag, aid_c, 0xC2, 14); cut_assert_success ("mifare_desfire_create_application()"); // Ensure we can find the created applications MifareDESFireAID *aids = NULL; size_t aid_count; res = mifare_desfire_get_application_ids (tag, &aids, &aid_count); cut_assert_success ("mifare_desfire_get_application_ids()"); cut_assert_equal_int (3, aid_count, cut_message ("Wrong application count")); mifare_desfire_free_application_ids (aids); // Create files in the application A res = mifare_desfire_select_application (tag, aid_a); cut_assert_success ("mifare_desfire_select_application()"); uint8_t std_data_file_id = 15; res = mifare_desfire_create_std_data_file (tag, std_data_file_id, MDCM_PLAIN, 0xEEEE, 100); cut_assert_success ("mifare_desfire_create_std_data_file()"); res = mifare_desfire_create_backup_data_file (tag, 5, MDCM_PLAIN, 0xEEEE, 64); cut_assert_success ("mifare_desfire_create_backup_data_file()"); res = mifare_desfire_create_value_file (tag, 4, MDCM_PLAIN, 0xEEEE, 0, 1000, 0, 0); cut_assert_success ("mifare_desfire_create_value_file()"); res = mifare_desfire_create_cyclic_record_file (tag, 0, MDCM_PLAIN, 0xEEEE, 4, 10); cut_assert_success ("mifare_desfire_create_cyclic_record_file()"); // Write some data in the standard data file res = mifare_desfire_write_data (tag, std_data_file_id, 0, 30, (uint8_t *)"Some data to write to the card"); cut_assert_success ("mifare_desfire_write_data()"); cut_assert_equal_int (30, res, cut_message ("Wrong number of bytes writen")); res = mifare_desfire_write_data (tag, std_data_file_id, 34, 22, (uint8_t *)"Another block of data."); cut_assert_success ("mifare_desfire_write_data()"); cut_assert_equal_int (22, res, cut_message ("Wrong number of bytes writen")); // Make the file read-only res = mifare_desfire_change_file_settings (tag, std_data_file_id, MDCM_PLAIN, 0xEFFF); cut_assert_success ("mifare_desfire_change_file_settings()"); // Read a part of the file uint8_t buffer[120]; res = mifare_desfire_read_data (tag, std_data_file_id, 10, 50, &buffer); cut_assert_success ("mifare_desfire_read_data()"); cut_assert_equal_int (50, res, cut_message ("Wrong number of bytes read")); cut_assert_equal_memory ("to write to the card\0\0\0\0Another block of data.\0\0\0\0", 50, buffer, 50, cut_message ("Wrong data")); // Read all the file at once res = mifare_desfire_read_data (tag, std_data_file_id, 0, 0, &buffer); cut_assert_success ("mifare_desfire_read_data()"); cut_assert_equal_int (100, res, cut_message ("Wrong number of bytes read")); cut_assert_equal_memory ("Some data to write to the" " card\0\0\0\0Another block of" " data.\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 100, buffer, 100, cut_message ("Wrong data")); // Try to overwrute the file res = mifare_desfire_write_data (tag, std_data_file_id, 20, 5, (char *)"Test!"); cut_assert_equal_int (-1, res, cut_message ("Wrong return value")); cut_assert_equal_int (PERMISSION_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("Wrong PICC error")); int32_t expected_value = 0; for (int transaction = 0; transaction < 15; transaction++) { char data_buffer[3]; sprintf (data_buffer, "%02d", transaction); // Write to the backup file res = mifare_desfire_write_data (tag, 5, 3*transaction, 3, data_buffer); cut_assert_success ("mifare_desfire_write_data()"); // Manipulate the value file res = mifare_desfire_credit (tag, 4, 100); cut_assert_success ("mifare_desfire_credit()"); res = mifare_desfire_debit (tag, 4, 97); cut_assert_success ("mifare_desfire_debit()"); // Write to the cyclic record file res = mifare_desfire_write_record (tag, 0, 2, 2, data_buffer); cut_assert_success ("mifare_desfire_write_record()"); // Overwrite the cyclic record file res = mifare_desfire_write_record (tag, 0, 0, 2, (char *)"r."); cut_assert_success("mifare_desfire_write_record()"); // Ensure that no content was changed yet char ref_buffer[64]; memset (ref_buffer, 0, sizeof (ref_buffer)); for (int n = 0; n < transaction; n++) { sprintf (ref_buffer + 3 * n, "%02d", n); } res = mifare_desfire_read_data (tag, 5, 0, 0, buffer); cut_assert_success ("mifare_desfire_read_data()"); cut_assert_equal_int (64, res, cut_message ("Wrong number of bytes read")); cut_assert_equal_memory (buffer, 64, ref_buffer, 64, cut_message ("Wrong data")); int32_t value; res = mifare_desfire_get_value (tag, 4, &value); cut_assert_success ("mifare_desfire_get_value()"); cut_assert_equal_int (expected_value, value, cut_message ("Wrong value")); // Reading records from an empty file would abort the transaction if (0 != transaction) { // Get the latest record res = mifare_desfire_read_records (tag, 0, 0, 1, buffer); cut_assert_success ("mifare_desfire_read_records()"); sprintf (ref_buffer, "r.%02d", transaction); cut_assert_not_equal_memory (ref_buffer, 4, buffer, res, cut_message ("Wrong data")); } // Commit ! res = mifare_desfire_commit_transaction (tag); cut_assert_success ("mifare_desfire_commit_transaction()"); res = mifare_desfire_read_data (tag, 5, 3*transaction, 3, buffer); cut_assert_success ("mifare_desfire_read_data()"); cut_assert_equal_memory (data_buffer, 3, buffer, res, cut_message ("Wrong data")); expected_value += 3; res = mifare_desfire_get_value (tag, 4, &value); cut_assert_success ("mifare_desfire_get_value()"); cut_assert_equal_int (expected_value, value, cut_message ("Wrong value")); res = mifare_desfire_read_records (tag, 0, 0, 1, buffer); cut_assert_success ("mifare_desfire_read_records()"); sprintf (ref_buffer, "r.%02d", transaction); cut_assert_equal_memory (ref_buffer, 4, buffer, res, cut_message ("Wrong data")); } // Ensure limited credit is disabled res = mifare_desfire_limited_credit (tag, 4, 20); cut_assert_equal_int (-1, res, cut_message ("mifare_desfire_limited_credit() should fail")); // Get all files uint8_t *files; size_t file_count; res = mifare_desfire_get_file_ids (tag, &files, &file_count); cut_assert_success ("mifare_desfire_get_file_ids()"); cut_assert_equal_int (4, file_count, cut_message ("Wrong number of files")); for (size_t i=0; i<file_count;i++) { if ((files[i] != 0) && (files[i] != 4) && (files[i] != 5) && (files[i] != 15)) { cut_fail ("File %d should not exist.", files[i]); } struct mifare_desfire_file_settings settings; res = mifare_desfire_get_file_settings (tag, files[i], &settings); cut_assert_success ("mifare_desfire_get_file_settings()"); switch (files[i]) { case 0: cut_assert_equal_int (MDFT_CYCLIC_RECORD_FILE_WITH_BACKUP, settings.file_type, cut_message ("Wrong file type")); cut_assert_equal_int (MDCM_PLAIN, settings.communication_settings, cut_message ("Wrong communication settings")); cut_assert_equal_int (4, settings.settings.linear_record_file.record_size, cut_message ("Wrong record size")); cut_assert_equal_int (10, settings.settings.linear_record_file.max_number_of_records, cut_message ("Wrong max number of records")); cut_assert_equal_int (9, settings.settings.linear_record_file.current_number_of_records, cut_message ("Wrong current number of records")); break; case 4: cut_assert_equal_int (MDFT_VALUE_FILE_WITH_BACKUP, settings.file_type, cut_message ("Wrong file type")); cut_assert_equal_int (MDCM_PLAIN, settings.communication_settings, cut_message ("Wrong communication settings")); cut_assert_equal_int (0, settings.settings.value_file.lower_limit, cut_message ("Wrong lower limit")); cut_assert_equal_int (1000, settings.settings.value_file.upper_limit, cut_message ("Wrong upper limit")); cut_assert_equal_int (97, settings.settings.value_file.limited_credit_value, cut_message ("Wrong limited_credit value")); cut_assert_equal_int (0, settings.settings.value_file.limited_credit_enabled, cut_message ("Wrong limited_credit enable state")); break; case 5: cut_assert_equal_int (MDFT_BACKUP_DATA_FILE, settings.file_type, cut_message ("Wrong file type")); cut_assert_equal_int (MDCM_PLAIN, settings.communication_settings, cut_message ("Wrong communication settings")); cut_assert_equal_int (64, settings.settings.standard_file.file_size, cut_message ("Wrong file size")); break; case 15: cut_assert_equal_int (MDFT_STANDARD_DATA_FILE, settings.file_type, cut_message ("Wrong file type")); cut_assert_equal_int (MDCM_PLAIN, settings.communication_settings, cut_message ("Wrong communication settings")); cut_assert_equal_int (100, settings.settings.standard_file.file_size, cut_message ("Wrong file size")); break; default: cut_fail ("Wow! Cosmic ray!"); } res = mifare_desfire_delete_file (tag, files[i]); cut_assert_success ("mifare_desfire_delete_file()"); } free (files); // All files should have been removed res = mifare_desfire_get_file_ids (tag, &files, &file_count); cut_assert_success ("mifare_desfire_get_file_ids()"); cut_assert_equal_int (0, file_count, cut_message ("Wrong number of files")); // Delete application A res = mifare_desfire_select_application (tag, 0); cut_assert_success ("mifare_desfire_select_application()"); key = mifare_desfire_3des_key_new (key_data_3des); res = mifare_desfire_authenticate_iso (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); res = mifare_desfire_delete_application (tag, aid_a); cut_assert_success ("mifare_desfire_delete_application()"); // Ensure application A was deleted res = mifare_desfire_get_application_ids (tag, &aids, &aid_count); cut_assert_success ("mifare_desfire_get_application_ids()"); cut_assert_equal_int (2, aid_count, cut_message ("Wrong application count")); mifare_desfire_free_application_ids (aids); // Change application B keys res = mifare_desfire_select_application (tag, aid_b); cut_assert_success ("mifare_desfire_select_application()"); key = mifare_desfire_des_key_new (key_data_null); res = mifare_desfire_authenticate (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate()"); mifare_desfire_key_free (key); // Use an AES application master key key = mifare_desfire_3des_key_new_with_version ((uint8_t *) "App.B Master Key12345678"); res = mifare_desfire_change_key (tag, 0, key, NULL); cut_assert_success ("mifare_desfire_change_key()"); mifare_desfire_key_free (key); /* Authenticate with the new master key */ key = mifare_desfire_3des_key_new ((uint8_t *) "App.B Master Key12345678"); res = mifare_desfire_authenticate_iso (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); res = mifare_desfire_get_key_version (tag, 0, &key_version); cut_assert_success ("mifare_desfire_get_key_version()"); cut_assert_equal_int (0x83, key_version, cut_message ("Wrong key version")); /* Change key #1 */ key = mifare_desfire_des_key_new (key_data_null); res = mifare_desfire_authenticate (tag, 1, key); cut_assert_success ("mifare_desfire_authenticate()"); mifare_desfire_key_free (key); key = mifare_desfire_3des_key_new ((uint8_t *) "Another AES key!12345678"); res = mifare_desfire_change_key (tag, 1, key, NULL); cut_assert_success ("mifare_desfire_change_key()"); mifare_desfire_key_free (key); /* Change key #5 */ key = mifare_desfire_des_key_new (key_data_null); res = mifare_desfire_authenticate (tag, 5, key); cut_assert_success ("mifare_desfire_authenticate()"); mifare_desfire_key_free (key); key = mifare_desfire_3des_key_new ((uint8_t *) "B's Chg Keys Key12345678"); res = mifare_desfire_change_key (tag, 5, key, NULL); cut_assert_success ("mifare_desfire_change_key()"); mifare_desfire_key_free (key); /* Set key #5 as the change key */ key = mifare_desfire_3des_key_new ((uint8_t *) "App.B Master Key12345678"); res = mifare_desfire_authenticate_iso (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); res = mifare_desfire_change_key_settings (tag, 0x5F); cut_assert_success ("mifare_desfire_change_key_settings()"); uint8_t key_settings; uint8_t max_keys; res = mifare_desfire_get_key_settings (tag, &key_settings, &max_keys); cut_assert_success ("mifare_desfire_get_key_settings()"); cut_assert_equal_int (0x5F, key_settings, cut_message ("Wrong key settings")); cut_assert_equal_int (6, max_keys, cut_message ("Wrong maximum number of keys")); /* Change key #1 to #4 using the three key procedure. */ key = mifare_desfire_3des_key_new ((uint8_t *) "B's Chg Keys Key12345678"); res = mifare_desfire_authenticate_iso (tag, 5, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); key = mifare_desfire_3des_key_new ((uint8_t *)"App.B Key #1. 12345678"); MifareDESFireKey key1 = mifare_desfire_3des_key_new ((uint8_t *) "Another AES key!12345678"); res = mifare_desfire_change_key (tag, 1, key, key1); cut_assert_success ("mifare_desfire_change_key()"); mifare_desfire_key_free (key); mifare_desfire_key_free (key1); key = mifare_desfire_3des_key_new ((uint8_t *)"App.B Key #2.. 12345678"); res = mifare_desfire_change_key (tag, 2, key, NULL); cut_assert_success ("mifare_desfire_change_key()"); mifare_desfire_key_free (key); key = mifare_desfire_3des_key_new ((uint8_t *)"App.B Key #3... 12345678"); res = mifare_desfire_change_key (tag, 3, key, NULL); cut_assert_success ("mifare_desfire_change_key()"); mifare_desfire_key_free (key); key = mifare_desfire_3des_key_new ((uint8_t *)"App.B Key #4....12345678"); res = mifare_desfire_change_key (tag, 4, key, NULL); cut_assert_success ("mifare_desfire_change_key()"); mifare_desfire_key_free (key); std_data_file_id--; res = mifare_desfire_create_std_data_file (tag, std_data_file_id, MDCM_PLAIN, 0x1234, 100); cut_assert_success ("mifare_desfire_create_std_data_file()"); expected_value = -1000000; res = mifare_desfire_create_value_file (tag, 4, 0, 0x1324, -987654321, -1000, expected_value, 1); cut_assert_success ("mifare_desfire_create_value_file()"); res = mifare_desfire_create_linear_record_file (tag, 1, 0, 0x1324, 25, 4); int nr = 0; for (int transaction = 0; transaction < 7; transaction++) { uint8_t cs = transaction % 3; if (cs == 2) cs++; key = mifare_desfire_3des_key_new ((uint8_t *) "App.B Key #4....12345678"); res = mifare_desfire_authenticate_iso (tag, 4, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); res = mifare_desfire_change_file_settings (tag, std_data_file_id, cs, 0x1234); cut_assert_success ("mifare_desfire_change_file_settings()"); res = mifare_desfire_change_file_settings (tag, 4, cs, 0x1324); cut_assert_success ("mifare_desfire_change_file_settings()"); res = mifare_desfire_change_file_settings (tag, 1, cs, 0x1324); cut_assert_success ("mifare_desfire_change_file_settings()"); // Authenticate witht he write key key = mifare_desfire_3des_key_new ((uint8_t *) "App.B Key #2.. 12345678"); res = mifare_desfire_authenticate_iso (tag, 2, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); char data_buffer[100]; char data_buffer2[100]; char data_buffer3[100]; for (int i = 0; i < 100; i++) data_buffer[i] = transaction + i; res = mifare_desfire_write_data (tag, std_data_file_id, 0, 100, data_buffer); cut_assert_success ("mifare_desfire_write_data()"); sprintf (data_buffer2, "Transaction #%d", transaction); res = mifare_desfire_write_data (tag, std_data_file_id, 5, strlen (data_buffer2), data_buffer2); cut_assert_success ("mifare_desfire_write_data()"); memcpy (data_buffer + 5, data_buffer2, strlen (data_buffer2)); // Write to the linear record. When it's full, erase it and restart. for (int i = 0; i < 2; i++) { if ((transaction % 2 == 1) && (i == 1)) { res = mifare_desfire_clear_record_file (tag, 1); cut_assert_success ("mifare_desfire_clear_record_file()"); sprintf (data_buffer3, "Test invalid write"); res = mifare_desfire_write_record (tag, 1, 0, strlen (data_buffer3), data_buffer3); cut_assert_equal_int (-1, res, cut_message ("error code")); cut_assert_equal_int (PERMISSION_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("PICC error")); // The previous failure has aborted the transaction, so // re-authenticate, then clear record again. key = mifare_desfire_3des_key_new ((uint8_t *) "App.B Key #2.. 12345678"); res = mifare_desfire_authenticate_iso (tag, 2, key); cut_assert_success ("mifare_desfire_authenticate_iso"); mifare_desfire_key_free (key); res = mifare_desfire_clear_record_file (tag, 1); cut_assert_success ("mifare_desfire_clear_record_file()"); res = mifare_desfire_commit_transaction (tag); cut_assert_success ("mifare_desfire_commit_transaction()"); nr = 0; } res = mifare_desfire_write_record (tag, 1, 0, 25, "0123456789012345678901234"); cut_assert_success ("mifare_desfire_write_record()"); res = mifare_desfire_write_record (tag, 1, 5, strlen (data_buffer2), data_buffer2); cut_assert_success ("mifare_desfire_write_record()"); } nr++; // Modify the value file res = mifare_desfire_debit (tag, 4, 1300); cut_assert_success ("mifare_desfire_debit()"); expected_value -= 1300; res = mifare_desfire_credit (tag, 4, 20); cut_assert_success ("mifare_desfire_credit()"); expected_value += 20; res = mifare_desfire_debit (tag, 4, 1700); cut_assert_success ("mifare_desfire_debit()"); expected_value -= 1700; // Commit res = mifare_desfire_commit_transaction (tag); cut_assert_success ("mifare_desfire_commit_transaction()"); // Refund the whole debited amount res = mifare_desfire_limited_credit (tag, 4, 3000); cut_assert_success ("mifare_desfire_limited_credit()"); expected_value += 3000; // Commit res = mifare_desfire_commit_transaction (tag); cut_assert_success ("mifare_desfire_commit_transaction()"); // Authenticate with the key that allows reading key = mifare_desfire_3des_key_new ((uint8_t *) "App.B Key #1. 12345678"); res = mifare_desfire_authenticate_iso (tag, 1, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); // Read first half of the file res = mifare_desfire_read_data (tag, std_data_file_id, 0, 50, data_buffer3); cut_assert_success ("mifare_desfire_read_data()"); cut_assert_equal_int (50, res, cut_message ("length")); cut_assert_equal_memory (data_buffer, 50, data_buffer3, res, cut_message ("data")); // Read second half of the file res = mifare_desfire_read_data (tag, std_data_file_id, 50, 0, data_buffer3); cut_assert_success ("mifare_desfire_read_data()"); cut_assert_equal_int (50, res, cut_message ("length")); cut_assert_equal_memory (data_buffer + 50, 50, data_buffer3, res, cut_message ("data")); // Get the value file current balance int32_t value; res = mifare_desfire_get_value (tag, 4, &value); cut_assert_success ("mifare_desfire_get_value()"); cut_assert_equal_int (expected_value, value, cut_message ("value")); // Get the number of records in the linear record file struct mifare_desfire_file_settings settings; res = mifare_desfire_get_file_settings (tag, 1, &settings); cut_assert_success ("mifare_desfire_get_file_settings()"); cut_assert_equal_int (MDFT_LINEAR_RECORD_FILE_WITH_BACKUP, settings.file_type, cut_message ("settings")); cut_assert_equal_int (nr, settings.settings.linear_record_file.current_number_of_records, cut_message ("settings")); // Read the oldest record res = mifare_desfire_read_records (tag, 1, nr - 1, 1, data_buffer3); cut_assert_success ("mifare_desfire_read_records()"); cut_assert_equal_int (25, res, cut_message ("length")); sprintf (data_buffer, "0123456789012345678901234"); sprintf (data_buffer2, "Transaction #%d", transaction - nr + 1); memcpy ((uint8_t *)data_buffer + 5, data_buffer2, strlen (data_buffer2)); cut_assert_equal_memory (data_buffer, strlen (data_buffer), data_buffer3, res, cut_message ("data")); // Read all records res = mifare_desfire_read_records (tag, 1, 0, 0, data_buffer3); cut_assert_success ("mifare_desfire_read_records()"); cut_assert_equal_int (25 * nr, res, cut_message ("length")); } res = mifare_desfire_get_file_ids (tag, &files, &file_count); cut_assert_success ("mifare_desfire_get_file_ids"); cut_assert_equal_int (3, file_count, cut_message ("count")); for (size_t i = 0; i < file_count; i++) { struct mifare_desfire_file_settings settings; res = mifare_desfire_get_file_settings (tag, files[i], &settings); cut_assert_success ("mifare_desfire_get_file_settings()"); switch (files[i]) { case 1: cut_assert_equal_int (MDFT_LINEAR_RECORD_FILE_WITH_BACKUP, settings.file_type, cut_message ("type")); cut_assert_equal_int (MDCM_PLAIN, settings.communication_settings, cut_message ("cs")); cut_assert_equal_int (0x1324, settings.access_rights, cut_message ("access_rights")); cut_assert_equal_int (25, settings.settings.linear_record_file.record_size, cut_message ("record_size")); cut_assert_equal_int (4, settings.settings.linear_record_file.max_number_of_records, cut_message ("max_number_of_records")); cut_assert_equal_int (2, settings.settings.linear_record_file.current_number_of_records, cut_message ("current_number_of_records")); break; case 4: cut_assert_equal_int (MDFT_VALUE_FILE_WITH_BACKUP , settings.file_type, cut_message ("type")); cut_assert_equal_int (MDCM_PLAIN, settings.communication_settings, cut_message ("cs")); cut_assert_equal_int (0x1324, settings.access_rights, cut_message ("access_rights")); cut_assert_equal_int (-987654321, settings.settings.value_file.lower_limit, cut_message ("lower_limit")); cut_assert_equal_int (-1000, settings.settings.value_file.upper_limit, cut_message ("upper_limit")); cut_assert_equal_int (0, settings.settings.value_file.limited_credit_value, cut_message ("limited_credit_value")); cut_assert_equal_int (1, settings.settings.value_file.limited_credit_enabled, cut_message ("limited_credit_enabled")); break; case 14: /* std_data_file_id */ cut_assert_equal_int (MDFT_STANDARD_DATA_FILE, settings.file_type, cut_message ("type")); cut_assert_equal_int (MDCM_PLAIN, settings.communication_settings, cut_message ("cs")); cut_assert_equal_int (0x1234, settings.access_rights, cut_message ("access_rights")); cut_assert_equal_int (100, settings.settings.standard_file.file_size, cut_message ("size")); break; default: cut_fail ("file_no"); } res = mifare_desfire_delete_file (tag, files[i]); cut_assert_success ("mifare_desfire_delete_file()"); } free (files); // Check there are no files anymore res = mifare_desfire_get_file_ids (tag, &files, &file_count); cut_assert_success ("mifare_desfire_get_file_ids"); cut_assert_equal_int (0, file_count, cut_message ("count")); /* Delete application B */ key = mifare_desfire_3des_key_new ((uint8_t *) "App.B Master Key12345678"); res = mifare_desfire_authenticate_iso (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); res = mifare_desfire_delete_application (tag, aid_b); cut_assert_success ("mifare_desfire_delete_application()"); res = mifare_desfire_get_application_ids (tag, &aids, &aid_count); cut_assert_success ("mifare_desfire_get_application_ids()"); cut_assert_equal_int (1, aid_count, cut_message ("Wrong AID count")); mifare_desfire_free_application_ids (aids); /* Tests using application C */ res = mifare_desfire_select_application (tag, aid_c); cut_assert_success ("mifare_desfire_select_application()"); key = mifare_desfire_des_key_new (key_data_null); res = mifare_desfire_authenticate (tag, 12, key); cut_assert_success ("mifare_desfire_authenticate()"); MifareDESFireKey new_key = mifare_desfire_3des_key_new ((uint8_t *)"App.C Key #1. 12345678"); res = mifare_desfire_change_key (tag, 1, new_key, key); cut_assert_success ("mifare_desfire_change_key()"); mifare_desfire_key_free (new_key); new_key = mifare_desfire_3des_key_new ((uint8_t *)"App.C Key #2.. 12345678"); res = mifare_desfire_change_key (tag, 2, new_key, key); cut_assert_success ("mifare_desfire_change_key()"); mifare_desfire_key_free (new_key); res = mifare_desfire_authenticate_iso (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); res = mifare_desfire_create_cyclic_record_file (tag, 6, MDCM_PLAIN, 0x12E0, 100, 22); cut_assert_success ("mifare_desfire_create_cyclic_record_file()"); for (int transaction = 0; transaction < 50; transaction++) { char data_buffer[100]; char read_buffer[100]; uint8_t cs = transaction % 3; if (cs == 2) cs++; key = mifare_desfire_des_key_new (key_data_null); res = mifare_desfire_authenticate (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate()"); mifare_desfire_key_free (key); res = mifare_desfire_change_file_settings (tag, 6, cs, 0x12E0); cut_assert_success ("mifare_desfire_change_file_settings()"); if (transaction & 4) { key = mifare_desfire_3des_key_new ((uint8_t *) "App.C Key #2.. 12345678"); res = mifare_desfire_authenticate_iso (tag, 2, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); } else { cs = 0; } memset (data_buffer, '_', 100); data_buffer[0] = transaction; data_buffer[99] = transaction; sprintf (data_buffer + 5, " Transaction #%d ", transaction); res = mifare_desfire_write_record (tag, 6, 0, 100, data_buffer); cut_assert_success ("mifare_desfire_write_record()"); if (transaction & 4) { key = mifare_desfire_3des_key_new ((uint8_t *) "App.C Key #1. 12345678"); res = mifare_desfire_authenticate_iso (tag, 1, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); } if (transaction % 7 == 0) { res = mifare_desfire_abort_transaction (tag); cut_assert_success ("mifare_desfire_abort_transaction()"); ssize_t n = mifare_desfire_read_records (tag, 6, 0, 1, read_buffer); if (transaction == 0) { cut_assert_equal_int (-1, n, cut_message ("Wrong return value")); } else { cut_assert_equal_int (100, n, cut_message ("Wrong return value")); cut_assert_not_equal_memory (data_buffer, sizeof (data_buffer), read_buffer, sizeof (read_buffer), cut_message ("Wrong data")); } } else { res = mifare_desfire_commit_transaction (tag); cut_assert_success ("mifare_desfire_commit_transaction()"); ssize_t n = mifare_desfire_read_records (tag, 6, 0, 1, read_buffer); cut_assert_equal_int (100, n, cut_message ("Wrong return value")); cut_assert_equal_memory (data_buffer, sizeof (data_buffer), read_buffer, sizeof (read_buffer), cut_message ("Wrong data")); } } // Read each record key = mifare_desfire_3des_key_new ((uint8_t *) "App.C Key #1. 12345678"); res = mifare_desfire_authenticate_iso (tag, 1, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); int t = 49; for (int i = 0; i < 22; i++) { char data_buffer[100]; char ref_data_buffer[100]; if (0 == (t % 7)) t--; memset (ref_data_buffer, '_', 100); ref_data_buffer[0] = t; ref_data_buffer[99] = t; sprintf (ref_data_buffer + 5, " Transaction #%d ", t); res = mifare_desfire_read_records (tag, 6, i, 1, data_buffer); if (i == 21) { cut_assert_equal_int (-1, res, cut_message ("return value")); } else { cut_assert_success ("mifare_desfire_read_records()"); cut_assert_equal_memory (ref_data_buffer, 100, data_buffer, res, cut_message ("data")); } t--; } /* * Change master key settings to require master key authentication for all * card operations. Only allow to revert this. */ res = mifare_desfire_select_application (tag, 0); cut_assert_success ("mifare_desfire_select_application()"); key = mifare_desfire_3des_key_new (key_data_3des); res = mifare_desfire_authenticate_iso (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); res = mifare_desfire_change_key_settings (tag, 0x08); cut_assert_success ("mifare_desfire_change_key_settings()"); /* Clear authentication */ res = mifare_desfire_select_application (tag, 0); cut_assert_success ("mifare_desfire_select_application()"); /* We should not be able to list applications now */ res = mifare_desfire_get_application_ids (tag, &aids, &aid_count); cut_assert_equal_int (-1, res, cut_message ("Wrong return value")); cut_assert_equal_int (AUTHENTICATION_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("Wrong PICC error")); /* Deleting an application should not be possible */ res = mifare_desfire_delete_application (tag, aid_c); cut_assert_equal_int (-1, res, cut_message ("Wrong return value")); cut_assert_equal_int (AUTHENTICATION_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("Wrong PICC error")); /* Creating an application should also be forbidden */ MifareDESFireAID aid_d = mifare_desfire_aid_new (0x00DDDDDD); res = mifare_desfire_create_application (tag, aid_d, 0xEF, 0); cut_assert_equal_int (-1, res, cut_message ("Wrong return value")); cut_assert_equal_int (AUTHENTICATION_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("Wrong PICC error")); /* * Now we retry authenticated with the master key. */ key = mifare_desfire_3des_key_new (key_data_3des); res = mifare_desfire_authenticate_iso (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); /* We should be able to list applications again */ res = mifare_desfire_get_application_ids (tag, &aids, &aid_count); cut_assert_success ("mifare_desfire_get_application_ids()"); cut_assert_equal_int (1, aid_count, cut_message ("Wrong AID count")); mifare_desfire_free_application_ids (aids); /* Deleting an application should be possible again */ res = mifare_desfire_delete_application (tag, aid_c); cut_assert_success ("mifare_desfire_delete_application()"); /* Creating an application should also be possible */ res = mifare_desfire_create_application (tag, aid_d, 0xEF, 0); cut_assert_success ("mifare_desfire_create_application()"); /* Revert master key settings to default */ res = mifare_desfire_change_key_settings (tag, 0xF); cut_assert_success ("mifare_desfire_change_key_settings()"); /* Change the master key back to the default one */ key = mifare_desfire_3des_key_new (key_data_3des); res = mifare_desfire_authenticate_iso (tag, 0, key); cut_assert_success ("mifare_desfire_authenticate_iso()"); mifare_desfire_key_free (key); 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()"); /* * Delete everything from the card */ res = mifare_desfire_authenticate (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()"); free (aid_a); free (aid_b); free (aid_c); free (aid_d); }
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); }
RSA* readRSA() { nfc_device *device = NULL; MifareTag *tag = NULL; MifareDESFireAID aid; RSA *rsa = NULL; uint8_t key_data_null[8] = { 0,0,0,0,0,0,0,0}; MifareDESFireKey defaultKey = mifare_desfire_des_key_new_with_version (key_data_null); device = getRfidDevice(); if (!device) return NULL; tag = freefare_get_tags(device); mifare_desfire_connect (tag[0]); aid = mifare_desfire_aid_new(AID_NUMBER); mifare_desfire_select_application (tag[0], aid); if (authApplication(tag[0], defaultKeyNumber) < 0) { fprintf(stderr,"Falscher Key\n"); nfc_close(device); return NULL; } if (!rsa) rsa = RSA_new(); if (!rsa->n) rsa->n = BN_new(); if (!rsa->d) rsa->d = BN_new(); if (!rsa->e) rsa->e = BN_new(); if (readBignum(tag[0],aid,rsa->n,0) < 0) { fprintf(stderr,"readBignum %d failed\n",0); nfc_close(device); return NULL; } if (readBignum(tag[0],aid,rsa->d,5) < 0) { fprintf(stderr,"readBignum %d failed\n",0); nfc_close(device); return NULL; } if (readBignum(tag[0],aid,rsa->e,10) < 0) { fprintf(stderr,"readBignum %d failed\n",0); nfc_close(device); return NULL; } nfc_close(device); return rsa; }
int deleteApplication() { nfc_device *device = NULL; MifareTag *tag = NULL; MifareDESFireAID aid = mifare_desfire_aid_new(AID_NUMBER); uint8_t *files = NULL; size_t file_count = 0; uint8_t key_data_null[8] = { 0,0,0,0,0,0,0,0}; MifareDESFireKey defaultKey = mifare_desfire_des_key_new_with_version (key_data_null); device = getRfidDevice(); if (!device) return NULL; tag = freefare_get_tags(device); mifare_desfire_connect (tag[0]); if (mifare_desfire_select_application (tag[0], aid) < 0) { fprintf(stderr,"select AID failed\n"); nfc_close(device); return -1; } if (mifare_desfire_authenticate(tag[0], defaultKeyNumber, defaultKey) < 0 ) { fprintf(stderr,"auth default key on AID failed\n"); nfc_close(device); return -1; } mifare_desfire_get_file_ids(tag[0], &files, &file_count); size_t i; for (i = 0; i < file_count; i++) { mifare_desfire_delete_file(tag[0],files[i]); } if (mifare_desfire_select_application (tag[0], NULL) < 0) { fprintf(stderr,"select Master Application failed\n"); nfc_close(device); return -1; } if (mifare_desfire_authenticate(tag[0], defaultKeyNumber, defaultKey) < 0 ) { fprintf(stderr,"auth Master Application failed\n"); nfc_close(device); return -1; } if (mifare_desfire_delete_application(tag[0],aid) < 0) { fprintf(stderr,"delete application failed\n"); nfc_close(device); return -1; } printf("Application deleted\n"); nfc_close(device); return 0; }
int writeRSA(RSA *rsa) { nfc_device *device = NULL; MifareTag *tag = NULL; MifareDESFireAID aid; uint8_t key_data_null[8] = { 0,0,0,0,0,0,0,0}; MifareDESFireKey defaultKey = mifare_desfire_des_key_new_with_version (key_data_null); device = getRfidDevice(); if (!device) return -1; tag = freefare_get_tags(device); mifare_desfire_connect (tag[0]); aid = mifare_desfire_aid_new(AID_NUMBER); mifare_desfire_create_application(tag[0],aid,0xED,1); if (mifare_desfire_select_application (tag[0], aid) < 0) { nfc_close(device); return -1; } MifareDESFireKey key = mifare_desfire_3des_key_new(createDesKey(makePinpad(),"des-ede")); if (mifare_desfire_authenticate(tag[0],0 , defaultKey) == 0 ) { if (mifare_desfire_change_key(tag[0], 0, key, defaultKey) < 0) { fprintf(stderr,"Change defaultKey to key failed\n"); nfc_close(device); return -1; } } if (mifare_desfire_authenticate(tag[0],0 , key) < 0 ) { fprintf(stderr,"Falscher Key\n"); nfc_close(device); return -1; } if (writeBignum(tag[0],aid,rsa->n,0) < 0) { fprintf(stderr,"writeBignum %d failed\n",0); nfc_close(device); return -1; } if (writeBignum(tag[0],aid,rsa->d,5) < 0) { fprintf(stderr,"writeBignum %d failed\n",5); nfc_close(device); return -1; } if (writeBignum(tag[0],aid,rsa->e,10) < 0) { fprintf(stderr,"writeBignum %d failed\n",10); nfc_close(device); return -1; } printf("Key Geschrieben\n"); fflush(stdout); nfc_close(device); return 0; }
void test_mifare_desfire_ev1_iso (void) { int res; mifare_desfire_auto_authenticate (tag, 0); res = mifare_desfire_format_picc (tag); cut_assert_equal_int (res, 0, cut_message ("mifare_desfire_format_picc()")); MifareDESFireDF *dfs; size_t count; res = mifare_desfire_get_df_names (tag, &dfs, &count); cut_assert_equal_int (res, 0, cut_message ("mifare_desfire_get_df_names()")); cut_assert_equal_int (count, 0, cut_message ("Wrong DF count")); cut_assert_null (dfs, cut_message ("DF should be NULL")); MifareDESFireAID aid = mifare_desfire_aid_new (0x111110); res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x111F, NULL, 0); cut_assert_success ("mifare_desfire_create_application_iso"); free (aid); uint8_t app2[] = "App2"; aid = mifare_desfire_aid_new (0x222220); res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x222F, app2, sizeof (app2)); cut_assert_success ("mifare_desfire_create_application_iso"); free (aid); uint8_t app3[] = "App3"; aid = mifare_desfire_aid_new (0x333330); res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x333F, app3, sizeof (app3)); cut_assert_success ("mifare_desfire_create_application_iso"); free (aid); aid = mifare_desfire_aid_new (0x444440); res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x111F, NULL, 0); cut_assert_equal_int (-1, res, cut_message ("Should fail")); cut_assert_equal_int (DUPLICATE_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("Should be a duplicate error")); res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x444F, app2, sizeof (app2)); cut_assert_equal_int (-1, res, cut_message ("Should fail")); cut_assert_equal_int (DUPLICATE_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("Should be a duplicate error")); free (aid); res = mifare_desfire_get_df_names (tag, &dfs, &count); cut_assert_equal_int (0, res, cut_message ("mifare_desfire_get_df_names()")); cut_assert_equal_int (3, count, cut_message ("Wrong DF count")); cut_assert_not_null (dfs, cut_message ("DF should not be NULL")); cut_assert_equal_int (0x111110, dfs[0].aid, cut_message ("Wrong value")); cut_assert_equal_int (0x111F, dfs[0].fid, cut_message ("Wrong value")); cut_assert_equal_int (0, dfs[0].df_name_len, cut_message ("Wrong value")); cut_assert_equal_int (0x222220, dfs[1].aid, cut_message ("Wrong value")); cut_assert_equal_int (0x222F, dfs[1].fid, cut_message ("Wrong value")); cut_assert_equal_int (sizeof (app2), dfs[1].df_name_len, cut_message ("Wrong value")); cut_assert_equal_memory (app2, sizeof (app2), dfs[1].df_name, dfs[1].df_name_len, cut_message ("Wrong value")); cut_assert_equal_int (0x333330, dfs[2].aid, cut_message ("Wrong value")); cut_assert_equal_int (0x333F, dfs[2].fid, cut_message ("Wrong value")); cut_assert_equal_int (sizeof (app3), dfs[2].df_name_len, cut_message ("Wrong value")); cut_assert_equal_memory (app3, sizeof (app3), dfs[2].df_name, dfs[2].df_name_len, cut_message ("Wrong value")); free (dfs); aid = mifare_desfire_aid_new (0x555550); res = mifare_desfire_create_application_iso (tag, aid, 0xff, 1, 1, 0x555F, NULL, 0); cut_assert_success ("mifare_desfire_create_application_iso"); res = mifare_desfire_select_application (tag, aid); cut_assert_success ("mifare_desfire_select_application"); res = mifare_desfire_create_std_data_file_iso (tag, 1, MDCM_PLAIN, 0xEEEE, 32, 0x1234); cut_assert_success ("mifare_desfire_create_std_data_file_iso"); res = mifare_desfire_create_backup_data_file_iso (tag, 2, MDCM_PLAIN, 0xEEEE, 32, 0x2345); cut_assert_success ("mifare_desfire_create_std_data_file_iso"); res = mifare_desfire_create_linear_record_file_iso (tag, 3, MDCM_PLAIN, 0xEEEE, 32, 10, 0x3456); cut_assert_success ("mifare_desfire_create_linear_record_file_iso"); res = mifare_desfire_create_cyclic_record_file_iso (tag, 4, MDCM_PLAIN, 0xEEEE, 32, 10, 0x4567); cut_assert_success ("mifare_desfire_create_cyclic_record_file_iso"); uint16_t *ids; res = mifare_desfire_get_iso_file_ids (tag, &ids, &count); cut_assert_success ("mifare_desfire_get_iso_file_ids"); cut_assert_equal_int (4, count, cut_message ("Invalid file count")); cut_assert_equal_int (0x1234, ids[0], cut_message ("Wrong file ID")); cut_assert_equal_int (0x2345, ids[1], cut_message ("Wrong file ID")); cut_assert_equal_int (0x3456, ids[2], cut_message ("Wrong file ID")); cut_assert_equal_int (0x4567, ids[3], cut_message ("Wrong file ID")); free (ids); free (aid); }
int main(int argc, char *argv[]) { int ch; int error = EXIT_SUCCESS; nfc_device *device = NULL; FreefareTag *tags = NULL; while ((ch = getopt (argc, argv, "hy")) != -1) { switch (ch) { case 'h': usage(argv[0]); exit (EXIT_SUCCESS); break; case 'y': configure_options.interactive = false; break; default: usage(argv[0]); exit (EXIT_FAILURE); } } // Remaining args, if any, are in argv[optind .. (argc-1)] nfc_connstring devices[8]; size_t device_count; nfc_context *context; nfc_init (&context); if (context == NULL) errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); device_count = nfc_list_devices (context, devices, 8); if (device_count <= 0) errx (EXIT_FAILURE, "No NFC device found."); for (size_t d = 0; (!error) && (d < device_count); d++) { device = nfc_open (context, devices[d]); if (!device) { warnx ("nfc_open() failed."); error = EXIT_FAILURE; continue; } tags = freefare_get_tags (device); if (!tags) { nfc_close (device); errx (EXIT_FAILURE, "Error listing Mifare DESFire tags."); } for (int i = 0; (!error) && tags[i]; i++) { if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i])) continue; char *tag_uid = freefare_get_tag_uid (tags[i]); char buffer[BUFSIZ]; int res; res = mifare_desfire_connect (tags[i]); if (res < 0) { warnx ("Can't connect to Mifare DESFire target."); error = EXIT_FAILURE; break; } // Make sure we've at least an EV1 version struct mifare_desfire_version_info info; res = mifare_desfire_get_version (tags[i], &info); if (res < 0) { freefare_perror (tags[i], "mifare_desfire_get_version"); error = 1; break; } if (info.software.version_major < 1) { warnx ("Found old DESFire, skipping"); continue; } printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid); bool do_it = true; if (configure_options.interactive) { printf ("Change default key? [yN] "); fgets (buffer, BUFSIZ, stdin); do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y')); } else { printf ("\n"); } if (do_it) { MifareDESFireKey default_key = mifare_desfire_des_key_new_with_version (null_key_data); res = mifare_desfire_authenticate (tags[i], 0, default_key); if (res < 0) { freefare_perror (tags[i], "mifare_desfire_authenticate"); error = EXIT_FAILURE; break; } mifare_desfire_key_free (default_key); MifareDESFireKey new_key = mifare_desfire_des_key_new (new_key_data); mifare_desfire_key_set_version (new_key, NEW_KEY_VERSION); res = mifare_desfire_set_default_key (tags[i], new_key); free (new_key); if (res < 0) { freefare_perror (tags[i], "mifare_desfire_set_default_key"); error = EXIT_FAILURE; break; } /* * Perform some tests to ensure the function actually worked * (it's hard to create a unit-test to do so). */ MifareDESFireAID aid = mifare_desfire_aid_new (0x112233); res = mifare_desfire_create_application (tags[i], aid, 0xFF, 1); if (res < 0) { freefare_perror (tags[i], "mifare_desfire_create_application"); error = EXIT_FAILURE; break; } res = mifare_desfire_select_application (tags[i], aid); if (res < 0) { freefare_perror (tags[i], "mifare_desfire_select_application"); error = EXIT_FAILURE; break; } uint8_t version; res = mifare_desfire_get_key_version (tags[i], 0, &version); if (res < 0) { freefare_perror (tags[i], "mifare_desfire_get_key_version"); error = EXIT_FAILURE; break; } if (version != NEW_KEY_VERSION) { fprintf (stderr, "Wrong key version: %02x (expected %02x).\n", version, NEW_KEY_VERSION); error = EXIT_FAILURE; /* continue */ } new_key = mifare_desfire_des_key_new (new_key_data); res = mifare_desfire_authenticate (tags[i], 0, new_key); free (new_key); if (res < 0) { freefare_perror (tags[i], "mifare_desfire_authenticate"); error = EXIT_FAILURE; break; } free (aid); /* Resetdefault settings */ res = mifare_desfire_select_application (tags[i], NULL); if (res < 0) { freefare_perror (tags[i], "mifare_desfire_select_application"); error = EXIT_FAILURE; break; } default_key = mifare_desfire_des_key_new (null_key_data); res = mifare_desfire_authenticate (tags[i], 0, default_key); if (res < 0) { freefare_perror (tags[i], "mifare_desfire_authenticate"); error = EXIT_FAILURE; break; } res = mifare_desfire_set_default_key (tags[i], default_key); if (res < 0) { freefare_perror (tags[i], "mifare_desfire_set_default_key"); error = EXIT_FAILURE; break; } mifare_desfire_key_free (default_key); /* Wipeout the card */ res = mifare_desfire_format_picc (tags[i]); if (res < 0) { freefare_perror (tags[i], "mifare_desfire_format_picc"); error = EXIT_FAILURE; break; } } mifare_desfire_disconnect (tags[i]); free (tag_uid); } freefare_free_tags (tags); nfc_close (device); } nfc_exit (context); exit (error); }
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); }
int setup_keys (MifareTag tag, keyvault_t *kv) { int res = 0; MifareDESFireAID aid = mifare_desfire_aid_new (0x1); res = mifare_desfire_select_application(tag, aid); if (res < 0) errx (EXIT_FAILURE, "Application selection failed"); free (aid); MifareDESFireKey old_key = mifare_desfire_des_key_new_with_version (initial_key); res = mifare_desfire_authenticate (tag, 0, old_key); if (res < 0) errx (EXIT_FAILURE, "Authentication to application 1 failed"); MifareDESFireKey new_key; if (get_keytype_3DES (kv, CRYPTO_KEY_KM1)) { printf ("Setting 3DES key K_M1 ...\n"); new_key = mifare_desfire_3des_key_new_with_version (kv->k_m_1); } else { printf ("Setting DES key K_M1 ...\n"); new_key = mifare_desfire_des_key_new_with_version (kv->k_m_1); } res = mifare_desfire_change_key (tag, 0x00, new_key, old_key); if (res < 0) freefare_perror (tag, "Change key 0x00"); res = mifare_desfire_authenticate (tag, 0, new_key); if (res < 0) freefare_perror (tag, "Reauthing after changing key 0x00"); mifare_desfire_key_free (new_key); if (get_keytype_3DES (kv, CRYPTO_KEY_KW1)) { printf ("Setting 3DES key K_W1 ...\n"); new_key = mifare_desfire_3des_key_new_with_version (kv->k_w_1); } else { printf ("Setting DES key K_W1 ...\n"); new_key = mifare_desfire_des_key_new_with_version (kv->k_w_1); } res = mifare_desfire_change_key (tag, 0x01, new_key, old_key); if (res < 0) freefare_perror (tag, "Change key 0x01"); mifare_desfire_key_free (new_key); /* AID 2 ... */ aid = mifare_desfire_aid_new (0x2); res = mifare_desfire_select_application(tag, aid); if (res < 0) errx (EXIT_FAILURE, "Application selection failed"); free (aid); res = mifare_desfire_authenticate (tag, 0, old_key); if (res < 0) errx (EXIT_FAILURE, "Authentication to application 2 failed"); if (get_keytype_3DES (kv, CRYPTO_KEY_KM2)) { printf ("Setting 3DES key K_M2 ...\n"); new_key = mifare_desfire_3des_key_new_with_version (kv->k_m_2); } else { printf ("Setting DES key K_M2 ...\n"); new_key = mifare_desfire_des_key_new_with_version (kv->k_m_2); } res = mifare_desfire_change_key (tag, 0x00, new_key, old_key); if (res < 0) freefare_perror (tag, "Change key 0x00"); res = mifare_desfire_authenticate (tag, 0, new_key); if (res < 0) freefare_perror (tag, "Reauthing after changing key 0x00"); mifare_desfire_key_free (new_key); if (get_keytype_3DES (kv, CRYPTO_KEY_K)) { printf ("Setting 3DES key K ...\n"); new_key = mifare_desfire_3des_key_new_with_version (kv->k); } else { printf ("Setting DES key K ...\n"); new_key = mifare_desfire_des_key_new_with_version (kv->k); } res = mifare_desfire_change_key (tag, 0x01, new_key, old_key); if (res < 0) freefare_perror (tag, "Change key 0x01"); mifare_desfire_key_free (new_key); mifare_desfire_key_free (old_key); return EXIT_SUCCESS; }
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[]) { int error = EXIT_SUCCESS; nfc_device *device = NULL; FreefareTag *tags = NULL; if (argc > 1) errx (EXIT_FAILURE, "usage: %s", argv[0]); nfc_connstring devices[8]; size_t device_count; nfc_context *context; nfc_init (&context); if (context == NULL) errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); device_count = nfc_list_devices (context, devices, 8); if (device_count <= 0) errx (EXIT_FAILURE, "No NFC device found."); for (size_t d = 0; d < device_count; d++) { device = nfc_open (context, devices[d]); if (!device) { warnx ("nfc_open() failed."); error = EXIT_FAILURE; continue; } tags = freefare_get_tags (device); if (!tags) { nfc_close (device); errx (EXIT_FAILURE, "Error listing tags."); } for (int i = 0; (!error) && tags[i]; i++) { if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i])) continue; int res; char *tag_uid = freefare_get_tag_uid (tags[i]); res = mifare_desfire_connect (tags[i]); if (res < 0) { warnx ("Can't connect to Mifare DESFire target."); error = 1; break; }else{ printf("Connected uid: %s\n", tag_uid); } uint8_t key_version; mifare_desfire_get_key_version (tags[i], 0, &key_version); MifareDESFireKey key = malloc(sizeof(MifareDESFireKey)); res = mifare_desfire_auto_authenticate(tags[i], 0, key); if(res < 0){ printf("Error while geting the master key.....\n"); break; } MifareDESFireAID aid = mifare_desfire_aid_new (0x112233); //res = mifare_desfire_create_application (tags[i], aid, 0xFF, 1); size_t count; MifareDESFireAID **aids = malloc(sizeof(MifareDESFireAID*)); res = mifare_desfire_get_application_ids(tags[i], aids, &count); if(res==0){ printf("found %d applicaton/s\n", (int)count); //struct MifareDESFireAID aidArr[count] = *aids; int j; for(j=0; j<count; j++){ // Fails here aid = (*aids)[j]; printf("aid %d: %x\n", j, mifare_desfire_aid_get_aid(aid)); if(mifare_desfire_aid_get_aid(aid) == 0x112233){ if(mifare_desfire_select_application(tags[i], aid) == 0){ printf("app selected...\n"); size_t fileCount = 0; uint8_t **files = malloc(sizeof(uint8_t)); int rra = mifare_desfire_get_file_ids(tags[i], files, &fileCount); printf("%d found %d file ids\n", rra, (int)fileCount); } } } printf("ok\n"); }else{ printf("error res is %d\n", res); } mifare_desfire_key_free (key); free (tag_uid); mifare_desfire_disconnect (tags[i]); } freefare_free_tags (tags); nfc_close (device); } nfc_exit (context); exit (error); } /* main() */
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 resetKey() { nfc_device *device = NULL; MifareTag *tag = NULL; MifareDESFireAID aid; uint8_t key_data_null[8] = { 0,0,0,0,0,0,0,0}; MifareDESFireKey defaultKey = mifare_desfire_des_key_new_with_version (key_data_null); device = getRfidDevice(); if (!device) return NULL; tag = freefare_get_tags(device); mifare_desfire_connect (tag[0]); aid = mifare_desfire_aid_new(AID_NUMBER); if (mifare_desfire_select_application (tag[0], aid) < 0) { nfc_close(device); return -1; } MifareDESFireKey key = mifare_desfire_3des_key_new(createDesKey(makePinpad(),"des-ede")); if (mifare_desfire_authenticate(tag[0], defaultKeyNumber, key) < 0) { fprintf(stderr,"Authentication with key failed\n"); nfc_close(device); return -1; } if (mifare_desfire_change_key(tag[0], 0, defaultKey, key) < 0) { fprintf(stderr,"Key change to defaultKey failed\n"); nfc_close(device); return -1; } if (mifare_desfire_authenticate(tag[0], defaultKeyNumber, defaultKey) < 0 ) { fprintf(stderr,"Authentication with defaultKey failed\n"); nfc_close(device); return -1; } if (mifare_desfire_select_application (tag[0], NULL) < 0) { nfc_close(device); return -1; } if (mifare_desfire_authenticate(tag[0], defaultKeyNumber, defaultKey) < 0) { fprintf(stderr,"Authentication with key failed\n"); if (mifare_desfire_change_key(tag[0], 0, defaultKey, key) < 0) { fprintf(stderr,"Key change to defaultKey in Master application failed\n"); nfc_close(device); return -1; } } printf("Schlüssel Erfolgreich geändert\n"); nfc_close(device); return 0; }