Guest User

mifare-classic-write-ndef.c

a guest
Feb 22nd, 2012
694
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.65 KB | None | 0 0
  1. /*-
  2.  * Copyright (C) 2010, Romain Tartiere, Romuald Conty.
  3.  *
  4.  * This program is free software: you can redistribute it and/or modify it
  5.  * under the terms of the GNU Lesser General Public License as published by the
  6.  * Free Software Foundation, either version 3 of the License, or (at your
  7.  * option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful, but WITHOUT
  10.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12.  * more details.
  13.  *
  14.  * You should have received a copy of the GNU Lesser General Public License
  15.  * along with this program.  If not, see <http://www.gnu.org/licenses/>
  16.  *
  17.  * $Id: mifare-classic-write-ndef.c 946 2011-10-11 22:24:26Z [email protected] $
  18.  */
  19.  
  20. #include "config.h"
  21.  
  22. #include <err.h>
  23. #include <errno.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <strings.h>
  27. #include <unistd.h>
  28.  
  29. #include <nfc/nfc.h>
  30.  
  31. #include <freefare.h>
  32.  
  33. #define MIN(a,b) ((a < b) ? a: b)
  34.  
  35. MifareClassicKey default_keys[] = {
  36.     { 0xff,0xff,0xff,0xff,0xff,0xff },
  37.     { 0xd3,0xf7,0xd3,0xf7,0xd3,0xf7 },
  38.     { 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5 },
  39.     { 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5 },
  40.     { 0x4d,0x3a,0x99,0xc3,0x51,0xdd },
  41.     { 0x1a,0x98,0x2c,0x7e,0x45,0x9a },
  42.     { 0xaa,0xbb,0xcc,0xdd,0xee,0xff },
  43.     { 0x00,0x00,0x00,0x00,0x00,0x00 }
  44. };
  45.  
  46. struct mifare_classic_key_and_type {
  47.     MifareClassicKey key;
  48.     MifareClassicKeyType type;
  49. };
  50.  
  51. const MifareClassicKey default_keyb = {
  52.     0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7
  53. };
  54.  
  55. const uint8_t ndef_default_msg[33] = {
  56.     0xd1, 0x02, 0x1c, 0x53, 0x70, 0x91, 0x01, 0x09,
  57.     0x54, 0x02, 0x65, 0x6e, 0x4c, 0x69, 0x62, 0x6e,
  58.     0x66, 0x63, 0x51, 0x01, 0x0b, 0x55, 0x03, 0x6c,
  59.     0x69, 0x62, 0x6e, 0x66, 0x63, 0x2e, 0x6f, 0x72,
  60.     0x67
  61. };
  62. uint8_t *ndef_msg;
  63. size_t  ndef_msg_len;
  64.  
  65. int
  66. search_sector_key (MifareTag tag, MifareClassicSectorNumber sector, MifareClassicKey *key, MifareClassicKeyType *key_type)
  67. {
  68.     MifareClassicBlockNumber block = mifare_classic_sector_last_block (sector);
  69.  
  70.     /*
  71.      * FIXME: We should not assume that if we have full access to trailer block
  72.      *        we also have a full access to data blocks.
  73.      */
  74.     mifare_classic_disconnect (tag);
  75.     for (size_t i = 0; i < (sizeof (default_keys) / sizeof (MifareClassicKey)); i++) {
  76.     if ((0 == mifare_classic_connect (tag)) && (0 == mifare_classic_authenticate (tag, block, default_keys[i], MFC_KEY_A))) {
  77.         if ((1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_KEYA, MFC_KEY_A)) &&
  78.         (1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_ACCESS_BITS, MFC_KEY_A)) &&
  79.         (1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_KEYB, MFC_KEY_A))) {
  80.         memcpy (key, &default_keys[i], sizeof (MifareClassicKey));
  81.         *key_type = MFC_KEY_A;
  82.         return 1;
  83.         }
  84.     }
  85.     mifare_classic_disconnect (tag);
  86.  
  87.     if ((0 == mifare_classic_connect (tag)) && (0 == mifare_classic_authenticate (tag, block, default_keys[i], MFC_KEY_B))) {
  88.         if ((1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_KEYA, MFC_KEY_B)) &&
  89.         (1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_ACCESS_BITS, MFC_KEY_B)) &&
  90.         (1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_KEYB, MFC_KEY_B))) {
  91.         memcpy (key, &default_keys[i], sizeof (MifareClassicKey));
  92.         *key_type = MFC_KEY_B;
  93.         return 1;
  94.         }
  95.     }
  96.     mifare_classic_disconnect (tag);
  97.     }
  98.  
  99.     warnx ("No known authentication key for sector 0x%02x\n", sector);
  100.     return 0;
  101. }
  102.  
  103. int
  104. fix_mad_trailer_block (nfc_device_t *device, MifareTag tag, MifareClassicSectorNumber sector, MifareClassicKey key, MifareClassicKeyType key_type)
  105. {
  106.     MifareClassicBlock block;
  107.     mifare_classic_trailer_block (&block, mad_public_key_a, 0x0, 0x1, 0x1, 0x6, 0x00, default_keyb);
  108.     if (mifare_classic_authenticate (tag, mifare_classic_sector_last_block (sector), key, key_type) < 0) {
  109.     nfc_perror (device, "fix_mad_trailer_block mifare_classic_authenticate");
  110.     return -1;
  111.     }
  112.     if (mifare_classic_write (tag, mifare_classic_sector_last_block (sector), block) < 0) {
  113.     nfc_perror (device, "mifare_classic_write");
  114.     return -1;
  115.     }
  116.     return 0;
  117. }
  118.  
  119. void
  120. usage(char *progname)
  121. {
  122.     fprintf (stderr, "usage: %s -i FILE\n", progname);
  123.     fprintf (stderr, "\nOptions:\n");
  124.     fprintf (stderr, "  -i     Use FILE as NDEF message to write on card\n");
  125. }
  126.  
  127. int
  128. main(int argc, char *argv[])
  129. {
  130.     int error = 0;
  131.     nfc_device_t *device = NULL;
  132.     MifareTag *tags = NULL;
  133.     Mad mad;
  134.     MifareClassicKey transport_key = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  135.  
  136.     int ch;
  137.     char *ndef_input = NULL;
  138.     while ((ch = getopt (argc, argv, "hi:")) != -1) {
  139.     switch (ch) {
  140.     case 'h':
  141.         usage(argv[0]);
  142.         exit (EXIT_SUCCESS);
  143.         break;
  144.     case 'i':
  145.         ndef_input = optarg;
  146.         break;
  147.     case '?':
  148.         if (optopt == 'i')
  149.         fprintf (stderr, "Option -%c requires an argument.\n", optopt);
  150.     default:
  151.         usage (argv[0]);
  152.         exit (EXIT_FAILURE);
  153.     }
  154.     }
  155.  
  156.     if (ndef_input == NULL) {
  157.         ndef_msg = (uint8_t*)ndef_default_msg;
  158.         ndef_msg_len = sizeof(ndef_default_msg);
  159.     } else {
  160.     FILE* ndef_stream = NULL;
  161.     if ((strlen (ndef_input) == 1) && (ndef_input[0] == '-')) {
  162.             // FIXME stdin as input have to be readed and buffered in ndef_msg
  163.         ndef_stream = stdin;
  164.             fprintf (stderr, "stdin as NDEF is not implemented");
  165.             exit (EXIT_FAILURE);
  166.     } else {
  167.         ndef_stream = fopen(ndef_input, "rb");
  168.         if (!ndef_stream) {
  169.         fprintf (stderr, "Could not open file %s.\n", ndef_input);
  170.         exit (EXIT_FAILURE);
  171.         }
  172.         fseek(ndef_stream, 0L, SEEK_END);
  173.         ndef_msg_len = ftell(ndef_stream);
  174.             fseek(ndef_stream, 0L, SEEK_SET);
  175.  
  176.         if (!(ndef_msg = malloc (ndef_msg_len))) {
  177.         err (EXIT_FAILURE, "malloc");
  178.         }
  179.         if (fread (ndef_msg, 1, ndef_msg_len, ndef_stream) != ndef_msg_len) {
  180.         fprintf (stderr, "Could not read NDEF from file: %s\n", ndef_input);
  181.         fclose (ndef_stream);
  182.         exit (EXIT_FAILURE);
  183.         }
  184.         fclose (ndef_stream);
  185.     }
  186.     }
  187.     printf ("NDEF file is %zu bytes long.\n", ndef_msg_len);
  188.  
  189.     struct mifare_classic_key_and_type *card_write_keys;
  190.     if (!(card_write_keys = malloc (40 * sizeof (*card_write_keys)))) {
  191.     err (EXIT_FAILURE, "malloc");
  192.     }
  193.  
  194.     nfc_device_desc_t devices[8];
  195.     size_t device_count;
  196.  
  197.     nfc_list_devices (devices, 8, &device_count);
  198.     if (!device_count)
  199.     errx (EXIT_FAILURE, "No NFC device found.");
  200.  
  201.     for (size_t d = 0; d < device_count; d++) {
  202.     device = nfc_connect (&(devices[d]));
  203.     if (!device) {
  204.         warnx ("nfc_connect() failed.");
  205.         error = EXIT_FAILURE;
  206.         continue;
  207.     }
  208.  
  209.     tags = freefare_get_tags (device);
  210.     if (!tags) {
  211.         nfc_disconnect (device);
  212.         errx (EXIT_FAILURE, "Error listing MIFARE classic tag.");
  213.     }
  214.  
  215.     for (int i = 0; (!error) && tags[i]; i++) {
  216.         switch (freefare_get_tag_type (tags[i])) {
  217.         case CLASSIC_1K:
  218.         case CLASSIC_4K:
  219.         break;
  220.         default:
  221.         continue;
  222.         }
  223.  
  224.         char *tag_uid = freefare_get_tag_uid (tags[i]);
  225.         char buffer[BUFSIZ];
  226.  
  227.         printf ("Found %s with UID %s. Write NDEF [yN] ", freefare_get_tag_friendly_name (tags[i]), tag_uid);
  228.         fgets (buffer, BUFSIZ, stdin);
  229.         bool write_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
  230.  
  231.         for (int n = 0; n < 40; n++) {
  232.         memcpy(card_write_keys[n].key, transport_key, sizeof (transport_key));
  233.         card_write_keys[n].type = MFC_KEY_A;
  234.         }
  235.  
  236.         if (write_ndef) {
  237.         switch (freefare_get_tag_type (tags[i])) {
  238.         case CLASSIC_4K:
  239.             if (!search_sector_key (tags[i], 0x10, &(card_write_keys[0x10].key), &(card_write_keys[0x10].type))) {
  240.             error = 1;
  241.             goto error;
  242.             }
  243.             /* fallthrough */
  244.         case CLASSIC_1K:
  245.             if (!search_sector_key (tags[i], 0x00, &(card_write_keys[0x00].key), &(card_write_keys[0x00].type))) {
  246.             error = 1;
  247.             goto error;
  248.             }
  249.             break;
  250.         default:
  251.             /* Keep compiler quiet */
  252.             break;
  253.         }
  254.  
  255.         if (!error) {
  256.             /* Ensure the auth key is always a B one. If not, change it! */
  257.             switch (freefare_get_tag_type (tags[i])) {
  258.             case CLASSIC_4K:
  259.             if (card_write_keys[0x10].type != MFC_KEY_B) {
  260.                 if( 0 != fix_mad_trailer_block (device, tags[i], 0x10, card_write_keys[0x10].key, card_write_keys[0x10].type)) {
  261.                 error = 1;
  262.                 goto error;
  263.                 }
  264.                 memcpy (&(card_write_keys[0x10].key), &default_keyb, sizeof (MifareClassicKey));
  265.                 card_write_keys[0x10].type = MFC_KEY_B;
  266.             }
  267.             /* fallthrough */
  268.             case CLASSIC_1K:
  269.             if (card_write_keys[0x00].type != MFC_KEY_B) {
  270.                 if( 0 != fix_mad_trailer_block (device, tags[i], 0x00, card_write_keys[0x00].key, card_write_keys[0x00].type)) {
  271.                 error = 1;
  272.                 goto error;
  273.                 }
  274.                 memcpy (&(card_write_keys[0x00].key), &default_keyb, sizeof (MifareClassicKey));
  275.                 card_write_keys[0x00].type = MFC_KEY_B;
  276.             }
  277.             break;
  278.             default:
  279.             /* Keep compiler quiet */
  280.             break;
  281.             }
  282.         }
  283.  
  284.         size_t encoded_size;
  285.         uint8_t *tlv_data = tlv_encode (3, ndef_msg, ndef_msg_len, &encoded_size);
  286.  
  287.         /*
  288.          * At his point, we should have collected all information needed to
  289.          * succeed.
  290.          */
  291.  
  292.         // If the card already has a MAD, load it.
  293.         if ((mad = mad_read (tags[i]))) {
  294.             // If our application already exists, erase it.
  295.             MifareClassicSectorNumber *sectors, *p;
  296.             sectors = p = mifare_application_find (mad, mad_nfcforum_aid);
  297.             if (sectors) {
  298.             while (*p) {
  299.                 if (mifare_classic_authenticate (tags[i], mifare_classic_sector_last_block(*p), default_keyb, MFC_KEY_B) < 0) {
  300.                 nfc_perror (device, "mifare_classic_authenticate");
  301.                 error = 1;
  302.                 goto error;
  303.                 }
  304.                 if (mifare_classic_format_sector (tags[i], *p) < 0) {
  305.                 nfc_perror (device, "mifare_classic_format_sector");
  306.                 error = 1;
  307.                 goto error;
  308.                 }
  309.                 p++;
  310.             }
  311.             }
  312.             free (sectors);
  313.             mifare_application_free (mad, mad_nfcforum_aid);
  314.         } else {
  315.  
  316.             // Create a MAD and mark unaccessible sectors in the card
  317.             if (!(mad = mad_new ((freefare_get_tag_type (tags[i]) == CLASSIC_4K) ? 2 : 1))) {
  318.             perror ("mad_new");
  319.             error = 1;
  320.             goto error;
  321.             }
  322.  
  323.             MifareClassicSectorNumber max_s;
  324.             switch (freefare_get_tag_type (tags[i])) {
  325.             case CLASSIC_1K:
  326.             max_s = 15;
  327.             break;
  328.             case CLASSIC_4K:
  329.             max_s = 39;
  330.             break;
  331.             default:
  332.             /* Keep compiler quiet */
  333.             break;
  334.             }
  335.  
  336.             // Mark unusable sectors as so
  337.             for (size_t s = max_s; s; s--) {
  338.             if (s == 0x10) continue;
  339.             if (!search_sector_key (tags[i], s, &(card_write_keys[s].key), &(card_write_keys[s].type))) {
  340.                 mad_set_aid (mad, s, mad_defect_aid);
  341.             } else if ((memcmp (card_write_keys[s].key, transport_key, sizeof (transport_key)) != 0) &&
  342.                    (card_write_keys[s].type != MFC_KEY_A)) {
  343.                 // Revert to transport configuration
  344.                 if (mifare_classic_format_sector (tags[i], s) < 0) {
  345.                 nfc_perror (device, "mifare_classic_format_sector");
  346.                 error = 1;
  347.                 goto error;
  348.                 }
  349.             }
  350.             }
  351.         }
  352.  
  353.         MifareClassicSectorNumber *sectors = mifare_application_alloc (mad, mad_nfcforum_aid, encoded_size);
  354.         if (!sectors) {
  355.             nfc_perror (device, "mifare_application_alloc");
  356.             error = EXIT_FAILURE;
  357.             goto error;
  358.         }
  359.  
  360.         if (mad_write (tags[i], mad, card_write_keys[0x00].key, card_write_keys[0x10].key) < 0) {
  361.             nfc_perror (device, "mad_write");
  362.             error = EXIT_FAILURE;
  363.             goto error;
  364.         }
  365.  
  366.         int s = 0;
  367.         while (sectors[s]) {
  368.             MifareClassicBlockNumber block = mifare_classic_sector_last_block (sectors[s]);
  369.             MifareClassicBlock block_data;
  370.             mifare_classic_trailer_block (&block_data, mifare_classic_nfcforum_public_key_a, 0x0, 0x0, 0x0, 0x6, 0x40, default_keyb);
  371.             if (mifare_classic_authenticate (tags[i], block, card_write_keys[sectors[s]].key, card_write_keys[sectors[s]].type) < 0) {
  372.             nfc_perror (device, "mifare_classic_authenticate");
  373.             error = EXIT_FAILURE;
  374.             goto error;
  375.             }
  376.             if (mifare_classic_write (tags[i], block, block_data) < 0) {
  377.             nfc_perror (device, "mifare_classic_write");
  378.             error = EXIT_FAILURE;
  379.             goto error;
  380.             }
  381.             s++;
  382.         }
  383.  
  384.         if ((ssize_t) encoded_size != mifare_application_write (tags[i], mad, mad_nfcforum_aid, tlv_data, encoded_size, default_keyb, MCAB_WRITE_KEYB)) {
  385.             nfc_perror (device, "mifare_application_write");
  386.             error = EXIT_FAILURE;
  387.             goto error;
  388.         }
  389.  
  390.         free (sectors);
  391.  
  392.         free (tlv_data);
  393.  
  394.         free (mad);
  395.         }
  396.  
  397. error:
  398.         free (tag_uid);
  399.     }
  400.  
  401.     freefare_free_tags (tags);
  402.     nfc_disconnect (device);
  403.     }
  404.  
  405.     free (card_write_keys);
  406.  
  407.     exit (error);
  408. }
Advertisement
Add Comment
Please, Sign In to add comment