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);
}
Exemple #4
0
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);
}