Advertisement
Guest User

libnfc mifare desfire w/default keys

a guest
Mar 23rd, 2010
4,133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.11 KB | None | 0 0
  1. #include <stdio.h>
  2. #include "nfc/nfc.h"
  3. #include "nfc/mifaretag.h"
  4. #include <stdlib.h>
  5. #include <string.h>
  6.  
  7. #include "openssl/des.h"
  8.  
  9. #include <time.h>
  10. static mifare_param mp;
  11. nfc_device_t* pnd;
  12. nfc_target_info_t nti;
  13.  
  14. static void
  15. xor8 (uint8_t *ivect, uint8_t *data)
  16. {
  17.     for (int i = 0; i < 8; i++) {
  18.         data[i] ^= ivect[i];
  19.     }  
  20. }
  21.  
  22. void
  23. rol8(uint8_t *data)
  24. {
  25.     uint8_t first = data[0];
  26.     for (int i = 0; i < 7; i++) {
  27.         data[i] = data[i+1];
  28.     }  
  29.     data[7] = first;
  30. }
  31.  
  32. void
  33. mifare_cbc_des (uint8_t *key, uint8_t *data, uint8_t *ivect, short direction)
  34. {
  35.     /*  
  36.      * FIXME Should we change the way errors traverse this function?
  37.      */
  38.     uint8_t ovect[8];
  39.    
  40.     if (direction == 1) {
  41.         xor8 (ivect, data);
  42.     } else {
  43.         memcpy (ovect, data, 8);
  44.     }  
  45.    
  46.     DES_key_schedule ks;
  47.     DES_set_key ((DES_cblock *)key, &ks);
  48.    
  49.     uint8_t edata[8];
  50.     DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &ks, DES_DECRYPT);
  51.     //    stat = ecb_crypt (key, data, 8, DES_HW | DES_DECRYPT);
  52.     //
  53.     memcpy (data, edata, 8);
  54.    
  55.     if (direction == 1) {
  56.         memcpy (ivect, data, 8);
  57.     } else {
  58.         xor8 (ivect, data);
  59.         memcpy (ivect, ovect, 8);
  60.     }
  61. }
  62.  
  63. /*
  64. void print_hex(byte_t* pbtData, size_t szDate)
  65. {
  66.     size_t i;
  67.     for(i=0; i<szDate; i++) {
  68.         printf("%02x",pbtData[i]);
  69.     }
  70. } */
  71.  
  72. static byte_t keys[] = {
  73.     0xff,0xff,0xff,0xff,0xff,0xff,
  74.     0xd3,0xf7,0xd3,0xf7,0xd3,0xf7,
  75.     0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,
  76.     0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,
  77.     0x4d,0x3a,0x99,0xc3,0x51,0xdd,
  78.     0x1a,0x98,0x2c,0x7e,0x45,0x9a,
  79.     0xaa,0xbb,0xcc,0xdd,0xee,0xff,
  80.     0x00,0x00,0x00,0x00,0x00,0x00
  81. };
  82. static size_t num_keys = sizeof(keys) / 6;
  83. bool authenticate(int block, int keynum, bool keyB) {
  84.     memcpy(mp.mpa.abtUid,nti.nai.abtUid,4);
  85.     memcpy(mp.mpa.abtKey, &keys[keynum], 6);
  86.    
  87.     bool res = nfc_initiator_mifare_cmd(pnd, (keyB ? MC_AUTH_B : MC_AUTH_A), block, &mp);
  88.     if (res) {
  89.         printf("Authentication succcessful on block %d\n",block);
  90.     } else {
  91.         printf("Authentication failed on block %d\n",block);
  92.     }
  93.     return res;
  94. }
  95. void readblocks(int start, int end) {
  96.     int block;
  97.     for (block=start; block<(end+1); block++) {
  98.         bool res = nfc_initiator_mifare_cmd(pnd, MC_READ, block, &mp);
  99.         if (res) {
  100.             printf("Block %d data: ",block);
  101.             print_hex(mp.mpd.abtData,16);
  102.         } else {
  103.             printf("Reading block %d failed\n",block);
  104.         }
  105.     }
  106. }
  107. void writeblock(int block, byte_t *data) {
  108.     memcpy(mp.mpv.abtValue,data,16);
  109.     bool res = nfc_initiator_mifare_cmd(pnd, MC_WRITE, block, &mp);
  110.     if (res) {
  111.         printf("Wrote to block %d successfully\n", block);
  112.     } else {
  113.         printf("Could not write to block %d\n",block);
  114.     }
  115. }
  116. void do_raw_command(unsigned char *command, int cmdsize) {
  117.     unsigned char recvbuf[16];
  118.     recvbuf[0] = 0xaf;
  119.     size_t recv;
  120.     unsigned char *cmdbuf = malloc(cmdsize);
  121.     size_t sent_command_size = cmdsize;
  122.     memcpy(cmdbuf,command,cmdsize);
  123.     while(recvbuf[0] == 0xaf) {
  124.         bool sent = nfc_initiator_transceive_dep_bytes(pnd,cmdbuf, sent_command_size,recvbuf,&recv);
  125.         if(sent) {
  126.             printf("Sent message, got %d bytes\n",(int)recv);
  127.             print_hex(recvbuf,recv);
  128.             if (recvbuf[0] == 0xaf) {
  129.                 cmdbuf[0] = 0xaf;
  130.                 sent_command_size = 1;
  131.             }
  132.         } else {
  133.             printf("Sending failed\n");
  134.             recvbuf[0] = 0x00;
  135.             break;
  136.         }
  137.     }
  138.     free(cmdbuf);
  139. }
  140. size_t get_response(unsigned char *command, int cmdsize, unsigned char *recvbuf) {
  141.     size_t recv = 0;
  142.     bool sent = nfc_initiator_transceive_dep_bytes(pnd, command, cmdsize, recvbuf, &recv);
  143.     if (sent) {
  144.         printf("Command sent successfully, got %d bytes\n",recv);
  145.         print_hex(recvbuf,recv);
  146.     }
  147.     return recv;
  148. }
  149.  
  150. int main (int argc, const char * argv[]) {
  151.    
  152.    
  153.     // Display libnfc version
  154.     const char* acLibnfcVersion = nfc_version();
  155.     printf("%s use libnfc %s\n", argv[0], acLibnfcVersion);
  156.    
  157.     pnd = nfc_connect(NULL);
  158.    
  159.     if (pnd == NULL) {
  160.         printf("No NFC device connection\n");
  161.         return 1;
  162.     }
  163.    
  164.     nfc_initiator_init(pnd);
  165.    
  166.     nfc_configure(pnd,NDO_ACTIVATE_FIELD,false);
  167.     // Let the reader only try once to find a tag
  168.     nfc_configure(pnd,NDO_INFINITE_SELECT,false);
  169.    
  170.     // Configure the CRC and Parity settings
  171.     nfc_configure(pnd,NDO_HANDLE_CRC,true);
  172.     nfc_configure(pnd,NDO_HANDLE_PARITY,true);
  173.    
  174.     // Enable field so more power consuming cards can power themselves up
  175.     nfc_configure(pnd,NDO_ACTIVATE_FIELD,true);
  176.    
  177.     printf("Connected to NFC reader: %s\n",pnd->acName);
  178.    
  179.     // Poll for a ISO14443A (MIFARE) tag
  180.     if (nfc_initiator_select_tag(pnd,NM_ISO14443A_106,NULL,0,&nti)) {
  181.         printf("The following (NFC) ISO14443A tag was found:\n");
  182.         printf("    ATQA (SENS_RES): "); print_hex(nti.nai.abtAtqa,2);
  183.         printf("       UID (NFCID%c): ",(nti.nai.abtUid[0]==0x08?'3':'1')); print_hex(nti.nai.abtUid,nti.nai.szUidLen);
  184.         printf("      SAK (SEL_RES): "); print_hex(&nti.nai.btSak,1);
  185.         if (nti.nai.szAtsLen) {
  186.             printf("          ATS (ATR): ");
  187.             print_hex(nti.nai.abtAts,nti.nai.szAtsLen);
  188.         }
  189.     } else {
  190.         goto DISCONNECT;
  191.     }
  192.  
  193.     unsigned char getversion[1] = {0x60};
  194.     do_raw_command(&getversion[0], 1);
  195.    
  196.     unsigned char getfileids[1] = {0x6f};
  197.     do_raw_command(&getfileids[0], 1);
  198.    
  199.    
  200.    
  201.     // create application
  202.      unsigned char createapp[6] = {0xca,0x0,0x0,0x01,0x01,0x01};
  203.     do_raw_command(&createapp[0],6);
  204.    
  205.     unsigned char listapp[1] = {0x6a};
  206.     printf("Listing applications \n");
  207.     do_raw_command(&listapp[0],1);
  208.    
  209.    
  210.     unsigned char gotoapp[4] = {0x5a,0x00,0x00,0x01};
  211.     do_raw_command(&gotoapp[0], 4);
  212.    
  213.     uint8_t ivec[8];
  214.     memset (ivec, '\0', sizeof (ivec));
  215.    
  216.     uint8_t key[8];
  217.     memset(key,0,sizeof(key));
  218.    
  219.     printf("Key: "); print_hex (key, 8);
  220.     printf("ivec: "); print_hex(ivec, 8);
  221.  
  222.     unsigned char authenticate[2] = {0x0a,0x00};
  223.     unsigned char response[32];
  224.     get_response(&authenticate[0],2,&response[0]);
  225.    
  226.     uint8_t PICC_E_RndB[8];
  227.     memcpy (PICC_E_RndB, &response[1], 8);
  228.     printf("e(PICC_RndB)          "); print_hex(PICC_E_RndB,16);
  229.    
  230.     uint8_t PICC_RndB[8];
  231.     memcpy (PICC_RndB, PICC_E_RndB, 8);
  232.     mifare_cbc_des (key, PICC_RndB, ivec, 0);
  233.     printf("  PICC_RndB           "); print_hex(PICC_RndB,16);
  234.    
  235.     uint8_t PCD_RndA[8];
  236.     DES_random_key ((DES_cblock*)&PCD_RndA);
  237.     printf("  PCD_RndA            "); print_hex(PCD_RndA,8);
  238.    
  239.     uint8_t PCD_r_RndB[8];
  240.     memcpy (PCD_r_RndB, PICC_RndB, 8);
  241.     rol8 (PCD_r_RndB);
  242.    
  243.     uint8_t token[16];
  244.     memcpy (token, PCD_RndA, 8);
  245.     memcpy (token+8, PCD_r_RndB, 8);
  246.    
  247.     printf("  PCD_RndA+PCD_RndB'  "); print_hex(token,16);
  248.    
  249.     memset (ivec, '\0', sizeof (ivec));
  250.     mifare_cbc_des (key, token, ivec, 1);
  251.     mifare_cbc_des (key, token+8, ivec, 1);
  252.    
  253.     printf("d(PCD_RndA+PCD_RndB') "); print_hex(token,16);
  254.    
  255.     uint8_t msg[17];
  256.     msg[0] = 0xAF;
  257.     memcpy (msg + 1, token, 16);
  258.    
  259.     get_response(msg, 17, &response[0]);
  260.    
  261.     uint8_t PICC_E_RndA_s[8];
  262.     memcpy (PICC_E_RndA_s, &response[1], 8);
  263.     printf("e(PICC_RndA')         "); print_hex(PICC_E_RndA_s,8);
  264.    
  265.     uint8_t PICC_RndA_s[8];
  266.     memcpy (PICC_RndA_s, PICC_E_RndA_s, 8);
  267.     memset (ivec, '\0', sizeof (ivec));
  268.     mifare_cbc_des (key, PICC_RndA_s, ivec, 0);
  269.     printf("  PICC_RndA'          "); print_hex(PICC_RndA_s,8);
  270.    
  271.     uint8_t PCD_RndA_s[8];
  272.     memcpy (PCD_RndA_s, PCD_RndA, 8);
  273.     rol8 (PCD_RndA_s);
  274.     printf("  PCD_RndA'           "); print_hex(PCD_RndA_s,8);
  275.    
  276.  
  277.     printf("Get file IDs: ");
  278.     uint8_t cmd[1] = {0x6f};
  279.     get_response(cmd, 1, &response[0]);
  280.    
  281.     /* printf("Create a file: ");
  282.     uint8_t createFileCommand[8] = {0xcd,0x02,0x00,0x00,0x00,0x18,0x00,0x00};
  283.     do_raw_command(&createFileCommand[0], 8);  */
  284.    
  285.     /* printf("Delete a file: ");
  286.     uint8_t deleteFileCommand[2] = {0xdf,0x01};
  287.     do_raw_command(&deleteFileCommand[0], 2);  */
  288.    
  289.     printf("Read file 01:");
  290.     uint8_t readFileCommand[8] = {0xbd,0x02,0x00,0x00,0x00,0x18,0x00,0x00};
  291.     uint8_t buffer[129];
  292.     uint8_t file1Contents[24];
  293.     size_t recv = 0;
  294.     size_t offset = 0;
  295.     recv = get_response(&readFileCommand[0], 8, &buffer[0]);
  296.     memcpy(&file1Contents[offset],&buffer[1],recv-1);
  297.     offset += recv - 1;
  298.     uint8_t moreCmd[1] = {0xaf};
  299.    
  300.     while(buffer[0] == 0xaf) {
  301.         recv = get_response(&moreCmd[0], 1, &buffer[0]);
  302.         size_t startLoc = (buffer[0] == 0xaf) ? 1 : 0;
  303.         size_t toCopy = (buffer[0] == 0xaf) ? recv - 1 : recv;
  304.         memcpy(&file1Contents[offset],&buffer[startLoc],toCopy);
  305.         offset += toCopy;
  306.    
  307.     }
  308.    
  309.     printf("The data in the sector is: %s\n",file1Contents);
  310.    
  311.      uint8_t fileSettings[2] = {0xf5,0x00};
  312.     do_raw_command(&fileSettings[0],2);
  313.    
  314.     char today[64];
  315.     time_t now_t;
  316.     struct tm *now;
  317.     time (&now_t);
  318.    
  319.     now = localtime(&now_t);
  320.     strftime(&today[0],64,"%c",now);
  321.    
  322.     uint8_t writeFileCommand[32] = {0x3d,0x02,0x00,0x00,0x00,0x18,0x00,0x00};
  323.     memcpy(&writeFileCommand[8],today,24);
  324.     printf("Write file command: "); print_hex(writeFileCommand,32);
  325.     get_response(&writeFileCommand[0], 32, &response[0]);
  326.  
  327.     /* uint8_t data[5] = {0xaf,0xca,0xfe,0xba,0xbe};
  328.     get_response(&data[0], 4, &response[0]); */
  329.    
  330.     //uint8_t commitTransactionCommand[1] = {199};
  331.     //get_response(&commitTransactionCommand[0], 1, &response[0]);
  332.  
  333.    
  334.     DISCONNECT:
  335.     // Disconnect from NFC device
  336.     nfc_disconnect(pnd);
  337.     return 0;
  338. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement