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;
}
Exemple #2
0
int mifare_desfire_auto_authenticate (FreefareTag tag, uint8_t key_no, MifareDESFireKey key)
{
    /* Determine which key is currently the master one */
    uint8_t key_version;
    int res = mifare_desfire_get_key_version (tag, key_no, &key_version);

    printf("key_version: %x\n", key_version);
    switch (key_version) {
        case 0x00:
          key = mifare_desfire_des_key_new_with_version (key_data_null);
        break;
        case 0x42:
          key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version);
        break;
        case 0xAA:
          key = mifare_desfire_des_key_new_with_version (key_data_des);
        break;
        case 0xC7:
          key = mifare_desfire_3des_key_new_with_version (key_data_3des);
        break;
        case 0x55:
          key = mifare_desfire_3k3des_key_new_with_version (key_data_3k3des);
        break;
    }

    /* Authenticate with this key */
    switch (key_version) {
        case 0x00:
        case 0xAA:
        case 0xC7:
            res = mifare_desfire_authenticate (tag, key_no, key);
        break;
        case 0x55:
            res = mifare_desfire_authenticate_iso (tag, key_no, key);
        break;
        case 0x42:
            res = mifare_desfire_authenticate_aes (tag, key_no, key);
        break;
    }

    return res;
}
void
test_mifare_desfire_ev1_aes2 (void)
{
    int res;
    MifareDESFireKey  key;

    mifare_desfire_auto_authenticate (tag, 0);

    // Setup the AES key
    key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version);
    res = mifare_desfire_change_key (tag, 0x80, key, NULL);
    cut_assert_success ("mifare_desfire_change_key");
    mifare_desfire_key_free (key);

    // Authenticate with the AES key
    key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version);
    res = mifare_desfire_authenticate_aes (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate");
    mifare_desfire_key_free (key);

    res = mifare_desfire_format_picc (tag);
    cut_assert_success ("mifare_desfire_format_picc()");

    key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version);
    res = mifare_desfire_authenticate_aes (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate");
    mifare_desfire_key_free (key);

    uint32_t size;
    res = mifare_desfire_free_mem (tag, &size);
    cut_assert_success ("mifare_desfire_free_mem");

    // Do some commands to check CMAC is properly handled
    res = mifare_desfire_free_mem (tag, &size);
    cut_assert_success ("mifare_desfire_free_mem");

    struct mifare_desfire_version_info info;
    res = mifare_desfire_get_version (tag, &info);
    cut_assert_success ("mifare_desfire_get_version");

    res = mifare_desfire_change_key_settings (tag, 0x0F);
    cut_assert_success ("mifare_desfire_change_key_settings");

    res = mifare_desfire_free_mem (tag, &size);
    cut_assert_success ("mifare_desfire_free_mem");

    MifareDESFireAID aid = mifare_desfire_aid_new (0x112233);

    mifare_desfire_delete_application (tag, aid);

    res = mifare_desfire_create_application (tag, aid, 0xff, 0x81);
    cut_assert_success ("mifare_desfire_create_application");

    res = mifare_desfire_select_application (tag, aid);
    cut_assert_success ("mifare_desfire_select_application");

    key = mifare_desfire_aes_key_new (key_data_aes);
    res = mifare_desfire_authenticate_aes (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate");
    free (key);

    key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version);
    res = mifare_desfire_change_key (tag, 0x00, key, NULL);
    cut_assert_success ("mifare_desfire_change_key");
    mifare_desfire_key_free (key);

    key = mifare_desfire_aes_key_new (key_data_aes);
    res = mifare_desfire_authenticate_aes (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate");
    free (key);

    res = mifare_desfire_create_std_data_file (tag, 1, MDCM_MACED, 0x0000, 512);
    if ((mifare_desfire_last_picc_error (tag) != DUPLICATE_ERROR) && (mifare_desfire_last_picc_error(tag) != OPERATION_OK))
	cut_assert_success ("mifare_desfire_create_std_data_file");

    char sample_data[] = "Hello World!  I'm a string that is probably too long "
	"to feet in a single frame.  For this reason, it will be split and like"
	"ly, some failure in the algorirthm should trigger an error in this uni"
	"t test.";
    res = mifare_desfire_write_data_ex (tag, 1, 0, strlen (sample_data), sample_data, MDCM_MACED);
    cut_assert_success ("mifare_desfire_write_data");

    char buffer[1024];

    res = mifare_desfire_read_data_ex (tag, 1, 0, 27, buffer, MDCM_MACED);
    cut_assert_success ("mifare_desfire_read_data");
    cut_assert_equal_memory (buffer, res, sample_data, 27, cut_message ("AES crypto failed"));

    uint8_t s, c;
    res = mifare_desfire_get_key_settings (tag, &s, &c);
    cut_assert_success ("mifare_desfire_get__key_settings");

    res = mifare_desfire_read_data_ex (tag, 1, 27, 27, buffer, MDCM_MACED);
    cut_assert_success ("mifare_desfire_read_data");
    cut_assert_equal_memory (buffer, res, sample_data + 27, 27, cut_message ("AES crypto failed"));

    res = mifare_desfire_read_data_ex (tag, 1, 0, 0, buffer, MDCM_MACED);
    cut_assert_success ("mifare_desfire_read_data");
    cut_assert_equal_memory (buffer, strlen (buffer), sample_data, strlen (sample_data), cut_message ("AES crypto failed"));

    // Revert to the default DES key
    res = mifare_desfire_select_application (tag, NULL);
    cut_assert_success ("mifare_desfire_select_application");

    key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version);
    res = mifare_desfire_authenticate_aes (tag, 0, key);
    cut_assert_success ("mifare_desfire_authenticate");
    mifare_desfire_key_free (key);

    key = mifare_desfire_des_key_new (key_data_null);
    res = mifare_desfire_change_key (tag, 0x00, key, NULL);
    cut_assert_success ("mifare_desfire_change_key");
    mifare_desfire_key_free (key);
}
int
main (void)
{
    uint8_t issuer_key_data[16];

    nfc_connstring nfc_devices[8];
    size_t nfc_device_count;

    nfc_device_count = nfc_list_devices (NULL, nfc_devices, 8);

    for (size_t n = 0; n < nfc_device_count; n++) {
	nfc_device *nfc_device = nfc_open (NULL, nfc_devices[n]);

	MifareTag *tags = freefare_get_tags (nfc_device);
	for (int i = 0; tags[i]; i++) {
	    MifareTag tag = tags[i];
	    if (DESFIRE == freefare_get_tag_type (tag)) {

		printf ("Fond Mifare DESFire with UID: %s\n", freefare_get_tag_uid (tag));

		printf ("Issuer private key: ");
		char buffer[BUFSIZ];
		system ("stty -echo");
		fgets (buffer, BUFSIZ, stdin);
		system ("stty echo");
		char *p;
		if ((p = strchr (buffer, '\n')))
		    *p = '\0';
		ucard_derivate_password (buffer, strlen (buffer), 16, issuer_key_data);
		memset (buffer, '\0', strlen (buffer));

		MifareDESFireKey key = mifare_desfire_aes_key_new (issuer_key_data);

		MifareDESFireAID ucard_info_aid = mifare_desfire_aid_new (UCARD_INFO_AID);

		int res = mifare_desfire_connect (tag);

		res = mifare_desfire_select_application (tag, ucard_info_aid);
		if (res < 0) {
		    freefare_perror (tag, "mifare_desfire_select_application");
		    goto end;
		}
		res = mifare_desfire_authenticate_aes (tag, 1, key);
		if (res < 0) {
		    freefare_perror (tag, "mifare_desfire_authenticate_aes");
		    goto end;
		}

		char owner_info[BUFSIZ];
		res = mifare_desfire_read_data_ex (tag, 10, 0, 0, owner_info, MDCM_ENCIPHERED);
		if (res < 0) {
		    freefare_perror (tag, "mifare_desfire_read_data");
		    goto end;
		}

		owner_info[res] = '\0';

		printf ("Owner: %s\n", owner_info);

end:
		mifare_desfire_disconnect (tag);

		mifare_desfire_key_free (key);

		free (ucard_info_aid);
	    }
	}

	nfc_close (nfc_device);
    }

    exit(EXIT_SUCCESS);
}
Exemple #5
0
int
main (int argc, char *argv[])
{
    /*
     * Collect information
     */

    bool f_flag = false;
    char *p;

    char ch;
    while ((ch = getopt (argc, argv, "f")) != -1) {
	switch (ch) {
	case 'f':
	    f_flag = true;
	    break;
	default:
	    usage (argv[0]);
	    exit (EXIT_FAILURE);
	    break;
	}
    }

    char issuer_address[BUFSIZ];
    fprintf (stderr, "Card issuer address: ");
    fgets (issuer_address, BUFSIZ, stdin);
    if ((p = strchr (issuer_address, '\n')))
	*p = '\0';

    char issuer_password[BUFSIZ];
    read_password ("Issuer password", issuer_password, BUFSIZ);
    fprintf (stderr, "\n");
    uint8_t issuer_password_data[16];
    ucard_derivate_password (issuer_password, strlen (issuer_password), 16, issuer_password_data);
    memset (issuer_password, '\0', strlen (issuer_password));
    MifareDESFireKey card_issuer_key = mifare_desfire_aes_key_new (issuer_password_data);

    char owner_full_name[BUFSIZ];
    fprintf (stderr, "Card owner full user name: ");
    fgets (owner_full_name, BUFSIZ, stdin);
    if ((p = strchr (owner_full_name, '\n')))
	*p = '\0';

    char user_password[BUFSIZ];
    read_password ("User password", user_password, BUFSIZ);
    fprintf (stderr, "\n");
    uint8_t user_key_data[16];
    ucard_derivate_password (user_password, strlen (user_password), 16, user_key_data);
    memset (user_password, '\0', strlen (user_password));
    MifareDESFireKey user_key = mifare_desfire_aes_key_new_with_version (user_key_data, UCARD_AES_KEY_VERSION);

    char admin_password[BUFSIZ];
    read_password ("Admin password", admin_password, BUFSIZ);
    fprintf (stderr, "\n");
    uint8_t admin_key_data[16];
    ucard_derivate_password (admin_password, strlen (admin_password), 16, admin_key_data);
    memset (admin_password, '\0', strlen (admin_password));

    MifareDESFireKey admin_key = mifare_desfire_aes_key_new_with_version (admin_key_data, UCARD_AES_KEY_VERSION);

    uint8_t null_key_data[16] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    MifareDESFireKey null_des_key = mifare_desfire_des_key_new (null_key_data);
    MifareDESFireKey null_aes_key = mifare_desfire_aes_key_new (null_key_data);

    nfc_connstring nfc_devices[8];
    size_t nfc_device_count;

    nfc_device_count = nfc_list_devices (NULL, nfc_devices, 8);

    for (size_t n = 0; n < nfc_device_count; n++) {
	nfc_device *nfc_device = nfc_open(NULL, nfc_devices[n]);

	MifareTag *tags = freefare_get_tags (nfc_device);
	for (int i = 0; tags[i]; i++) {
	    MifareTag tag = tags[i];
	    if (DESFIRE == freefare_get_tag_type (tag)) {

		/* Actually setup the card */

		printf ("Fond Mifare DESFire with UID: %s\n", freefare_get_tag_uid (tag));

		/*
		 * Master Application
		 *
		 * Key  0: Card owner 'user' private key
		 */

		MifareDESFireAID ucard_info_aid = mifare_desfire_aid_new (UCARD_INFO_AID);

		int res = mifare_desfire_connect (tag);
		if (f_flag) {
		    if (0 == res) res = mifare_desfire_authenticate_aes (tag, 0, user_key);
		    if (0 == res) res = mifare_desfire_format_picc (tag);
		} else {
		    if (0 == res) res = mifare_desfire_authenticate (tag, 0, null_des_key);
		    if (0 == res) res = mifare_desfire_change_key (tag, 0, user_key, NULL);
		    if (0 == res) res = mifare_desfire_authenticate_aes (tag, 0, user_key);
		}
		if (0 == res) res = mifare_desfire_create_application (tag, ucard_info_aid, 0x0F, 0x83);
		if (!f_flag) {
		    if (0 == res) res = mifare_desfire_change_key_settings (tag, 0x01);
		}

		/*
		 * Card information application
		 *
		 * Key  0: Card owner 'admin' private key
		 * Key  1: Card issuer private key
		 * Key  2: Anonymous access public key
		 *
		 * File  9: Card issuer information
		 * File 10: Card owner information
		 * File 11: Keyring
		 */

		if (0 == res) res = mifare_desfire_select_application (tag, ucard_info_aid);
		if (0 == res) res = mifare_desfire_authenticate_aes (tag, 0, null_aes_key);
		if (0 == res) res = mifare_desfire_change_key (tag, 0, admin_key, NULL);
		if (0 == res) res = mifare_desfire_authenticate_aes (tag, 0, admin_key);
		if (0 == res) res = mifare_desfire_change_key (tag, 1, card_issuer_key, NULL);

		if (0 == res) res = mifare_desfire_create_std_data_file (tag, 9, MDCM_ENCIPHERED, 0x0000, strlen (issuer_address));
		if (0 == res) res = mifare_desfire_write_data (tag, 9, 0, strlen (issuer_address), issuer_address);
		if (strlen (issuer_address) ==  (size_t) res) res = mifare_desfire_change_file_settings (tag, 9, MDCM_ENCIPHERED, 0x2F11);

		if (0 == res) res = mifare_desfire_create_std_data_file (tag, 10, MDCM_ENCIPHERED, 0x0000, strlen (owner_full_name));
		if (0 == res) res = mifare_desfire_write_data (tag, 10, 0, strlen (owner_full_name), owner_full_name);
		if (strlen (owner_full_name) == (size_t) res) res = mifare_desfire_change_file_settings (tag, 10, MDCM_ENCIPHERED, 0x0F11);

		if (0 == res) res = mifare_desfire_create_linear_record_file (tag, 11, MDCM_ENCIPHERED, 0xF20F, 3 + 16, 24);

		if (0 == res) res = mifare_desfire_change_key_settings (tag, 0x01);

		if (res < 0) {
		    fprintf (stderr, "Oops, something went wrong! (%s)\n", freefare_strerror (tag));
		}

		mifare_desfire_disconnect (tag);

		free (ucard_info_aid);
	    }
	}

	nfc_close (nfc_device);
    }

    mifare_desfire_key_free (admin_key);
    mifare_desfire_key_free (user_key);
    mifare_desfire_key_free (card_issuer_key);
    mifare_desfire_key_free (null_aes_key);
    mifare_desfire_key_free (null_des_key);

    exit(EXIT_SUCCESS);
}