diff --git a/NEWS b/NEWS
index f061c34..07b4a5f 100644
--- a/NEWS
+++ b/NEWS
@@ -5,8 +5,8 @@ Changes between 0.2.3 and 0.3.0 [XX xxx XXXX]
*) Add support for 3K3DES and AES cryptographic operations.
*) New functions mifare_desfire_free_mem(),
mifare_desfire_set_configuration(), mifare_desfire_set_default_key(),
- mifare_desfire_get_card_uid(), for Mifare DESFire EV1 targets
- manipulation.
+ mifare_desfire_set_ats(), mifare_desfire_get_card_uid(), for Mifare
+ DESFire EV1 targets manipulation.
*) Deprecate authentication information when deleting the currently selected
application
diff --git a/examples/Makefile.am b/examples/Makefile.am
index a1cf91b..c92abed 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -6,6 +6,7 @@ AM_LDFLAGS = @LIBNFC_LIBS@
bin_PROGRAMS = mifare-classic-format \
mifare-classic-write-ndef \
mifare-desfire-access \
+ mifare-desfire-ev1-configure-ats \
mifare-desfire-ev1-configure-default-key \
mifare-desfire-ev1-configure-random-uid \
mifare-desfire-format \
@@ -21,6 +22,9 @@ mifare_classic_write_ndef_LDADD = -lnfc $(top_builddir)/libfreefare/libfreefare.
mifare_desfire_access_SOURCES = mifare-desfire-access.c
mifare_desfire_access_LDADD = -lnfc $(top_builddir)/libfreefare/libfreefare.la
+mifare_desfire_ev1_configure_ats_SOURCES = mifare-desfire-ev1-configure-ats.c
+mifare_desfire_ev1_configure_ats_LDADD = -lnfc $(top_builddir)/libfreefare/libfreefare.la
+
mifare_desfire_ev1_configure_default_key_SOURCES = mifare-desfire-ev1-configure-default-key.c
mifare_desfire_ev1_configure_default_key_LDADD = -lnfc $(top_builddir)/libfreefare/libfreefare.la
diff --git a/examples/mifare-desfire-ev1-configure-ats.c b/examples/mifare-desfire-ev1-configure-ats.c
new file mode 100644
index 0000000..3be4913
--- /dev/null
+++ b/examples/mifare-desfire-ev1-configure-ats.c
@@ -0,0 +1,153 @@
+/*-
+ * Copyright (C) 2010, Romain Tartiere.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see
+ *
+ * $Id$
+ */
+
+#include "config.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+
+uint8_t null_key_data[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+uint8_t new_ats[] = { 0x06, 0x75, 0x77, 0x81, 0x02, 0x42 };
+
+struct {
+ bool interactive;
+} configure_options = {
+ .interactive = true
+};
+
+void
+usage(char *progname)
+{
+ fprintf (stderr, "usage: %s [-y]\n", progname);
+ fprintf (stderr, "\nOptions:\n");
+ fprintf (stderr, " -y Do not ask for confirmation (dangerous)\n");
+}
+
+int
+main(int argc, char *argv[])
+{
+ int ch;
+ int error = EXIT_SUCCESS;
+ nfc_device_t *device = NULL;
+ MifareTag *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);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ nfc_device_desc_t devices[8];
+ size_t device_count;
+
+ nfc_list_devices (devices, 8, &device_count);
+ if (!device_count)
+ errx (EXIT_FAILURE, "No NFC device found.");
+
+ for (size_t d = 0; (!error) && (d < device_count); d++) {
+ device = nfc_connect (&(devices[d]));
+ if (!device) {
+ warnx ("nfc_connect() failed.");
+ error = EXIT_FAILURE;
+ continue;
+ }
+
+ tags = freefare_get_tags (device);
+ if (!tags) {
+ nfc_disconnect (device);
+ errx (EXIT_FAILURE, "Error listing Mifare DESFire tags.");
+ }
+
+ for (int i = 0; (!error) && tags[i]; i++) {
+ if (DESFIRE != freefare_get_tag_type (tags[i]))
+ continue;
+
+ char *tag_uid = freefare_get_tag_uid (tags[i]);
+ char buffer[BUFSIZ];
+
+ printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid);
+ bool do_it = true;
+ int res;
+
+ if (configure_options.interactive) {
+ printf ("Change ATS? [yN] ");
+ fgets (buffer, BUFSIZ, stdin);
+ do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
+ } else {
+ printf ("\n");
+ }
+
+ if (do_it) {
+
+ res = mifare_desfire_connect (tags[i]);
+ if (res < 0) {
+ warnx ("Can't connect to Mifare DESFire target.");
+ error = EXIT_FAILURE;
+ break;
+ }
+
+ 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);
+
+ res = mifare_desfire_set_ats (tags[i], new_ats);
+ if (res < 0) {
+ freefare_perror (tags[i], "mifare_desfire_set_ats");
+ error = EXIT_FAILURE;
+ break;
+ }
+
+ mifare_desfire_disconnect (tags[i]);
+
+ }
+
+ free (tag_uid);
+ }
+
+ freefare_free_tags (tags);
+ nfc_disconnect (device);
+ }
+
+ exit (error);
+} /* main() */
+
diff --git a/libfreefare/freefare.h b/libfreefare/freefare.h
index b655035..3c1e8c8 100644
--- a/libfreefare/freefare.h
+++ b/libfreefare/freefare.h
@@ -320,6 +320,7 @@ int mifare_desfire_get_version (MifareTag tag, struct mifare_desfire_version_i
int mifare_desfire_free_mem (MifareTag tag, uint32_t *size);
int mifare_desfire_set_configuration (MifareTag tag, bool disable_format, bool enable_random_uid);
int mifare_desfire_set_default_key (MifareTag tag, MifareDESFireKey key);
+int mifare_desfire_set_ats (MifareTag tag, uint8_t *ats);
int mifare_desfire_get_card_uid (MifareTag tag, char **uid);
int mifare_desfire_get_file_ids (MifareTag tag, uint8_t *files[], size_t *count);
int mifare_desfire_get_file_settings (MifareTag tag, uint8_t file_no, struct mifare_desfire_file_settings *settings);
diff --git a/libfreefare/mifare_desfire.c b/libfreefare/mifare_desfire.c
index 121e072..211aba8 100644
--- a/libfreefare/mifare_desfire.c
+++ b/libfreefare/mifare_desfire.c
@@ -929,6 +929,40 @@ mifare_desfire_set_default_key (MifareTag tag, MifareDESFireKey key)
return 0;
}
+int
+mifare_desfire_set_ats (MifareTag tag, uint8_t *ats)
+{
+ ASSERT_ACTIVE (tag);
+ ASSERT_MIFARE_DESFIRE (tag);
+
+ BUFFER_INIT (cmd, 34);
+ BUFFER_INIT (res, 1 + CMAC_LENGTH);
+
+ BUFFER_APPEND (cmd, 0x5C);
+ BUFFER_APPEND (cmd, 0x02);
+ BUFFER_APPEND_BYTES (cmd, ats, *ats);
+ switch (MIFARE_DESFIRE (tag)->authentication_scheme) {
+ case AS_LEGACY:
+ iso14443a_crc_append (cmd + 2 , __cmd_n - 2);
+ __cmd_n += 2;
+ break;
+ case AS_NEW:
+ desfire_crc32_append (cmd, __cmd_n);
+ __cmd_n += 4;
+ break;
+ }
+ BUFFER_APPEND (cmd, 0x80);
+
+ uint8_t *p = mifare_cryto_preprocess_data (tag, cmd, &__cmd_n, 2, MDCM_ENCIPHERED | NO_CRC | ENC_COMMAND);
+
+ DESFIRE_TRANSCEIVE2 (tag, p, __cmd_n, res);
+
+ ssize_t sn = __res_n;
+ p = mifare_cryto_postprocess_data (tag, res, &sn, MDCM_PLAIN | CMAC_COMMAND | CMAC_VERIFY);
+
+ return 0;
+}
+
int
mifare_desfire_get_card_uid (MifareTag tag, char **uid)
{