int id_init(int handle, const id_desc_t *desc, mifare_tag_t *tag, const void *id, int32_t counter) { int i, block = desc->sector * 4; /* Generate per card key */ uint8_t aes_key[32]; memcpy(aes_key, desc->aes_key, 32); for (i = 0; i < 32; i++) aes_key[i] ^= tag->serial[i & 3]; /* Prepare buffer */ uint8_t buf[16]; memcpy(buf, desc->magic, 4); memcpy(&buf[4], id, 12); /* Encrypt buffer */ aes256_context aes; aes256_init(&aes, aes_key); aes256_encrypt_ecb(&aes, buf); aes256_done(&aes); if (mifare_select(handle, tag)) return ID_ERROR_SELECT; if (mifare_login(handle, desc->sector, desc->key_type, desc->key)) return ID_ERROR_LOGIN; if (mifare_write_block(handle, block + 1, buf)) return ID_ERROR_WRITE_BLOCK; if (mifare_write_value(handle, block + 2, 0)) return ID_ERROR_WRITE_VALUE; return ID_OK; }
static int mifare_write_sector_cb(uint8_t *resp, int length, void *data) { struct mifare_cookie *mf_ck = data; int err; /* Next block */ mf_ck->rws_completed = mf_ck->rws_completed + 1; /* Check if it's the last block */ if ((mf_ck->rws_block_start + mf_ck->rws_completed) < mf_ck->rws_block_end) { /* then check if there's still data to write */ if (mf_ck->ndef->offset < mf_ck->ndef->length) err = mifare_write_block( mf_ck->rws_block_start + mf_ck->rws_completed, data, mifare_write_sector_cb); else /* No more Data to write */ /* Correct length of the ndef message */ err = mifare_unlock_sector(NFC_1ST_BLOCK, mifare_correct_length, mf_ck); } else { /* Process the callback */ err = (*mf_ck->rws_next_fct)(resp, length, data); } if (err < 0) return mifare_release(err, mf_ck); return err; }
/* After writing ndef message, its length has to be updated */ static int mifare_correct_length(uint8_t *resp, int length, void *data) { struct mifare_cookie *mf_ck = data; DBG(""); /* Correct length field */ mf_ck->ndef->data[1] = mf_ck->ndef_length; /* and ndef offset so it points to the beginning */ mf_ck->ndef->offset = 0; /* Run the write process only on the first block of the sector */ return mifare_write_block(NFC_1ST_BLOCK, mf_ck, mifare_correct_length_cb); }
static int mifare_write_sector_unlocked(uint8_t *resp, int length, void *data) { struct mifare_cookie *mf_ck = data; int err; if (length < 0) { err = length; goto out_err; } /* Run the write process on the first block of the sector */ err = mifare_write_block(mf_ck->rws_block_start, data, mifare_write_sector_cb); if (err < 0) goto out_err; return err; out_err: return mifare_release(err, mf_ck); }
void loop_clone_rfid(uint8_t *menu, uint8_t *opmode) { uint8_t data[80]; uint8_t keyindex = 0; uint8_t block = 0; uint8_t tries = 0; int res, oid; get_firmware_version(); while (block < BLOCKS) { if ( READ != *menu) { break; } res = mifare_reader_init(data, sizeof(data)); if (tries >= KEYS) { tries = 0; block += 1; } if (res >= 0) { res = initiator_init(data, sizeof(data)); if (res >= 11) { if (0x00 == data[3] && data[6] >= 0x04) { memcpy(&oid, &data[7], sizeof(oid)); if (0x00 == block) { debug_printf("MIFARE_CARD_ID:"); rfid_hexdump(&oid, sizeof(oid)); } set_uid(data, oid); set_key(data, keyindex); res = mifare_authenticate_block(data, sizeof(data), block); /* debug_printf("res:"); rfid_hexdump(&res, sizeof(res)); debug_printf("data:"); rfid_hexdump(&data[0], sizeof(data)); */ if (0x41 == data[0] && 0x00 == data[1]) { debug_printf("Auth Succeeded.\n"); tries = 0; switch (*opmode) { case READ: res = mifare_read_block(data, sizeof(data), block); if (res == 18) { debug_printf("Block:"); rfid_hexdump(&block, sizeof(block)); debug_printf("Data:"); rfid_hexdump(&data[2], BLOCK_SIZE); debug_printf("Key:"); rfid_hexdump(&default_keys[keyindex], MIFARE_KEY_SIZE); memcpy(&mifare_card[block*BLOCK_SIZE], &data[2], BLOCK_SIZE); if (0x00 == (block+1) % 4) { memcpy(&mifare_card[block*BLOCK_SIZE], &default_keys[keyindex], MIFARE_KEY_SIZE); memcpy(&mifare_card[block*BLOCK_SIZE+6], &access_bytes[0], ACCESS_BYTES); memcpy(&mifare_card[block*BLOCK_SIZE+10], &key_b[0], MIFARE_KEY_SIZE); } } break; case WRITE: memcpy(&data[4], &mifare_card[block*BLOCK_SIZE], BLOCK_SIZE); res = mifare_write_block(data, sizeof(data), block); debug_printf("res:"); rfid_hexdump(&res, sizeof(res)); break; } block += 1; } else if (0x41 == data[0] && 0x14 == data[1]) { debug_printf("Auth Failed.\n"); keyindex = (keyindex + 1) % KEYS; tries += 1; } } } } else { turn_rf_off(data, sizeof(data)); } } *menu = LIBNFC; }