fetch wplugins

This commit is contained in:
r3df0xx
2022-05-18 17:23:59 +03:00
parent 12200299bc
commit 4760c1c5ce
57 changed files with 664 additions and 58 deletions

View File

@@ -311,3 +311,118 @@ uint8_t mf_classic_read_card(
return sectors_read;
}
bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_rx) {
furi_assert(emulator);
furi_assert(tx_rx);
// Get first frame
tx_rx->tx_bits = 0;
tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault;
furi_hal_nfc_tx_rx(tx_rx, 300);
// TODO support all commands
uint8_t cmd = tx_rx->rx_data[0];
if(!(cmd == 0x60 || cmd == 0x61)) {
FURI_LOG_E(TAG, "Unsupported command");
return false;
}
uint8_t block = tx_rx->rx_data[1];
uint64_t key = 0;
// TODO Now works only for 1k!!!
uint8_t sector_trailer_block = block | 0x03;
MfClassicSectorTrailer* sector_trailer =
(MfClassicSectorTrailer*)emulator->data.block[sector_trailer_block].value;
if(cmd & 0x01) {
key = nfc_util_bytes2num(sector_trailer->key_b, 6);
} else {
key = nfc_util_bytes2num(sector_trailer->key_a, 6);
}
uint32_t nonce = prng_successor(DWT->CYCCNT, 32);
uint8_t nt[4];
uint8_t nt_keystream[4];
nfc_util_num2bytes(nonce, 4, nt);
nfc_util_num2bytes(nonce ^ emulator->cuid, 4, nt_keystream);
crypto1_init(&emulator->crypto, key);
crypto1_word(&emulator->crypto, emulator->cuid ^ nonce, 0);
memcpy(tx_rx->tx_data, nt, sizeof(nt));
tx_rx->tx_bits = sizeof(nt) * 8;
tx_rx->tx_rx_type = FuriHalNfcTxRxTypeRxRaw;
if(!furi_hal_nfc_tx_rx(tx_rx, 500)) {
FURI_LOG_E(TAG, "Error in 1st data exchange");
return false;
}
if(tx_rx->rx_bits != 64) {
FURI_LOG_E(TAG, "Incorrect nr + ar");
return false;
}
uint32_t nr = nfc_util_bytes2num(tx_rx->rx_data, 4);
uint32_t ar = nfc_util_bytes2num(&tx_rx->rx_data[4], 4);
crypto1_word(&emulator->crypto, nr, 1);
uint32_t cardRr = ar ^ crypto1_word(&emulator->crypto, 0, 0);
if(cardRr != prng_successor(nonce, 64)) {
FURI_LOG_E(TAG, "Wrong AUTH! %08X != %08X", cardRr, prng_successor(nonce, 64));
// Don't send NACK, as tag don't send it
return false;
}
uint32_t ans = prng_successor(nonce, 96);
uint8_t responce[4] = {};
nfc_util_num2bytes(ans, 4, responce);
tx_rx->tx_parity[0] = 0;
for(uint8_t i = 0; i < 4; i++) {
tx_rx->tx_data[i] = crypto1_byte(&emulator->crypto, 0, 0) ^ responce[i];
tx_rx->tx_parity[0] |=
(((crypto1_filter(emulator->crypto.odd) ^ nfc_util_odd_parity8(responce[i])) & 0x01)
<< (7 - (i & 0x0007)));
}
tx_rx->tx_bits = 8 * 4;
tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent;
if(!furi_hal_nfc_tx_rx(tx_rx, 500)) {
FURI_LOG_E(TAG, "Error in 2nd data exchange");
return false;
}
uint8_t decrypted_cmd[4] = {};
for(uint8_t i = 0; i < 4; i++) {
decrypted_cmd[i] = crypto1_byte(&emulator->crypto, 0, 0) ^ tx_rx->rx_data[i];
}
// FURI_LOG_I(TAG, "Decrypted: %02X %02X", decrypted_cmd[0], decrypted_cmd[1]);
if(decrypted_cmd[0] != 0x30) {
FURI_LOG_W(TAG, "Not read command");
return false;
}
uint16_t block_num = decrypted_cmd[1];
// Send 0 block
uint8_t block_data[18] = {};
memcpy(block_data, emulator->data.block[block_num].value, MF_CLASSIC_BLOCK_SIZE);
nfca_append_crc16(block_data, 16);
tx_rx->tx_parity[0] = 0;
tx_rx->tx_parity[1] = 0;
tx_rx->tx_parity[2] = 0;
for(uint8_t i = 0; i < 18; i++) {
tx_rx->tx_data[i] = crypto1_byte(&emulator->crypto, 0, 0) ^ block_data[i];
tx_rx->tx_parity[i >> 3] |=
(((crypto1_filter(emulator->crypto.odd) ^ nfc_util_odd_parity8(block_data[i])) & 0x01)
<< (7 - (i & 0x0007)));
}
tx_rx->tx_bits = 18 * 8;
tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent;
if(!furi_hal_nfc_tx_rx(tx_rx, 500)) {
FURI_LOG_E(TAG, "Error in Block emulation data exchange");
return false;
}
return false;
}