void
test_mifare_classic_sector_boundaries (void)
{
    for (int i=0; i < 32; i++) {
	for (int j=0; j < 4; j++) {
	    cut_assert_equal_int (4 * i, mifare_classic_sector_first_block (mifare_classic_block_sector (4 * i)), cut_message ("Wrong first block number for block %d", i));
	    cut_assert_equal_int (4 * i + 3, mifare_classic_sector_last_block (mifare_classic_block_sector (4 * i + j)), cut_message ("Wrong last block number for block %d", i));
	}
    }

    for (int i=0; i < 8; i++) {
	for (int j=0; j < 16; j++) {
	    cut_assert_equal_int (128 + 16 * i, mifare_classic_sector_first_block (mifare_classic_block_sector (128 + 16 * i)), cut_message ("Wrong last block number for block %d", i));
	    cut_assert_equal_int (128 + 16 * i + 15, mifare_classic_sector_last_block (mifare_classic_block_sector (128 + 16 * i + j)), cut_message ("Wrong last block number for block %d", i));
	}
    }
}
ssize_t
mifare_application_write (MifareTag tag, Mad mad, const MadAid aid, const void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type)
{
    ssize_t res = 0;

    MifareClassicSectorNumber *sectors = mifare_application_find (mad, aid);
    MifareClassicSectorNumber *s = sectors;

    if (!sectors)
	return errno = EBADF, -1;

    while (*s && nbytes && (res >= 0)) {
	MifareClassicBlockNumber first_block = mifare_classic_sector_first_block (*s);
	MifareClassicBlockNumber last_block  = mifare_classic_sector_last_block (*s);

	MifareClassicBlockNumber b = first_block;
	MifareClassicBlock block;

	if (mifare_classic_authenticate (tag, first_block, key, key_type) < 0) {
	    res = -1;
	    break;
	}

	while ((b < last_block) && nbytes) {
	    size_t n = MIN (nbytes, 16);
	    // Avoid overwriting existing data with uninitialized memory.
	    if (n < 16) {
		if (mifare_classic_read (tag, b, &block) < 0) {
		    res = -1;
		    break;
		}
	    }

	    memcpy (&block, (uint8_t *)buf + res, n);
	    if (mifare_classic_write (tag, b, block) < 0) {
		res = -1;
		break;
	    }

	    nbytes -= n;
	    res += n;

	    b++;
	}

	s++;
    }

    free (sectors);
    return res;

}
Example #3
0
int main(int argc, const char *argv[])
{
  nfc_device *pnd;
  //nfc_target nt;
  MifareTag *tags = NULL;
  int i,j,k;
  int nbrsect=0;

  MifareClassicBlock data;

  // Allocate only a pointer to nfc_context
  nfc_context *context;

  // Initialize libnfc and set the nfc_context
  nfc_init(&context);
  if (context == NULL) {
    printf("Unable to init libnfc\n");
    exit(EXIT_FAILURE);
  }

  // Open, using the first available NFC device which can be in order of selection:
  //   - default device specified using environment variable or
  //   - first specified device in libnfc.conf (/etc/nfc) or
  //   - first specified device in device-configuration directory (/etc/nfc/devices.d) or
  //   - first auto-detected (if feature is not disabled in libnfc.conf) device
  pnd = nfc_open(context, NULL);

  if (pnd == NULL) {
    printf("ERROR: %s\n", "Unable to open NFC device.");
    exit(EXIT_FAILURE);
  }

  printf("NFC reader: %s opened\n", nfc_device_get_name(pnd));

  tags = freefare_get_tags(pnd);

  if (!tags) {
    printf("no Mifare classic\n");
  } else {
    for (i = 0; tags[i]; i++) {
      switch(freefare_get_tag_type(tags[i])) {
	case CLASSIC_1K:
	  printf("%u : Mifare 1k (S50) : %s\n", i, freefare_get_tag_uid(tags[i]));
	  nbrsect=16;
	  break;
	case CLASSIC_4K:
	  printf("%u : Mifare 4k (S70) : %s\n", i, freefare_get_tag_uid(tags[i]));
	  nbrsect=40;
	  break;
	default:
	  printf("%u : other ISO14443A tag : %s\n", i, freefare_get_tag_uid(tags[i]));
      }
    }
  }

  if (!tags[0]) {
    printf("no tag found !\n");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }

  printf ("Found %s\n", freefare_get_tag_friendly_name (tags[0]));

  /*
     MifareClassicBlockNumber dablock = 1;
     if(mifare_classic_connect(tags[0]) == OPERATION_OK) {
     printf("Connected !\n");
     if(mifare_classic_authenticate(tags[0], dablock, keys[0], MFC_KEY_A) == OPERATION_OK) {
     printf("Authenticated !\n");
     if(mifare_classic_get_data_block_permission (tags[0], dablock, MCAB_R|MCAB_W, MFC_KEY_A))
     printf("i can READ block %d with key A\n", dablock);
     if(mifare_classic_get_trailer_block_permission (tags[0], ((dablock)/4)*4+3, MCAB_READ_KEYB, MFC_KEY_B))
     printf("i can READ KEY A in trailer\n");
     }
     }
   */

  for(i=0; i<nbrsect; i++) {
    for(j=0; j < sizeof(keys)/sizeof(keys[0]); j++) {
      if((mifare_classic_connect(tags[0]) == OPERATION_OK) && 
	  (mifare_classic_authenticate(
				       tags[0], 
				       mifare_classic_sector_last_block(i), 
				       keys[j], 
				       MFC_KEY_A) == OPERATION_OK)) {
	printf("sector %02d auth with A[%d]\n", i, j);
	for(k=mifare_classic_sector_first_block(i); 
	    k<=mifare_classic_sector_last_block(i); k++) {
	  if(mifare_classic_read(tags[0], k, &data) == OPERATION_OK) {
	    print_hex(data,16);
	  } else {
	    printf("read error\n");
	  }
	}
	mifare_classic_disconnect(tags[0]);
	break;
      }
      mifare_classic_disconnect(tags[0]);
    }
    printf("\n");
  }
  printf("\n");

  freefare_free_tags(tags);

  // Close NFC device
  nfc_close(pnd);
  // Release the context
  nfc_exit(context);
  exit(EXIT_SUCCESS);
}
int main(int argc, char **argv) {
	int res;
	nfc_connstring devices[8];
	size_t device_count;
	nfc_context *nfcctx;
	char *uid = NULL;
	init_crypto_state();
	nfc_init(&nfcctx);
	
	device_count = nfc_list_devices(nfcctx,devices,8);

	if (device_count <= 0) {
		std::cerr << "No device found" << std::endl;
	}

	device = nfc_open(nfcctx, devices[0]);
    	tags = freefare_get_tags(device);

	if (tags[0] == NULL) {
        	std::cerr << "No tag on device" << std::endl;
    		exit(1);
	}

	for (int i = 0; tags[i]; i++) {
        	if (freefare_get_tag_type(tags[i]) == CLASSIC_1K) {
        	    tag = tags[i];
        	    res = mifare_classic_connect(tag);
        	    if (res != 0) {
        	        std::cout << "Error connecting to MiFare Classic" << std::endl;
			exit(1);
			}
			std::cout << "Connected to MiFare Classic" << std::endl;
		 	uid = freefare_get_tag_uid(tag);
			 break;
        	}
    	}
	std::cout << "UID: " << uid << std::endl;
	MifareClassicKey *keyA = (MifareClassicKey *)get_random_bytes(6);
	std::cout << "Key A: ";
	print_hex(*keyA,6);
	char *b64KeyA = getBase64String((char *)keyA,6);
	std::cout << b64KeyA << std::endl;
	std::cout << "Key B: ";
	MifareClassicKey *keyB = (MifareClassicKey *)get_random_bytes(6);
	print_hex(*keyB,6);	
	char *b64KeyB = getBase64String((char *)keyB,6);	
	bool addedToServer = addCard(uid,b64KeyA,b64KeyB);	
	if (!addedToServer) {
		printf("Not added to server\n");
	}

	// Authenticate with default key to make changes
	
	MifareClassicBlockNumber lastTrailer = mifare_classic_sector_last_block(15);
	res = mifare_classic_authenticate(tag,lastTrailer,defaultKey,MFC_KEY_A);
	if (res != 0) {
		printf("Could not authenticate with default key.. card already formatted?\n");
		return -1;
	}	
	
	MifareClassicBlockNumber firstBlock = mifare_classic_sector_first_block(15);
	res = mifare_classic_init_value(tag,firstBlock,SECTOR_15_BLOCK_0_INIT,firstBlock);
	if (res != 0) {
		printf("Could not init value block %d\n",firstBlock);
	}
	MifareClassicBlock trailerBlock;
	
	mifare_classic_trailer_block(&trailerBlock,*keyA,0x03,0x00,0x00,0x04,0x00, *keyB);
	print_hex(trailerBlock, sizeof(MifareClassicBlock));
	res = mifare_classic_write(tag,lastTrailer,trailerBlock);	
	if (res != 0) {
		printf("Could not write sector 15 trailer. STOP\n");
		return -1;
	} 
	

	MifareClassicBlock normalTrailerBlock;
	mifare_classic_trailer_block(&normalTrailerBlock,*keyA,0x00,0x00,0x00,0x04,0x00,*keyB);
	printf("Writing normal trailer block ");
	print_hex(&normalTrailerBlock[0], sizeof(MifareClassicBlock));
	MifareClassicSectorNumber sector;
	for(sector=0; sector<15;sector++) {
		MifareClassicBlockNumber trailerBlockNumber = mifare_classic_sector_last_block(sector);
		res = mifare_classic_authenticate(tag,trailerBlockNumber,defaultKey,MFC_KEY_A);
		if (res != 0) {
			printf("Could not authenticate with default key.. card already formatted?\n");
			return -1;
		}	

		res = mifare_classic_write(tag,trailerBlockNumber,normalTrailerBlock);
		if (res != 0) {
			printf("Could not write trailer block for sector %d\n",sector);
			return -1;
		} else {
			printf("Wrote trailer block for sector %d\n",sector);
		}
	}	
		
	free(keyA);
	free(keyB);
	free(b64KeyA);
	free(b64KeyB);
	free(uid);

	
	freefare_free_tags(tags);
	nfc_close(device);
}