|
@@ -8,7 +8,7 @@
|
|
|
#define HAS_MASK(x, b) ((x & b) == b)
|
|
#define HAS_MASK(x, b) ((x & b) == b)
|
|
|
|
|
|
|
|
// CSNs from Proxmark3 repo
|
|
// CSNs from Proxmark3 repo
|
|
|
-static const uint8_t loclass_csns[LOCLASS_NUM_CSNS][RFAL_PICOPASS_BLOCK_LEN] = {
|
|
|
|
|
|
|
+static const uint8_t loclass_csns[LOCLASS_NUM_CSNS][PICOPASS_BLOCK_LEN] = {
|
|
|
{0x01, 0x0A, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0},
|
|
{0x01, 0x0A, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0},
|
|
|
{0x0C, 0x06, 0x0C, 0xFE, 0xF7, 0xFF, 0x12, 0xE0},
|
|
{0x0C, 0x06, 0x0C, 0xFE, 0xF7, 0xFF, 0x12, 0xE0},
|
|
|
{0x10, 0x97, 0x83, 0x7B, 0xF7, 0xFF, 0x12, 0xE0},
|
|
{0x10, 0x97, 0x83, 0x7B, 0xF7, 0xFF, 0x12, 0xE0},
|
|
@@ -220,7 +220,7 @@ static ReturnCode
|
|
|
uint8_t ccnr[12] = {0};
|
|
uint8_t ccnr[12] = {0};
|
|
|
|
|
|
|
|
size_t index = 0;
|
|
size_t index = 0;
|
|
|
- uint8_t key[RFAL_PICOPASS_BLOCK_LEN] = {0};
|
|
|
|
|
|
|
+ uint8_t key[PICOPASS_BLOCK_LEN] = {0};
|
|
|
|
|
|
|
|
if(!iclass_elite_dict_check_presence(dict_type)) {
|
|
if(!iclass_elite_dict_check_presence(dict_type)) {
|
|
|
FURI_LOG_E(TAG, "Dictionary not found");
|
|
FURI_LOG_E(TAG, "Dictionary not found");
|
|
@@ -261,7 +261,7 @@ static ReturnCode
|
|
|
|
|
|
|
|
err = rfalPicoPassPollerCheck(mac, &chkRes);
|
|
err = rfalPicoPassPollerCheck(mac, &chkRes);
|
|
|
if(err == ERR_NONE) {
|
|
if(err == ERR_NONE) {
|
|
|
- memcpy(pacs->key, key, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ memcpy(pacs->key, key, PICOPASS_BLOCK_LEN);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -379,7 +379,7 @@ ReturnCode picopass_write_card(PicopassBlock* AA1) {
|
|
|
FURI_LOG_D(TAG, "rfalPicoPassPollerWriteBlock %d", i);
|
|
FURI_LOG_D(TAG, "rfalPicoPassPollerWriteBlock %d", i);
|
|
|
uint8_t data[9] = {0};
|
|
uint8_t data[9] = {0};
|
|
|
data[0] = i;
|
|
data[0] = i;
|
|
|
- memcpy(data + 1, AA1[i].data, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ memcpy(data + 1, AA1[i].data, PICOPASS_BLOCK_LEN);
|
|
|
loclass_doMAC_N(data, sizeof(data), div_key, mac);
|
|
loclass_doMAC_N(data, sizeof(data), div_key, mac);
|
|
|
FURI_LOG_D(
|
|
FURI_LOG_D(
|
|
|
TAG,
|
|
TAG,
|
|
@@ -438,7 +438,7 @@ ReturnCode picopass_write_block(PicopassBlock* AA1, uint8_t blockNo, uint8_t* ne
|
|
|
}
|
|
}
|
|
|
memcpy(ccnr, rcRes.CCNR, sizeof(rcRes.CCNR)); // last 4 bytes left 0
|
|
memcpy(ccnr, rcRes.CCNR, sizeof(rcRes.CCNR)); // last 4 bytes left 0
|
|
|
|
|
|
|
|
- if(memcmp(selRes.CSN, AA1[PICOPASS_CSN_BLOCK_INDEX].data, RFAL_PICOPASS_BLOCK_LEN) != 0) {
|
|
|
|
|
|
|
+ if(memcmp(selRes.CSN, AA1[PICOPASS_CSN_BLOCK_INDEX].data, PICOPASS_BLOCK_LEN) != 0) {
|
|
|
FURI_LOG_E(TAG, "Wrong CSN for write");
|
|
FURI_LOG_E(TAG, "Wrong CSN for write");
|
|
|
return ERR_REQUEST;
|
|
return ERR_REQUEST;
|
|
|
}
|
|
}
|
|
@@ -514,7 +514,7 @@ void picopass_worker_elite_dict_attack(PicopassWorker* picopass_worker) {
|
|
|
uint8_t ccnr[12] = {0};
|
|
uint8_t ccnr[12] = {0};
|
|
|
|
|
|
|
|
size_t index = 0;
|
|
size_t index = 0;
|
|
|
- uint8_t key[RFAL_PICOPASS_BLOCK_LEN] = {0};
|
|
|
|
|
|
|
+ uint8_t key[PICOPASS_BLOCK_LEN] = {0};
|
|
|
|
|
|
|
|
// Load dictionary
|
|
// Load dictionary
|
|
|
IclassEliteDict* dict = dict_attack_data->dict;
|
|
IclassEliteDict* dict = dict_attack_data->dict;
|
|
@@ -590,7 +590,7 @@ void picopass_worker_elite_dict_attack(PicopassWorker* picopass_worker) {
|
|
|
key[6],
|
|
key[6],
|
|
|
key[7]);
|
|
key[7]);
|
|
|
|
|
|
|
|
- memcpy(pacs->key, key, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ memcpy(pacs->key, key, PICOPASS_BLOCK_LEN);
|
|
|
pacs->elite_kdf = elite;
|
|
pacs->elite_kdf = elite;
|
|
|
err = picopass_read_card(AA1);
|
|
err = picopass_read_card(AA1);
|
|
|
if(err != ERR_NONE) {
|
|
if(err != ERR_NONE) {
|
|
@@ -768,7 +768,7 @@ void picopass_worker_write_key(PicopassWorker* picopass_worker) {
|
|
|
uint8_t fuses = configBlock[7];
|
|
uint8_t fuses = configBlock[7];
|
|
|
uint8_t* oldKey = AA1[PICOPASS_SECURE_KD_BLOCK_INDEX].data;
|
|
uint8_t* oldKey = AA1[PICOPASS_SECURE_KD_BLOCK_INDEX].data;
|
|
|
|
|
|
|
|
- uint8_t newKey[RFAL_PICOPASS_BLOCK_LEN] = {0};
|
|
|
|
|
|
|
+ uint8_t newKey[PICOPASS_BLOCK_LEN] = {0};
|
|
|
loclass_iclass_calc_div_key(csn, pacs->key, newKey, pacs->elite_kdf);
|
|
loclass_iclass_calc_div_key(csn, pacs->key, newKey, pacs->elite_kdf);
|
|
|
|
|
|
|
|
if((fuses & 0x80) == 0x80) {
|
|
if((fuses & 0x80) == 0x80) {
|
|
@@ -776,7 +776,7 @@ void picopass_worker_write_key(PicopassWorker* picopass_worker) {
|
|
|
} else {
|
|
} else {
|
|
|
FURI_LOG_D(TAG, "XOR write for application mode key change");
|
|
FURI_LOG_D(TAG, "XOR write for application mode key change");
|
|
|
// XOR when in application mode
|
|
// XOR when in application mode
|
|
|
- for(size_t i = 0; i < RFAL_PICOPASS_BLOCK_LEN; i++) {
|
|
|
|
|
|
|
+ for(size_t i = 0; i < PICOPASS_BLOCK_LEN; i++) {
|
|
|
newKey[i] ^= oldKey[i];
|
|
newKey[i] ^= oldKey[i];
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -819,9 +819,7 @@ static inline void picopass_emu_read_blocks(
|
|
|
uint8_t block_num,
|
|
uint8_t block_num,
|
|
|
uint8_t block_count) {
|
|
uint8_t block_count) {
|
|
|
memcpy(
|
|
memcpy(
|
|
|
- buf,
|
|
|
|
|
- nfcv_data->data + (block_num * RFAL_PICOPASS_BLOCK_LEN),
|
|
|
|
|
- block_count * RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ buf, nfcv_data->data + (block_num * PICOPASS_BLOCK_LEN), block_count * PICOPASS_BLOCK_LEN);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static inline void picopass_emu_write_blocks(
|
|
static inline void picopass_emu_write_blocks(
|
|
@@ -830,23 +828,21 @@ static inline void picopass_emu_write_blocks(
|
|
|
uint8_t block_num,
|
|
uint8_t block_num,
|
|
|
uint8_t block_count) {
|
|
uint8_t block_count) {
|
|
|
memcpy(
|
|
memcpy(
|
|
|
- nfcv_data->data + (block_num * RFAL_PICOPASS_BLOCK_LEN),
|
|
|
|
|
- buf,
|
|
|
|
|
- block_count * RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ nfcv_data->data + (block_num * PICOPASS_BLOCK_LEN), buf, block_count * PICOPASS_BLOCK_LEN);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void picopass_init_cipher_state_key(
|
|
static void picopass_init_cipher_state_key(
|
|
|
NfcVData* nfcv_data,
|
|
NfcVData* nfcv_data,
|
|
|
PicopassEmulatorCtx* ctx,
|
|
PicopassEmulatorCtx* ctx,
|
|
|
- const uint8_t key[RFAL_PICOPASS_BLOCK_LEN]) {
|
|
|
|
|
- uint8_t cc[RFAL_PICOPASS_BLOCK_LEN];
|
|
|
|
|
|
|
+ const uint8_t key[PICOPASS_BLOCK_LEN]) {
|
|
|
|
|
+ uint8_t cc[PICOPASS_BLOCK_LEN];
|
|
|
picopass_emu_read_blocks(nfcv_data, cc, PICOPASS_SECURE_EPURSE_BLOCK_INDEX, 1);
|
|
picopass_emu_read_blocks(nfcv_data, cc, PICOPASS_SECURE_EPURSE_BLOCK_INDEX, 1);
|
|
|
|
|
|
|
|
ctx->cipher_state = loclass_opt_doTagMAC_1(cc, key);
|
|
ctx->cipher_state = loclass_opt_doTagMAC_1(cc, key);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void picopass_init_cipher_state(NfcVData* nfcv_data, PicopassEmulatorCtx* ctx) {
|
|
static void picopass_init_cipher_state(NfcVData* nfcv_data, PicopassEmulatorCtx* ctx) {
|
|
|
- uint8_t key[RFAL_PICOPASS_BLOCK_LEN];
|
|
|
|
|
|
|
+ uint8_t key[PICOPASS_BLOCK_LEN];
|
|
|
|
|
|
|
|
picopass_emu_read_blocks(nfcv_data, key, ctx->key_block_num, 1);
|
|
picopass_emu_read_blocks(nfcv_data, key, ctx->key_block_num, 1);
|
|
|
|
|
|
|
@@ -858,10 +854,10 @@ static void
|
|
|
// collect LOCLASS_NUM_PER_CSN nonces in a row for each CSN
|
|
// collect LOCLASS_NUM_PER_CSN nonces in a row for each CSN
|
|
|
const uint8_t* csn =
|
|
const uint8_t* csn =
|
|
|
loclass_csns[(ctx->key_block_num / LOCLASS_NUM_PER_CSN) % LOCLASS_NUM_CSNS];
|
|
loclass_csns[(ctx->key_block_num / LOCLASS_NUM_PER_CSN) % LOCLASS_NUM_CSNS];
|
|
|
- memcpy(nfc_data->uid, csn, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ memcpy(nfc_data->uid, csn, PICOPASS_BLOCK_LEN);
|
|
|
picopass_emu_write_blocks(nfcv_data, csn, PICOPASS_CSN_BLOCK_INDEX, 1);
|
|
picopass_emu_write_blocks(nfcv_data, csn, PICOPASS_CSN_BLOCK_INDEX, 1);
|
|
|
|
|
|
|
|
- uint8_t key[RFAL_PICOPASS_BLOCK_LEN];
|
|
|
|
|
|
|
+ uint8_t key[PICOPASS_BLOCK_LEN];
|
|
|
loclass_iclass_calc_div_key(csn, picopass_iclass_key, key, false);
|
|
loclass_iclass_calc_div_key(csn, picopass_iclass_key, key, false);
|
|
|
picopass_emu_write_blocks(nfcv_data, key, PICOPASS_SECURE_KD_BLOCK_INDEX, 1);
|
|
picopass_emu_write_blocks(nfcv_data, key, PICOPASS_SECURE_KD_BLOCK_INDEX, 1);
|
|
|
|
|
|
|
@@ -918,8 +914,8 @@ static void picopass_emu_handle_packet(
|
|
|
ctx->state == PicopassEmulatorStateActive) { // PICOPASS_CMD_IDENTIFY
|
|
ctx->state == PicopassEmulatorStateActive) { // PICOPASS_CMD_IDENTIFY
|
|
|
// ASNB(8) CRC16(2)
|
|
// ASNB(8) CRC16(2)
|
|
|
picopass_anticoll_csn(response, nfc_data->uid);
|
|
picopass_anticoll_csn(response, nfc_data->uid);
|
|
|
- picopass_append_crc(response, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
- response_length = RFAL_PICOPASS_BLOCK_LEN + 2;
|
|
|
|
|
|
|
+ picopass_append_crc(response, PICOPASS_BLOCK_LEN);
|
|
|
|
|
+ response_length = PICOPASS_BLOCK_LEN + 2;
|
|
|
break;
|
|
break;
|
|
|
} else if(
|
|
} else if(
|
|
|
nfcv_data->frame_length == 4 &&
|
|
nfcv_data->frame_length == 4 &&
|
|
@@ -935,12 +931,12 @@ static void picopass_emu_handle_packet(
|
|
|
if(nfcv_data->frame[1] == PICOPASS_SECURE_KD_BLOCK_INDEX ||
|
|
if(nfcv_data->frame[1] == PICOPASS_SECURE_KD_BLOCK_INDEX ||
|
|
|
nfcv_data->frame[1] == PICOPASS_SECURE_KC_BLOCK_INDEX) {
|
|
nfcv_data->frame[1] == PICOPASS_SECURE_KC_BLOCK_INDEX) {
|
|
|
// Reading Kd or Kc blocks always returns FF's
|
|
// Reading Kd or Kc blocks always returns FF's
|
|
|
- memcpy(response, block_ff, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ memcpy(response, block_ff, PICOPASS_BLOCK_LEN);
|
|
|
} else {
|
|
} else {
|
|
|
picopass_emu_read_blocks(nfcv_data, response, nfcv_data->frame[1], 1);
|
|
picopass_emu_read_blocks(nfcv_data, response, nfcv_data->frame[1], 1);
|
|
|
}
|
|
}
|
|
|
- picopass_append_crc(response, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
- response_length = RFAL_PICOPASS_BLOCK_LEN + 2;
|
|
|
|
|
|
|
+ picopass_append_crc(response, PICOPASS_BLOCK_LEN);
|
|
|
|
|
+ response_length = PICOPASS_BLOCK_LEN + 2;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -960,32 +956,32 @@ static void picopass_emu_handle_packet(
|
|
|
picopass_emu_read_blocks(nfcv_data, response, blockNum, 4);
|
|
picopass_emu_read_blocks(nfcv_data, response, blockNum, 4);
|
|
|
if(blockNum == 4) {
|
|
if(blockNum == 4) {
|
|
|
// Kc is block 4, so just redact first block of response
|
|
// Kc is block 4, so just redact first block of response
|
|
|
- memcpy(response, block_ff, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ memcpy(response, block_ff, PICOPASS_BLOCK_LEN);
|
|
|
} else if(blockNum < 4) {
|
|
} else if(blockNum < 4) {
|
|
|
// Kd is block 3
|
|
// Kd is block 3
|
|
|
- uint8_t* kdOffset = response + ((3 - blockNum) * RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
- memcpy(kdOffset, block_ff, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ uint8_t* kdOffset = response + ((3 - blockNum) * PICOPASS_BLOCK_LEN);
|
|
|
|
|
+ memcpy(kdOffset, block_ff, PICOPASS_BLOCK_LEN);
|
|
|
if(blockNum != 0) {
|
|
if(blockNum != 0) {
|
|
|
// Redact Kc
|
|
// Redact Kc
|
|
|
- memcpy(kdOffset + RFAL_PICOPASS_BLOCK_LEN, block_ff, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ memcpy(kdOffset + PICOPASS_BLOCK_LEN, block_ff, PICOPASS_BLOCK_LEN);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- picopass_append_crc(response, RFAL_PICOPASS_BLOCK_LEN * 4);
|
|
|
|
|
- response_length = (RFAL_PICOPASS_BLOCK_LEN * 4) + 2;
|
|
|
|
|
|
|
+ picopass_append_crc(response, PICOPASS_BLOCK_LEN * 4);
|
|
|
|
|
+ response_length = (PICOPASS_BLOCK_LEN * 4) + 2;
|
|
|
break;
|
|
break;
|
|
|
case RFAL_PICOPASS_CMD_SELECT: // ASNB(8)|SERIALNB(8)
|
|
case RFAL_PICOPASS_CMD_SELECT: // ASNB(8)|SERIALNB(8)
|
|
|
if(nfcv_data->frame_length != 9) {
|
|
if(nfcv_data->frame_length != 9) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- uint8_t select_csn[RFAL_PICOPASS_BLOCK_LEN];
|
|
|
|
|
|
|
+ uint8_t select_csn[PICOPASS_BLOCK_LEN];
|
|
|
if(ctx->state == PicopassEmulatorStateHalt || ctx->state == PicopassEmulatorStateIdle) {
|
|
if(ctx->state == PicopassEmulatorStateHalt || ctx->state == PicopassEmulatorStateIdle) {
|
|
|
- memcpy(select_csn, nfc_data->uid, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ memcpy(select_csn, nfc_data->uid, PICOPASS_BLOCK_LEN);
|
|
|
} else {
|
|
} else {
|
|
|
picopass_anticoll_csn(select_csn, nfc_data->uid);
|
|
picopass_anticoll_csn(select_csn, nfc_data->uid);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if(memcmp(nfcv_data->frame + 1, select_csn, RFAL_PICOPASS_BLOCK_LEN)) {
|
|
|
|
|
|
|
+ if(memcmp(nfcv_data->frame + 1, select_csn, PICOPASS_BLOCK_LEN)) {
|
|
|
if(ctx->state == PicopassEmulatorStateActive) {
|
|
if(ctx->state == PicopassEmulatorStateActive) {
|
|
|
ctx->state = PicopassEmulatorStateIdle;
|
|
ctx->state = PicopassEmulatorStateIdle;
|
|
|
} else if(ctx->state == PicopassEmulatorStateSelected) {
|
|
} else if(ctx->state == PicopassEmulatorStateSelected) {
|
|
@@ -999,10 +995,10 @@ static void picopass_emu_handle_packet(
|
|
|
ctx->state = PicopassEmulatorStateSelected;
|
|
ctx->state = PicopassEmulatorStateSelected;
|
|
|
|
|
|
|
|
// SERIALNB(8) CRC16(2)
|
|
// SERIALNB(8) CRC16(2)
|
|
|
- memcpy(response, nfc_data->uid, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
- picopass_append_crc(response, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ memcpy(response, nfc_data->uid, PICOPASS_BLOCK_LEN);
|
|
|
|
|
+ picopass_append_crc(response, PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
|
- response_length = RFAL_PICOPASS_BLOCK_LEN + 2;
|
|
|
|
|
|
|
+ response_length = PICOPASS_BLOCK_LEN + 2;
|
|
|
break;
|
|
break;
|
|
|
case RFAL_PICOPASS_CMD_READCHECK_KC: // ADDRESS(1)
|
|
case RFAL_PICOPASS_CMD_READCHECK_KC: // ADDRESS(1)
|
|
|
key_block_num = PICOPASS_SECURE_KC_BLOCK_INDEX;
|
|
key_block_num = PICOPASS_SECURE_KC_BLOCK_INDEX;
|
|
@@ -1023,7 +1019,7 @@ static void picopass_emu_handle_packet(
|
|
|
|
|
|
|
|
// DATA(8)
|
|
// DATA(8)
|
|
|
picopass_emu_read_blocks(nfcv_data, response, nfcv_data->frame[1], 1);
|
|
picopass_emu_read_blocks(nfcv_data, response, nfcv_data->frame[1], 1);
|
|
|
- response_length = RFAL_PICOPASS_BLOCK_LEN;
|
|
|
|
|
|
|
+ response_length = PICOPASS_BLOCK_LEN;
|
|
|
break;
|
|
break;
|
|
|
case RFAL_PICOPASS_CMD_CHECK: // CHALLENGE(4) READERSIGNATURE(4)
|
|
case RFAL_PICOPASS_CMD_CHECK: // CHALLENGE(4) READERSIGNATURE(4)
|
|
|
if(nfcv_data->frame_length != 9 || ctx->state != PicopassEmulatorStateSelected) {
|
|
if(nfcv_data->frame_length != 9 || ctx->state != PicopassEmulatorStateSelected) {
|
|
@@ -1034,11 +1030,11 @@ static void picopass_emu_handle_packet(
|
|
|
// LOCLASS Reader attack mode
|
|
// LOCLASS Reader attack mode
|
|
|
|
|
|
|
|
// Copy EPURSE
|
|
// Copy EPURSE
|
|
|
- uint8_t cc[RFAL_PICOPASS_BLOCK_LEN];
|
|
|
|
|
|
|
+ uint8_t cc[PICOPASS_BLOCK_LEN];
|
|
|
picopass_emu_read_blocks(nfcv_data, cc, PICOPASS_SECURE_EPURSE_BLOCK_INDEX, 1);
|
|
picopass_emu_read_blocks(nfcv_data, cc, PICOPASS_SECURE_EPURSE_BLOCK_INDEX, 1);
|
|
|
|
|
|
|
|
#ifndef PICOPASS_DEBUG_IGNORE_LOCLASS_STD_KEY
|
|
#ifndef PICOPASS_DEBUG_IGNORE_LOCLASS_STD_KEY
|
|
|
- uint8_t key[RFAL_PICOPASS_BLOCK_LEN];
|
|
|
|
|
|
|
+ uint8_t key[PICOPASS_BLOCK_LEN];
|
|
|
// loclass mode stores the derived standard debit key in Kd to check
|
|
// loclass mode stores the derived standard debit key in Kd to check
|
|
|
picopass_emu_read_blocks(nfcv_data, key, PICOPASS_SECURE_KD_BLOCK_INDEX, 1);
|
|
picopass_emu_read_blocks(nfcv_data, key, PICOPASS_SECURE_KD_BLOCK_INDEX, 1);
|
|
|
|
|
|
|
@@ -1071,7 +1067,7 @@ static void picopass_emu_handle_packet(
|
|
|
// CSN changed
|
|
// CSN changed
|
|
|
if(ctx->key_block_num % LOCLASS_NUM_PER_CSN == 0) {
|
|
if(ctx->key_block_num % LOCLASS_NUM_PER_CSN == 0) {
|
|
|
// Flush NR-MACs for this CSN to SD card
|
|
// Flush NR-MACs for this CSN to SD card
|
|
|
- uint8_t cc[RFAL_PICOPASS_BLOCK_LEN];
|
|
|
|
|
|
|
+ uint8_t cc[PICOPASS_BLOCK_LEN];
|
|
|
picopass_emu_read_blocks(nfcv_data, cc, PICOPASS_SECURE_EPURSE_BLOCK_INDEX, 1);
|
|
picopass_emu_read_blocks(nfcv_data, cc, PICOPASS_SECURE_EPURSE_BLOCK_INDEX, 1);
|
|
|
|
|
|
|
|
for(int i = 0; i < LOCLASS_NUM_PER_CSN; i++) {
|
|
for(int i = 0; i < LOCLASS_NUM_PER_CSN; i++) {
|
|
@@ -1096,7 +1092,7 @@ static void picopass_emu_handle_packet(
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- uint8_t key[RFAL_PICOPASS_BLOCK_LEN];
|
|
|
|
|
|
|
+ uint8_t key[PICOPASS_BLOCK_LEN];
|
|
|
picopass_emu_read_blocks(nfcv_data, key, ctx->key_block_num, 1);
|
|
picopass_emu_read_blocks(nfcv_data, key, ctx->key_block_num, 1);
|
|
|
|
|
|
|
|
uint8_t rmac[4];
|
|
uint8_t rmac[4];
|
|
@@ -1125,7 +1121,7 @@ static void picopass_emu_handle_packet(
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- uint8_t cfgBlock[RFAL_PICOPASS_BLOCK_LEN];
|
|
|
|
|
|
|
+ uint8_t cfgBlock[PICOPASS_BLOCK_LEN];
|
|
|
picopass_emu_read_blocks(nfcv_data, cfgBlock, PICOPASS_CONFIG_BLOCK_INDEX, 1);
|
|
picopass_emu_read_blocks(nfcv_data, cfgBlock, PICOPASS_CONFIG_BLOCK_INDEX, 1);
|
|
|
bool persMode = HAS_MASK(cfgBlock[7], PICOPASS_FUSE_PERS);
|
|
bool persMode = HAS_MASK(cfgBlock[7], PICOPASS_FUSE_PERS);
|
|
|
|
|
|
|
@@ -1160,7 +1156,7 @@ static void picopass_emu_handle_packet(
|
|
|
// -> must auth with that key to change it
|
|
// -> must auth with that key to change it
|
|
|
|
|
|
|
|
uint8_t blockOffset = nfcv_data->frame[1];
|
|
uint8_t blockOffset = nfcv_data->frame[1];
|
|
|
- uint8_t block[RFAL_PICOPASS_BLOCK_LEN];
|
|
|
|
|
|
|
+ uint8_t block[PICOPASS_BLOCK_LEN];
|
|
|
switch(nfcv_data->frame[1]) {
|
|
switch(nfcv_data->frame[1]) {
|
|
|
case PICOPASS_CONFIG_BLOCK_INDEX:
|
|
case PICOPASS_CONFIG_BLOCK_INDEX:
|
|
|
block[0] = cfgBlock[0]; // Applications Limit
|
|
block[0] = cfgBlock[0]; // Applications Limit
|
|
@@ -1193,14 +1189,14 @@ static void picopass_emu_handle_packet(
|
|
|
case PICOPASS_SECURE_KC_BLOCK_INDEX:
|
|
case PICOPASS_SECURE_KC_BLOCK_INDEX:
|
|
|
if(!persMode) {
|
|
if(!persMode) {
|
|
|
picopass_emu_read_blocks(nfcv_data, block, blockOffset, 1);
|
|
picopass_emu_read_blocks(nfcv_data, block, blockOffset, 1);
|
|
|
- for(uint8_t i = 0; i < sizeof(RFAL_PICOPASS_BLOCK_LEN); i++)
|
|
|
|
|
|
|
+ for(uint8_t i = 0; i < sizeof(PICOPASS_BLOCK_LEN); i++)
|
|
|
block[i] ^= nfcv_data->frame[i + 2];
|
|
block[i] ^= nfcv_data->frame[i + 2];
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
// Use default case when in personalisation mode
|
|
// Use default case when in personalisation mode
|
|
|
// fallthrough
|
|
// fallthrough
|
|
|
default:
|
|
default:
|
|
|
- memcpy(block, nfcv_data->frame + 2, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ memcpy(block, nfcv_data->frame + 2, PICOPASS_BLOCK_LEN);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1215,12 +1211,12 @@ static void picopass_emu_handle_packet(
|
|
|
if(nfcv_data->frame[1] == PICOPASS_SECURE_KD_BLOCK_INDEX ||
|
|
if(nfcv_data->frame[1] == PICOPASS_SECURE_KD_BLOCK_INDEX ||
|
|
|
nfcv_data->frame[1] == PICOPASS_SECURE_KD_BLOCK_INDEX) {
|
|
nfcv_data->frame[1] == PICOPASS_SECURE_KD_BLOCK_INDEX) {
|
|
|
// Key updates always return FF's
|
|
// Key updates always return FF's
|
|
|
- memcpy(response, block_ff, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ memcpy(response, block_ff, PICOPASS_BLOCK_LEN);
|
|
|
} else {
|
|
} else {
|
|
|
- memcpy(response, block, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ memcpy(response, block, PICOPASS_BLOCK_LEN);
|
|
|
}
|
|
}
|
|
|
- picopass_append_crc(response, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
- response_length = RFAL_PICOPASS_BLOCK_LEN + 2;
|
|
|
|
|
|
|
+ picopass_append_crc(response, PICOPASS_BLOCK_LEN);
|
|
|
|
|
+ response_length = PICOPASS_BLOCK_LEN + 2;
|
|
|
break;
|
|
break;
|
|
|
case RFAL_PICOPASS_CMD_PAGESEL: // PAGE(1) CRC16(2)
|
|
case RFAL_PICOPASS_CMD_PAGESEL: // PAGE(1) CRC16(2)
|
|
|
// Chips with a single page do not answer to this command
|
|
// Chips with a single page do not answer to this command
|
|
@@ -1262,7 +1258,7 @@ void picopass_worker_emulate(PicopassWorker* picopass_worker, bool loclass_mode)
|
|
|
.uid_len = RFAL_PICOPASS_UID_LEN,
|
|
.uid_len = RFAL_PICOPASS_UID_LEN,
|
|
|
};
|
|
};
|
|
|
NfcVData* nfcv_data = malloc(sizeof(NfcVData));
|
|
NfcVData* nfcv_data = malloc(sizeof(NfcVData));
|
|
|
- nfcv_data->block_size = RFAL_PICOPASS_BLOCK_LEN;
|
|
|
|
|
|
|
+ nfcv_data->block_size = PICOPASS_BLOCK_LEN;
|
|
|
nfcv_data->emu_protocol_ctx = &emu_ctx;
|
|
nfcv_data->emu_protocol_ctx = &emu_ctx;
|
|
|
nfcv_data->emu_protocol_handler = &picopass_emu_handle_packet;
|
|
nfcv_data->emu_protocol_handler = &picopass_emu_handle_packet;
|
|
|
|
|
|
|
@@ -1300,7 +1296,7 @@ void picopass_worker_emulate(PicopassWorker* picopass_worker, bool loclass_mode)
|
|
|
|
|
|
|
|
loclass_writer_write_start_stop(emu_ctx.loclass_writer, true);
|
|
loclass_writer_write_start_stop(emu_ctx.loclass_writer, true);
|
|
|
} else {
|
|
} else {
|
|
|
- memcpy(nfc_data.uid, blocks[PICOPASS_CSN_BLOCK_INDEX].data, RFAL_PICOPASS_BLOCK_LEN);
|
|
|
|
|
|
|
+ memcpy(nfc_data.uid, blocks[PICOPASS_CSN_BLOCK_INDEX].data, PICOPASS_BLOCK_LEN);
|
|
|
memcpy(nfcv_data->data, blocks, sizeof(dev_data->AA1));
|
|
memcpy(nfcv_data->data, blocks, sizeof(dev_data->AA1));
|
|
|
picopass_init_cipher_state(nfcv_data, &emu_ctx);
|
|
picopass_init_cipher_state(nfcv_data, &emu_ctx);
|
|
|
}
|
|
}
|