예제 #1
0
static  bool
parse_card()
{
  e.logcount = 0; e.current_tran = 0; 
  int32_t iBlock;
  bool    bFailure = false;

  //printf("Reading out %d blocks\n", uiBlocks + 1);
  // Read the card from end to begin
  for (iBlock = uiBlocks; iBlock >= 0; iBlock--) {
    // Authenticate everytime we reach a trailer block
    if(is_debug) printf("  0x%02x : ", iBlock);
    if (iBlock / 4 == DO_NOT_ACCESS) { if(is_debug) printf("!\n"); continue; }
    if (is_trailer_block(iBlock)) {
      if (bFailure) {
        // When a failure occured we need to redo the anti-collision
        if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
          printf("!\nError: tag was removed\n");
          return false;
        }
        bFailure = false;
      }

      fflush(stdout);

      // Try to authenticate for the current sector
      if (!authenticate(iBlock, false)) {
        printf("!\nError: authentication failed for block 0x%02x\n", iBlock);
        return false;
      }
      // Try to read out the trailer
      if (nfc_initiator_mifare_cmd(pnd, MC_READ, iBlock, &mp)) {
    	  if(is_debug) print_hex(mp.mpd.abtData, 16);
	  parserights(&e, uiBlocks / 4, mp.mpd.abtData); 
      } else {
        printf("!\nfailed to read trailer block 0x%02x\n", iBlock);
        bFailure = true;
      }
    } else {
      // Make sure a earlier readout did not fail
      if (!bFailure) {
        // Try to read out the data block
        if (nfc_initiator_mifare_cmd(pnd, MC_READ, iBlock, &mp)) {
        	if(is_debug) print_hex(mp.mpd.abtData, 16);
		parseTag(&e, iBlock, mp.mpd.abtData); 
        } else {
          printf("!\nError: unable to read block 0x%02x\n", iBlock);
          bFailure = true;
        }
      }
    }
    if ( bFailure )
      return false;
  }
  fflush(stdout);

  return true;
}
예제 #2
0
bool authenticate(uint32_t uiBlock)
{
    mifare_cmd mc;
    uint32_t uiTrailerBlock;
    //! Set the authentication information (uid)
    memcpy(mp.mpa.abtAuthUid, nt.nti.nai.abtUid + nt.nti.nai.szUidLen - 4, 4);
    //! Should we use key A or B?
    mc = (bUseKeyA) ? MC_AUTH_A : MC_AUTH_B;
    //! Key file authentication.
    if (bUseKeyFile)
    {
        //! Locate the trailer (with the keys) used for this sector
        uiTrailerBlock = get_trailer_block(uiBlock);
        //! Extract the right key from dump file
        if (bUseKeyA)
        {
            memcpy(mp.mpa.abtKey, mtKeys.amb[uiTrailerBlock].mbt.abtKeyA, 6);
        }
        else
        {
            memcpy(mp.mpa.abtKey, mtKeys.amb[uiTrailerBlock].mbt.abtKeyB, 6);
        }
        //! Try to authenticate for the current sector
        if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp))
        {
            return true;
        }
    }
    else
    {
        //! Try to guess the right key
        size_t key_index;
        for (key_index = 0; key_index < num_keys; key_index++)
        {
            memcpy(mp.mpa.abtKey, keys + (key_index * 6), 6);
            if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp))
            {
                if (bUseKeyA)
                {
                    memcpy(mtKeys.amb[uiBlock].mbt.abtKeyA, &mp.mpa.abtKey, 6);
                }
                else
                {
                    memcpy(mtKeys.amb[uiBlock].mbt.abtKeyB, &mp.mpa.abtKey, 6);
                }
                return true;
            }
            nfc_initiator_select_passive_target(pnd, nmMifare, nt.nti.nai.abtUid, nt.nti.nai.szUidLen, NULL);
        }
    }
    return false;
}
예제 #3
0
static  bool
authenticate(uint32_t uiBlock)
{
  mifare_cmd mc;
  uint32_t uiTrailerBlock;

  // Set the authentication information (uid)
  memcpy(mp.mpa.abtAuthUid, nt.nti.nai.abtUid + nt.nti.nai.szUidLen - 4, 4);

  // Should we use key A or B?
  mc = (bUseKeyA) ? MC_AUTH_A : MC_AUTH_B;

  // Key file authentication.
  if (bUseKeyFile) {

    // Locate the trailer (with the keys) used for this sector
    uiTrailerBlock = get_trailer_block(uiBlock);

    // Extract the right key from dump file
    if (bUseKeyA)
      memcpy(mp.mpa.abtKey, mtKeys.amb[uiTrailerBlock].mbt.abtKeyA, 6);
    else
      memcpy(mp.mpa.abtKey, mtKeys.amb[uiTrailerBlock].mbt.abtKeyB, 6);

    // Try to authenticate for the current sector
    if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp))
      return true;
  }

  // If formatting or not using key file, try to guess the right key
  if (bFormatCard || !bUseKeyFile) {
    for (size_t key_index = 0; key_index < num_keys; key_index++) {
      memcpy(mp.mpa.abtKey, keys + (key_index * 6), 6);
      if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp)) {
        if (bUseKeyA)
          memcpy(mtKeys.amb[uiBlock].mbt.abtKeyA, &mp.mpa.abtKey, 6);
        else
          memcpy(mtKeys.amb[uiBlock].mbt.abtKeyB, &mp.mpa.abtKey, 6);
        return true;
      }
      if (nfc_initiator_select_passive_target(pnd, nmMifare, nt.nti.nai.abtUid, nt.nti.nai.szUidLen, NULL) <= 0) {
        ERR("tag was removed");
        return false;
      }
    }
  }

  return false;
}
예제 #4
0
static  bool
write_card (void)
{
  uint32_t uiBlock = 0;
  bool    bFailure = false;
  uint32_t uiWritenPages = 0;
  uint32_t uiSkippedPages;

  char    buffer[BUFSIZ];
  bool    write_otp;
  bool    write_lock;

  printf ("Write OTP bytes ? [yN] ");
  fgets (buffer, BUFSIZ, stdin);
  write_otp = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
  printf ("Write Lock bytes ? [yN] ");
  fgets (buffer, BUFSIZ, stdin);
  write_lock = ((buffer[0] == 'y') || (buffer[0] == 'Y'));

  printf ("Writing %d pages |", uiBlocks + 1);
  /* We need to skip 2 first pages. */
  printf ("ss");
  uiSkippedPages = 2;

  for (int page = 0x2; page <= 0xF; page++) {
    if ((page==0x2) && (!write_lock)) {
      printf ("s");
      uiSkippedPages++;
      continue;
    }
    if ((page==0x3) && (!write_otp)) {
      printf ("s");
      uiSkippedPages++;
      continue;
    }
    // Show if the readout went well
    if (bFailure) {
      // When a failure occured we need to redo the anti-collision
      if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
        ERR ("tag was removed");
        return false;
      }
      bFailure = false;
    }
    // For the Mifare Ultralight, this write command can be used
    // in compatibility mode, which only actually writes the first 
    // page (4 bytes). The Ultralight-specific Write command only
    // writes one page at a time.
    uiBlock = page / 4;
    memcpy (mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData + ((page % 4) * 4), 16);
    if (!nfc_initiator_mifare_cmd (pnd, MC_WRITE, page, &mp))
      bFailure = true;

    print_success_or_failure (bFailure, &uiWritenPages);
  }
  printf ("|\n");
  printf ("Done, %d of %d pages written (%d pages skipped).\n", uiWritenPages, uiBlocks + 1, uiSkippedPages);

  return true;
}
예제 #5
0
static  bool
read_card (void)
{
  uint32_t page;
  bool    bFailure = false;
  uint32_t uiReadedPages = 0;

  printf ("Reading %d pages |", uiBlocks + 1);

  for (page = 0; page <= uiBlocks; page += 4) {
    // Try to read out the data block
    if (nfc_initiator_mifare_cmd (pnd, MC_READ, page, &mp)) {
      memcpy (mtDump.amb[page / 4].mbd.abtData, mp.mpd.abtData, 16);
    } else {
      bFailure = true;
      break;
    }

    print_success_or_failure (bFailure, &uiReadedPages);
    print_success_or_failure (bFailure, &uiReadedPages);
    print_success_or_failure (bFailure, &uiReadedPages);
    print_success_or_failure (bFailure, &uiReadedPages);
  }
  printf ("|\n");
  printf ("Done, %d of %d pages readed.\n", uiReadedPages, uiBlocks + 1);
  fflush (stdout);

  return (!bFailure);
}
예제 #6
0
static bool check_magic()
{
  bool     bFailure = false;
  int      uid_data;

  for (uint32_t page = 0; page <= 1; page++) {
    // Show if the readout went well
    if (bFailure) {
      // When a failure occured we need to redo the anti-collision
      if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
        ERR("tag was removed");
        return false;
      }
      bFailure = false;
    }

    uid_data = 0x00000000;

    memcpy(mp.mpd.abtData, &uid_data, sizeof uid_data);
    memset(mp.mpd.abtData + 4, 0, 12);

    //Force the write without checking for errors - otherwise the writes to the sector 0 seem to complain
    nfc_initiator_mifare_cmd(pnd, MC_WRITE, page, &mp);
  }

  //Check that the ID is now set to 0x000000000000
  if (nfc_initiator_mifare_cmd(pnd, MC_READ, 0, &mp)) {
    //printf("%u", mp.mpd.abtData);
    bool result = true;
    for (int i = 0; i <= 7; i++) {
      if (mp.mpd.abtData[i] != 0x00) result = false;
    }

    if (result) {
      return true;
    }

  }

  //Initially check if we can unlock via the MF method
  if (unlock_card()) {
    return true;
  } else {
    return false;
  }

}
예제 #7
0
static bool
write_block(uint32_t uiBlock, uint8_t* data, bool isTypeA)
{ 
  if(is_trailer_block(uiBlock)) return false; 
  mifare_param mpw; 
  mifare_cmd mc = MC_WRITE; 
  memcpy(mpw.mpd.abtData, data, 16); 

  if(!authenticate(uiBlock, isTypeA)) return false; 
  if(!nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mpw)) return false; 

  return true; 
}
예제 #8
0
bool write_card(ReaderTag rt,mifareul_tag * tag){
    
  uint32_t uiBlock = 0;
  bool    bFailure = false;
  uint32_t uiWritenPages = 0;
  uint32_t uiSkippedPages;

  char    buffer[BUFSIZ];
  bool    write_otp=0;
  bool    write_lock=0;

 
 
  uiSkippedPages = 2;

  for (int page = 0x2; page <= 30; page++) {
    if ((page == 0x2) && (!write_lock)) {
      printf("s");
      uiSkippedPages++;
      continue;
    }
    if ((page == 0x3) && (!write_otp)) {
      printf("s");
      uiSkippedPages++;
      continue;
    }
    // Show if the readout went well
    if (bFailure) {
      // When a failure occured we need to redo the anti-collision
      if (nfc_initiator_select_passive_target(rt.device, nmMifare, NULL, 0, &rt.nt) <= 0) {
        ERR("tag was removed");
        return false;
      }
      bFailure = false;
    }
    // For the Mifare Ultralight, this write command can be used
    // in compatibility mode, which only actually writes the first
    // page (4 bytes). The Ultralight-specific Write command only
    // writes one page at a time.
    uiBlock = page / 4;
    memcpy(mp.mpd.abtData, tag->amb[uiBlock].mbd.abtData + ((page % 4) * 4), 16);
    if (!nfc_initiator_mifare_cmd(rt.device, MC_WRITE, page, &mp))
      bFailure = true;

    print_success_or_failure(bFailure, &uiWritenPages);
  }
  printf("|\n");
  printf("Done, %d of 16 pages written (%d pages skipped).\n", uiWritenPages, uiSkippedPages);

  return true;
}
예제 #9
0
static  bool
authenticate(uint32_t uiBlock, bool isTypeA)
{
  mifare_cmd mc;

  // Set the authentication information (uid)
  memcpy(mp.mpa.abtAuthUid, nt.nti.nai.abtUid + nt.nti.nai.szUidLen - 4, 4);

  // Should we use key A or B?
  mc = (isTypeA)?MC_AUTH_A:MC_AUTH_B;

  int uiSecs = (uiBlocks + 1) / 4; 

  if(isTypeA) memcpy(mp.mpa.abtKey, keysA[uiSecs - uiBlock / 4 - 1], 6);
  else memcpy(mp.mpa.abtKey, keysB[uiSecs - uiBlock / 4 - 1], 6);
  if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp)) return true;
  nfc_initiator_select_passive_target(pnd, nmMifare, nt.nti.nai.abtUid, nt.nti.nai.szUidLen, NULL);

  return false;
}
예제 #10
0
static  bool
read_card(void)
{
  uint32_t page;
  bool    bFailure = false;
  uint32_t uiFailedPages = 0;

  printf("Reading %d pages |", uiBlocks);

  for (page = 0; page < uiBlocks; page += 4) {
    // Try to read out the data block
    if (nfc_initiator_mifare_cmd(pnd, MC_READ, page, &mp)) {
      memcpy(mtDump.amb[page / 4].mbd.abtData, mp.mpd.abtData, uiBlocks - page < 4 ? (uiBlocks - page) * 4 : 16);
    } else {
      bFailure = true;
    }
    for (uint8_t i = 0; i < (uiBlocks - page < 4 ? uiBlocks - page : 4); i++) {
      print_success_or_failure(bFailure, &uiReadPages, &uiFailedPages);
    }
  }
  printf("|\n");
  printf("Done, %d of %d pages read (%d pages failed).\n", uiReadPages, uiBlocks, uiFailedPages);
  fflush(stdout);

  // copy EV1 secrets to dump data
  switch (iEV1Type) {
    case EV1_UL11:
      memcpy(mtDump.amb[4].mbc11.pwd, iPWD, 4);
      memcpy(mtDump.amb[4].mbc11.pack, iPACK, 2);
      break;
    case EV1_UL21:
      memcpy(mtDump.amb[9].mbc21a.pwd, iPWD, 4);
      memcpy(mtDump.amb[9].mbc21b.pack, iPACK, 2);
      break;
    case EV1_NONE:
    default:
      break;
  }

  return (!bFailure);
}
예제 #11
0
bool mf_authenticate(size_t block, const uint8_t* key, mf_key_type_t key_type) {

  mifare_param mp;

  // Set the authentication information (uid)
  memcpy(mp.mpa.abtAuthUid, target.nti.nai.abtUid + target.nti.nai.szUidLen - 4, 4);

  // Select key for authentication
  mifare_cmd mc = (key_type == MF_KEY_A) ? MC_AUTH_A : MC_AUTH_B;

  // Set the key
  memcpy(mp.mpa.abtKey, key, 6);

  // Try to authenticate for the current sector
  if (nfc_initiator_mifare_cmd(device, mc, (uint8_t)block, &mp))
    return true;

  // Do the hand shaking again if auth failed
  nfc_initiator_select_passive_target(device, mf_nfc_modulation,
                                      NULL, 0, &target);

  return false;
}
예제 #12
0
bool read_card_ultralight(void)
{
    uint32_t page;
    bool    bFailure = false;
    uint32_t uiReadedPages = 0;
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"Reading %d pages |", uiBlocks_ultralight + 1);
    #endif
    for (page = 0; page <= uiBlocks_ultralight; page += 4)
    {
        //! Try to read out the data block
        if (nfc_initiator_mifare_cmd(pnd, MC_READ, page, &mp))
        {
            memcpy(mtDump.amb[page / 4].mbd.abtData, mp.mpd.abtData, 16);
        }
        else
        {
            bFailure = true;
            break;
        }
        print_success_or_failure(bFailure, &uiReadedPages);
        print_success_or_failure(bFailure, &uiReadedPages);
        print_success_or_failure(bFailure, &uiReadedPages);
        print_success_or_failure(bFailure, &uiReadedPages);
    }
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"|\n");
    fprintf(stderr,"Done : %d of %d pages readed.\n", uiReadedPages, uiBlocks_ultralight + 1);
    #endif
    fflush(stdout);
    if (bFailure)
    {
        sprintf(message_erreur,"Impossible d'accéder aux données de la carte !");
    }
    return (!bFailure);
}
예제 #13
0
bool write_card_ultralight(int argc, const char *argv[])
{
    uint32_t uiBlock = 0;
    bool    bFailure = false;
    uint32_t uiWritenPages = 0;
    uint32_t uiSkippedPages = 0;
    
    bool    write_otp;
    bool    write_lock;
    bool    write_uid;
    
    if (argc>3) // Mode EXPERT !
    {
        write_otp = ((argv[3][0] == 'y') || (argv[3][0] == 'Y'));
        write_lock = ((argv[4][0] == 'y') || (argv[4][0] == 'Y'));
        write_uid = ((argv[5][0] == 'y') || (argv[5][0] == 'Y'));
    }
    else
    {
        write_otp = true;
        write_lock = true;
        write_uid = false;
    }
    
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"Writing %d pages |", uiBlocks_ultralight + 1);
    #endif
    /* We may need to skip 2 first pages. */
    if (!write_uid)
    {
        fprintf(stderr,"ss");
        uiSkippedPages = 2;
    }
    int page;
    for (page = uiSkippedPages; page <= 0xF; page++)
    {
        if ((page == 0x2) && (!write_lock))
        {
            #ifdef DEBUG_PRINTF
            fprintf(stderr,"s");
            #endif
            uiSkippedPages++;
            continue;
        }
        if ((page == 0x3) && (!write_otp))
        {
            #ifdef DEBUG_PRINTF
            fprintf(stderr,"s");
            #endif
            uiSkippedPages++;
            continue;
        }
        //! Show if the readout went well
        if (bFailure)
        {
            //! When a failure occured we need to redo the anti-collision
            if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0)
            {
                sprintf(message_erreur,"Tag was removed !");
                return false;
            }
            bFailure = false;
        }
        //! For the Mifare Ultralight, this write command can be used
        //! in compatibility mode, which only actually writes the first
        //! page (4 bytes). The Ultralight-specific Write command only
        //! writes one page at a time.
        uiBlock = page / 4;
        memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData + ((page % 4) * 4), 16);
        if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, page, &mp))
            bFailure = true;
        print_success_or_failure(bFailure, &uiWritenPages);
    }
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"|\n");
    fprintf(stderr,"Done, %d of %d pages written (%d pages skipped).\n", uiWritenPages, uiBlocks_ultralight + 1, uiSkippedPages);
    #endif
    return true;
}
예제 #14
0
bool write_card(int write_block_zero)
{
    uint32_t uiBlock;
    bool    bFailure = false;
    uint32_t uiWriteBlocks = 0;
    if (write_block_zero)
    {
        if (!unlock_card())
        {
            return false;
        }
    }
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"Writing %d blocks |", uiBlocks + 1);
    #endif
    //! Write the card from begin to end;
    for (uiBlock = 0; uiBlock <= uiBlocks; uiBlock++)
    {
        //! Authenticate everytime we reach the first sector of a new block
        if (is_first_block(uiBlock))
        {
            if (bFailure)
            {
                //! When a failure occured we need to redo the anti-collision
                if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0)
                {
                    #ifdef DEBUG_PRINTF
                    fprintf(stderr,"!\nError: tag was removed\n");
                    #endif
                    sprintf(message_erreur,"Error: tag was removed !");
                    return false;
                }
                bFailure = false;
            }
            fflush(stdout);
            //! Try to authenticate for the current sector
            if (!write_block_zero && !authenticate(uiBlock))
            {
                #ifdef DEBUG_PRINTF
                fprintf(stderr,"!\nError: authentication failed for block %02x\n", uiBlock);
                #endif
                sprintf(message_erreur,"Error: authentication failed for block %02x !", uiBlock);
                return false;
            }
        }
        if (is_trailer_block(uiBlock))
        {
            //! Copy the keys over from our key dump and store the retrieved access bits
            memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbt.abtKeyA, 6);
            memcpy(mp.mpd.abtData + 6, mtDump.amb[uiBlock].mbt.abtAccessBits, 4);
            memcpy(mp.mpd.abtData + 10, mtDump.amb[uiBlock].mbt.abtKeyB, 6);
            //! Try to write the trailer
            if (nfc_initiator_mifare_cmd(pnd, MC_WRITE, uiBlock, &mp) == false)
            {
                #ifdef DEBUG_PRINTF
                fprintf(stderr,"failed to write trailer block %d \n", uiBlock);
                #endif
                bFailure = true;
            }
        }
        else
        {
            //! The first block 0x00 is read only, skip this
            if (uiBlock == 0 && ! write_block_zero && ! magic2)
                continue;
    
            //! Make sure a earlier write did not fail
            if (!bFailure)
            {
                //! Try to write the data block
                memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, 16);
                //! do not write a block 0 with incorrect BCC - card will be made invalid!
                if (uiBlock == 0)
                {
                    if ((mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3] ^ mp.mpd.abtData[4]) != 0x00 && !magic2)
                    {
                        #ifdef DEBUG_PRINTF
                        fprintf(stderr,"!\nError: incorrect BCC in MFD file!\n");
                        fprintf(stderr,"Expecting BCC=%02X\n", mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3]);
                        #endif
                        sprintf(message_erreur,"Error: incorrect BCC in MFD file! ");
                        return false;
                    }
                }
                if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, uiBlock, &mp))
                {
                    bFailure = true;
                }
            }
        }
        //! Show if the write went well for each block
        print_success_or_failure(bFailure, &uiWriteBlocks);
        if ((! bTolerateFailures) && bFailure)
        {
            return false;
        }
    }
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"|\n");
    fprintf(stderr,"Done, %d of %d blocks written.\n", uiWriteBlocks, uiBlocks + 1);
    #endif
    fflush(stdout);
    return true;
}
예제 #15
0
bool read_card(int read_unlocked)
{
    int32_t iBlock;
    bool    bFailure = false;
    uint32_t uiReadBlocks = 0;
    if (read_unlocked)
    {
        if (!unlock_card())
        {
            return false;
        }
    }
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"Reading out %d blocks |\n", uiBlocks + 1);
    #endif
    //! Read the card from end to begin
    for (iBlock = uiBlocks; iBlock >= 0; iBlock--)
    {
        //! Authenticate everytime we reach a trailer block
        if (is_trailer_block(iBlock))
        {
            if (bFailure)
            {
                //! When a failure occured we need to redo the anti-collision
                if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0)
                {
                    #ifdef DEBUG_PRINTF
                    fprintf(stderr,"!\nError: tag was removed\n");
                    #endif
                    sprintf(message_erreur,"Error: tag was removed !");
                    return false;
                }
                bFailure = false;
            }
            fflush(stdout);
            //! Try to authenticate for the current sector
            if (!read_unlocked && !authenticate(iBlock))
            {
                #ifdef DEBUG_PRINTF
                fprintf(stderr,"!\nError: authentication failed for block 0x%02x\n", iBlock);
                #endif
                sprintf(message_erreur,"Error: authentication failed for block 0x%02x !", iBlock);
                return false;
            }
            //! Try to read out the trailer
            if (nfc_initiator_mifare_cmd(pnd, MC_READ, iBlock, &mp))
            {
                if (read_unlocked)
                {
                    memcpy(mtDump.amb[iBlock].mbd.abtData, mp.mpd.abtData, 16);
                }
                else
                {
                    //! Copy the keys over from our key dump and store the retrieved access bits
                    memcpy(mtDump.amb[iBlock].mbt.abtKeyA, mtKeys.amb[iBlock].mbt.abtKeyA, 6);
                    memcpy(mtDump.amb[iBlock].mbt.abtAccessBits, mp.mpd.abtData + 6, 4);
                    memcpy(mtDump.amb[iBlock].mbt.abtKeyB, mtKeys.amb[iBlock].mbt.abtKeyB, 6);
                }
            }
            else
            {
                #ifdef DEBUG_PRINTF
                fprintf(stderr,"!\nfailed to read trailer block 0x%02x\n", iBlock);
                #endif
                bFailure = true;
            }
        }
        else
        {
            //! Make sure a earlier readout did not fail
            if (!bFailure)
            {
                //! Try to read out the data block
                if (nfc_initiator_mifare_cmd(pnd, MC_READ, iBlock, &mp))
                {
                    memcpy(mtDump.amb[iBlock].mbd.abtData, mp.mpd.abtData, 16);
                }
                else
                {
                    #ifdef DEBUG_PRINTF
                    fprintf(stderr,"!\nError: unable to read block 0x%02x\n", iBlock);
                    #endif
                    bFailure = true;
                }
            }
        }
        //! Show if the readout went well for each block
        print_success_or_failure(bFailure, &uiReadBlocks);
        if ((! bTolerateFailures) && bFailure)
        {
            return false;
        }
    }
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"|\n");
    fprintf(stderr,"Done : %d of %d blocks read.\n", uiReadBlocks, uiBlocks + 1);
    #endif
    fflush(stdout);
    return true;
}
예제 #16
0
bool mf_read_tag_internal(mf_tag_t* tag,
                      const mf_tag_t* keys, mf_key_type_t key_type) {
  mifare_param mp;

  static mf_tag_t buffer_tag;
  clear_tag(&buffer_tag);

  int error = 0;

  printf("Reading: ["); fflush(stdout);

  // Read the card from end to begin
  for (int block_it = (int)block_count(size) - 1; block_it >= 0; --block_it) {
    size_t block = (size_t)block_it;
    // Authenticate everytime we reach a trailer block
    if (is_trailer_block(block)) {

      // Try to authenticate for the current sector
      uint8_t* key = key_from_tag(keys, key_type, block);
      if (!mf_authenticate(block, key, key_type)) {
        // Progress indication and error report
        printf("0x%02zx", block_to_sector(block));
        if (block != 3) printf(".");
        fflush(stdout);

        block_it -= (int)sector_size(block) - 1; // Skip the rest of the sector blocks
        error = 1;
      }
      else {
        // Try to read the trailer (only to *read* the access bits)
        if (nfc_initiator_mifare_cmd(device, MC_READ, (uint8_t)block, &mp)) {
          // Copy the keys over to our tag buffer
          key_to_tag(&buffer_tag, keys->amb[block].mbt.abtKeyA, MF_KEY_A, block);
          key_to_tag(&buffer_tag, keys->amb[block].mbt.abtKeyB, MF_KEY_B, block);

          // Store the retrieved access bits in the tag buffer
          memcpy(buffer_tag.amb[block].mbt.abtAccessBits,
                 mp.mpd.abtData + 6, 4);
        } else {
          printf ("\nUnable to read trailer block: 0x%02zx.\n", block);
          return false;
        }
        printf("."); fflush(stdout); // Progress indicator
      }
    }

    else { // I.e. not a sector trailer
      // Try to read out the block
      if (!nfc_initiator_mifare_cmd(device, MC_READ, (uint8_t)block, &mp)) {
        printf("\nUnable to read block: 0x%02zx.\n", block);
        return false;
      }
      memcpy(buffer_tag.amb[block].mbd.abtData, mp.mpd.abtData, 0x10);
    }
  }

  // Terminate progress indicator
  if (error)
    printf("] Auth errors in indicated sectors.\n");
  else
    printf("] Success!\n");

  // Success! Copy the data
  // todo: Or return static ptr?
  memcpy(tag, &buffer_tag, MF_4K);

  return true;
}
예제 #17
0
bool mf_write_tag_internal(const mf_tag_t* tag,
                           const mf_tag_t* keys,
                           mf_key_type_t key_type) {

  mifare_param mp;
  int error = 0;

  printf("Writing %s tag [", sprint_size(size)); fflush(stdout);

  // Process each sector in turn
  for (int header_block_it = sector_header_iterator(0);
       header_block_it != -1;
       header_block_it = sector_header_iterator(size)) {
    size_t header_block = (size_t)header_block_it;

    // Authenticate
    uint8_t* key = key_from_tag(keys, key_type, header_block);
    if (key_type != MF_KEY_UNLOCKED) {
      if (!mf_authenticate(header_block, key, key_type)) {
        // Progress indication and error report
        if (header_block != 0) printf(".");
        printf("0x%02zx", block_to_sector(header_block));
        fflush(stdout);

        error = 1;
        continue; // Skip the rest of the sector blocks
      }
    }

    // Write the sectors blocks
    for (size_t block = header_block, trailer = block_to_trailer(header_block);
         block < trailer; ++block) {

      // First block on tag is read only - skip it unless unlocked
      if (block == 0 && key_type != MF_KEY_UNLOCKED)
        continue;

      // Try to write the data block
      memcpy (mp.mpd.abtData, tag->amb[block].mbd.abtData, 0x10);

      // do not write a block 0 with incorrect BCC - card will be made invalid!
      if (block == 0) {
        if((mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^
            mp.mpd.abtData[3] ^ mp.mpd.abtData[4]) != 0x00) {
          printf ("\nError: incorrect BCC in MFD file!\n"); // ADD DATA
          return false;
        }
      }

      // Write the data block
      if (!nfc_initiator_mifare_cmd(device, MC_WRITE, (uint8_t)block, &mp)) {
        printf("\nUnable to write block: 0x%02zx.\n", block);
        return false;
      }
    }

    // Auth ok and sector read ok, finish up by reading trailer
    size_t trailer_block = block_to_trailer(header_block);
    memcpy (mp.mpd.abtData, tag->amb[trailer_block].mbt.abtKeyA, 6);
    memcpy (mp.mpd.abtData + 6, tag->amb[trailer_block].mbt.abtAccessBits, 4);
    memcpy (mp.mpd.abtData + 10, tag->amb[trailer_block].mbt.abtKeyB, 6);

    // Try to write the trailer
    if (!nfc_initiator_mifare_cmd(device, MC_WRITE, (uint8_t)trailer_block, &mp)) {
      printf("\nUnable to write block: 0x%02zx.\n", trailer_block);
      return false;
    }

    printf("."); fflush(stdout); // Progress indicator
  }

  // Terminate progress indicator
  if (error)
    printf("] Auth errors in indicated sectors.\n");
  else
    printf("] Success!\n");

  return true;
}
예제 #18
0
static  bool
write_card(bool write_otp, bool write_lock, bool write_uid)
{
  uint32_t uiBlock = 0;
  bool    bFailure = false;
  uint32_t uiWritenPages = 0;
  uint32_t uiSkippedPages = 0;

  char    buffer[BUFSIZ];

  if (!write_otp) {
    printf("Write OTP bytes ? [yN] ");
    if (!fgets(buffer, BUFSIZ, stdin)) {
      ERR("Unable to read standard input.");
    }
    write_otp = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
  }

  if (!write_lock) {
    printf("Write Lock bytes ? [yN] ");
    if (!fgets(buffer, BUFSIZ, stdin)) {
      ERR("Unable to read standard input.");
    }
    write_lock = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
  }

  if (!write_uid) {
    printf("Write UID bytes (only for special writeable UID cards) ? [yN] ");
    if (!fgets(buffer, BUFSIZ, stdin)) {
      ERR("Unable to read standard input.");
    }
    write_uid = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
  }

  printf("Writing %d pages |", uiBlocks + 1);
  /* We may need to skip 2 first pages. */
  if (!write_uid) {
    printf("ss");
    uiSkippedPages = 2;
  } else {
    if (!check_magic()) {
      printf("\nUnable to unlock card - are you sure the card is magic?\n");
      bFailure = false;
      return false;
    }
  }

  for (uint32_t page = uiSkippedPages; page <= ((uiBlocks / 4) * 4); page++) {
    if ((page == 0x2) && (!write_lock)) {
      printf("s");
      uiSkippedPages++;
      continue;
    }
    if ((page == 0x3) && (!write_otp)) {
      printf("s");
      uiSkippedPages++;
      continue;
    }
    // Show if the readout went well
    if (bFailure) {
      // When a failure occured we need to redo the anti-collision
      if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
        ERR("tag was removed");
        return false;
      }
      bFailure = false;
    }
    // For the Mifare Ultralight, this write command can be used
    // in compatibility mode, which only actually writes the first
    // page (4 bytes). The Ultralight-specific Write command only
    // writes one page at a time.
    uiBlock = page / 4;
    memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData + ((page % 4) * 4), 4);
    memset(mp.mpd.abtData + 4, 0, 12);
    if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, page, &mp))
      bFailure = true;

    print_success_or_failure(bFailure, &uiWritenPages);
  }
  printf("|\n");
  printf("Done, %d of %d pages written (%d pages skipped).\n", uiWritenPages, uiBlocks + 1, uiSkippedPages);

  return true;
}