Merge branch 'RfidResearchGroup:master' into fix-flash-suggest

This commit is contained in:
Self Not Found 2023-01-06 14:20:48 +08:00 committed by GitHub
commit b2d03e8c30
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 313 additions and 949 deletions

View file

@ -36,6 +36,7 @@ jobs:
- name: Install dependencies
run: brew install readline coreutils qt5 RfidResearchGroup/proxmark3/arm-none-eabi-gcc openssl
continue-on-error: true
- name: Install Python dependencies
run: |
@ -77,6 +78,7 @@ jobs:
- name: Install dependencies
run: brew install readline coreutils qt5 RfidResearchGroup/proxmark3/arm-none-eabi-gcc openssl
continue-on-error: true
- name: Install Python dependencies
run: |
@ -119,6 +121,7 @@ jobs:
- name: Install dependencies
run: brew install readline coreutils qt5 RfidResearchGroup/proxmark3/arm-none-eabi-gcc openssl
continue-on-error: true
- name: Install Python dependencies
run: |

View file

@ -3,6 +3,11 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased]
- Add `--shallow` option to `hf iclass` reader commands to do shallow (ASK) reader modulation instead of OOK (@nvx)
- Improved NXP SLI/SLIX series tag identification (@nvx)
- Fixed buffer overflow in "lf em 4x05 sniff" (@HeinrichsH)
- Fixed potential NULL array printing (@jmichel)
- Added PIV aid to resource file (@jmichel)
- Fixed failing compilation on Proxspace environment due to how python is initialized (@jmichel)
- Fixed length check in sim module communications (@jmichel)
- Changed timings in i2c.c when communicating with sim module (@iceman1001)

View file

@ -93,7 +93,13 @@ We define generic Proxmark3 platforms as following devices.
- ⚠ VX
- **Note**: unknown device hw
- ⚠ Proxmark3 X
- **Note**: unknown device hw.
- **Note**: unknown device hw
- ⚠ Proxmark3 Ultimate
- **Note**: unknown device hw
- ⚠ Proxmark3 SE
- **Note**: unknown device hw
When it comes to these new unknown models we are depending on the community to report in if this repo works and what they did to make it work.
**256kb flash memory size of generic Proxmark3 platforms**

View file

@ -322,6 +322,7 @@ static int reader_dump_mode(void) {
.use_credit_key = false,
.do_auth = true,
.send_reply = false,
.shallow_mod = false,
};
memcpy(auth.key, legacy_aa1_key, sizeof(auth.key));
@ -333,7 +334,7 @@ static int reader_dump_mode(void) {
// select tag.
uint32_t eof_time = 0;
bool res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time);
bool res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time, false);
if (res == false) {
switch_off();
continue;
@ -382,7 +383,7 @@ static int reader_dump_mode(void) {
// main read loop
for (uint16_t i = start_block; i <= app1_limit; i++) {
if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time)) {
if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time, false)) {
dumped++;
}
}
@ -394,7 +395,7 @@ static int reader_dump_mode(void) {
auth.use_credit_key = true;
memcpy(auth.key, aa2_key, sizeof(auth.key));
res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time);
res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time, false);
if (res) {
// sanity check of CSN.
@ -408,7 +409,7 @@ static int reader_dump_mode(void) {
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
for (uint16_t i = app1_limit + 1; i <= app2_limit; i++) {
if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time)) {
if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time, false)) {
dumped++;
}
}
@ -458,6 +459,7 @@ static int dump_sim_mode(void) {
.use_credit_key = false,
.do_auth = true,
.send_reply = false,
.shallow_mod = false,
};
memcpy(auth.key, legacy_aa1_key, sizeof(auth.key));
@ -469,7 +471,7 @@ static int dump_sim_mode(void) {
// select tag.
uint32_t eof_time = 0;
bool res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time);
bool res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time, false);
if (res == false) {
switch_off();
continue;
@ -518,7 +520,7 @@ static int dump_sim_mode(void) {
// main read loop
for (uint16_t i = start_block; i <= app1_limit; i++) {
if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time)) {
if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time, false)) {
dumped++;
}
}
@ -530,7 +532,7 @@ static int dump_sim_mode(void) {
auth.use_credit_key = true;
memcpy(auth.key, aa2_key, sizeof(auth.key));
res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time);
res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time, false);
if (res) {
// sanity check of CSN.
@ -544,7 +546,7 @@ static int dump_sim_mode(void) {
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
for (uint16_t i = app1_limit + 1; i <= app2_limit; i++) {
if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time)) {
if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time, false)) {
dumped++;
}
}

View file

@ -1245,23 +1245,23 @@ send:
}
// THE READER CODE
static void iclass_send_as_reader(uint8_t *frame, int len, uint32_t *start_time, uint32_t *end_time) {
static void iclass_send_as_reader(uint8_t *frame, int len, uint32_t *start_time, uint32_t *end_time, bool shallow_mod) {
CodeIso15693AsReader(frame, len);
tosend_t *ts = get_tosend();
TransmitTo15693Tag(ts->buf, ts->max, start_time);
TransmitTo15693Tag(ts->buf, ts->max, start_time, shallow_mod);
*end_time = *start_time + (32 * ((8 * ts->max) - 4)); // subtract the 4 padding bits after EOF
LogTrace_ISO15693(frame, len, (*start_time * 4), (*end_time * 4), NULL, true);
}
static bool iclass_send_cmd_with_retries(uint8_t *cmd, size_t cmdsize, uint8_t *resp, size_t max_resp_size,
uint8_t expected_size, uint8_t tries, uint32_t *start_time,
uint16_t timeout, uint32_t *eof_time) {
uint16_t timeout, uint32_t *eof_time, bool shallow_mod) {
uint16_t resp_len = 0;
int res;
while (tries-- > 0) {
iclass_send_as_reader(cmd, cmdsize, start_time, eof_time);
iclass_send_as_reader(cmd, cmdsize, start_time, eof_time, shallow_mod);
if (resp == NULL) {
return true;
@ -1282,7 +1282,7 @@ static bool iclass_send_cmd_with_retries(uint8_t *cmd, size_t cmdsize, uint8_t *
* @return false = fail
* true = Got all.
*/
static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time, uint8_t *status) {
static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time, uint8_t *status, bool shallow_mod) {
static uint8_t act_all[] = { ICLASS_CMD_ACTALL };
static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x00, 0x73, 0x33 };
@ -1299,7 +1299,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3
// wakeup
uint32_t start_time = GetCountSspClk();
iclass_send_as_reader(act_all, 1, &start_time, eof_time);
iclass_send_as_reader(act_all, 1, &start_time, eof_time, shallow_mod);
int res;
uint16_t resp_len = 0;
res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_ACTALL, eof_time, false, true, &resp_len);
@ -1308,7 +1308,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3
// send Identify
start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
iclass_send_as_reader(identify, 1, &start_time, eof_time);
iclass_send_as_reader(identify, 1, &start_time, eof_time, shallow_mod);
// expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC
res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true, &resp_len);
@ -1320,7 +1320,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3
// select the card
start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
iclass_send_as_reader(select, sizeof(select), &start_time, eof_time);
iclass_send_as_reader(select, sizeof(select), &start_time, eof_time, shallow_mod);
// expect a 10-byte response here, 8 byte CSN and 2 byte CRC
res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true, &resp_len);
@ -1332,7 +1332,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3
// card selected, now read config (block1) (only 8 bytes no CRC)
start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
iclass_send_as_reader(read_conf, sizeof(read_conf), &start_time, eof_time);
iclass_send_as_reader(read_conf, sizeof(read_conf), &start_time, eof_time, shallow_mod);
// expect a 8-byte response here
res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true, &resp_len);
@ -1350,7 +1350,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3
// read App Issuer Area block 5
start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
iclass_send_as_reader(read_aia, sizeof(read_aia), &start_time, eof_time);
iclass_send_as_reader(read_aia, sizeof(read_aia), &start_time, eof_time, shallow_mod);
// expect a 10-byte response here
res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true, &resp_len);
@ -1364,7 +1364,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3
// card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC)
start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
iclass_send_as_reader(read_check_cc, sizeof(read_check_cc), &start_time, eof_time);
iclass_send_as_reader(read_check_cc, sizeof(read_check_cc), &start_time, eof_time, shallow_mod);
// expect a 8-byte response here
res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true, &resp_len);
@ -1386,7 +1386,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3
read_aia[3] = 0x10;
start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
iclass_send_as_reader(read_aia, sizeof(read_aia), &start_time, eof_time);
iclass_send_as_reader(read_aia, sizeof(read_aia), &start_time, eof_time, shallow_mod);
// expect a 10-byte response here
res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true, &resp_len);
@ -1402,9 +1402,9 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3
return true;
}
bool select_iclass_tag(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time) {
bool select_iclass_tag(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time, bool shallow_mod) {
uint8_t result = 0;
return select_iclass_tag_ex(hdr, use_credit_key, eof_time, &result);
return select_iclass_tag_ex(hdr, use_credit_key, eof_time, &result, shallow_mod);
}
// Reader iClass Anticollission
@ -1413,6 +1413,7 @@ void ReaderIClass(uint8_t flags) {
// flag to use credit key
bool use_credit_key = ((flags & FLAG_ICLASS_READER_CREDITKEY) == FLAG_ICLASS_READER_CREDITKEY);
bool shallow_mod = (flags & FLAG_ICLASS_READER_SHALLOW_MOD);
if ((flags & FLAG_ICLASS_READER_INIT) == FLAG_ICLASS_READER_INIT) {
Iso15693InitReader();
@ -1427,7 +1428,7 @@ void ReaderIClass(uint8_t flags) {
uint32_t eof_time = 0;
picopass_hdr_t hdr = {0};
if (select_iclass_tag_ex(&hdr, use_credit_key, &eof_time, &res) == false) {
if (select_iclass_tag_ex(&hdr, use_credit_key, &eof_time, &res, shallow_mod) == false) {
reply_ng(CMD_HF_ICLASS_READER, PM3_ERFTRANS, NULL, 0);
goto out;
}
@ -1498,7 +1499,7 @@ bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr_t *hdr, ui
cmd_check[7] = pmac[2];
cmd_check[8] = pmac[3];
}
return iclass_send_cmd_with_retries(cmd_check, sizeof(cmd_check), resp_auth, sizeof(resp_auth), 4, 2, start_time, ICLASS_READER_TIMEOUT_OTHERS, eof_time);
return iclass_send_cmd_with_retries(cmd_check, sizeof(cmd_check), resp_auth, sizeof(resp_auth), 4, 2, start_time, ICLASS_READER_TIMEOUT_OTHERS, eof_time, payload->shallow_mod);
}
@ -1516,6 +1517,8 @@ void iClass_Authentication_fast(iclass_chk_t *p) {
return;
}
bool shallow_mod = p->shallow_mod;
uint8_t check[9] = { ICLASS_CMD_CHECK };
uint8_t resp[ICLASS_BUFFER_SIZE] = {0};
uint8_t readcheck_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 };
@ -1537,7 +1540,7 @@ void iClass_Authentication_fast(iclass_chk_t *p) {
bool isOK = false;
uint32_t start_time = 0, eof_time = 0;
if (select_iclass_tag(&hdr, p->use_credit_key, &eof_time) == false)
if (select_iclass_tag(&hdr, p->use_credit_key, &eof_time, shallow_mod) == false)
goto out;
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
@ -1566,14 +1569,14 @@ void iClass_Authentication_fast(iclass_chk_t *p) {
check[8] = keys[i].mac[3];
// expect 4bytes, 3 retries times..
isOK = iclass_send_cmd_with_retries(check, sizeof(check), resp, sizeof(resp), 4, 2, &start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time);
isOK = iclass_send_cmd_with_retries(check, sizeof(check), resp, sizeof(resp), 4, 2, &start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time, shallow_mod);
if (isOK)
goto out;
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
// Auth Sequence MUST begin with reading e-purse. (block2)
// Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC)
iclass_send_as_reader(readcheck_cc, sizeof(readcheck_cc), &start_time, &eof_time);
iclass_send_as_reader(readcheck_cc, sizeof(readcheck_cc), &start_time, &eof_time, shallow_mod);
LED_B_OFF();
}
@ -1586,11 +1589,11 @@ out:
// Tries to read block.
// retries 3times.
// reply 8 bytes block
bool iclass_read_block(uint16_t blockno, uint8_t *data, uint32_t *start_time, uint32_t *eof_time) {
bool iclass_read_block(uint16_t blockno, uint8_t *data, uint32_t *start_time, uint32_t *eof_time, bool shallow_mod) {
uint8_t resp[10];
uint8_t c[] = {ICLASS_CMD_READ_OR_IDENTIFY, blockno, 0x00, 0x00};
AddCrc(c + 1, 1);
bool isOK = iclass_send_cmd_with_retries(c, sizeof(c), resp, sizeof(resp), 10, 2, start_time, ICLASS_READER_TIMEOUT_OTHERS, eof_time);
bool isOK = iclass_send_cmd_with_retries(c, sizeof(c), resp, sizeof(resp), 10, 2, start_time, ICLASS_READER_TIMEOUT_OTHERS, eof_time, shallow_mod);
if (isOK)
memcpy(data, resp, 8);
return isOK;
@ -1602,6 +1605,7 @@ bool iclass_read_block(uint16_t blockno, uint8_t *data, uint32_t *start_time, ui
void iClass_ReadBlock(uint8_t *msg) {
iclass_auth_req_t *payload = (iclass_auth_req_t *)msg;
bool shallow_mod = payload->shallow_mod;
iclass_readblock_resp_t response = { .isOK = true };
memset(response.data, 0, sizeof(response.data));
@ -1614,7 +1618,7 @@ void iClass_ReadBlock(uint8_t *msg) {
// select tag.
uint32_t eof_time = 0;
picopass_hdr_t hdr = {0};
bool res = select_iclass_tag(&hdr, payload->use_credit_key, &eof_time);
bool res = select_iclass_tag(&hdr, payload->use_credit_key, &eof_time, shallow_mod);
if (res == false) {
if (payload->send_reply) {
response.isOK = res;
@ -1642,7 +1646,7 @@ void iClass_ReadBlock(uint8_t *msg) {
// read data
uint8_t resp[10];
res = iclass_send_cmd_with_retries(cmd_read, sizeof(cmd_read), resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time);
res = iclass_send_cmd_with_retries(cmd_read, sizeof(cmd_read), resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time, shallow_mod);
if (res) {
memcpy(response.data, resp, sizeof(response.data));
if (payload->send_reply) {
@ -1670,6 +1674,7 @@ void iClass_Dump(uint8_t *msg) {
iclass_dump_req_t *cmd = (iclass_dump_req_t *)msg;
iclass_auth_req_t *req = &cmd->req;
bool shallow_mod = req->shallow_mod;
uint8_t *dataout = BigBuf_malloc(ICLASS_16KS_SIZE);
if (dataout == NULL) {
@ -1689,7 +1694,7 @@ void iClass_Dump(uint8_t *msg) {
picopass_hdr_t hdr = {0};
memset(&hdr, 0xff, sizeof(picopass_hdr_t));
bool res = select_iclass_tag(&hdr, req->use_credit_key, &eof_time);
bool res = select_iclass_tag(&hdr, req->use_credit_key, &eof_time, shallow_mod);
if (res == false) {
if (req->send_reply) {
reply_ng(CMD_HF_ICLASS_DUMP, PM3_ETIMEOUT, NULL, 0);
@ -1724,7 +1729,7 @@ void iClass_Dump(uint8_t *msg) {
uint8_t c[] = {ICLASS_CMD_READ_OR_IDENTIFY, i, 0x00, 0x00};
AddCrc(c + 1, 1);
res = iclass_send_cmd_with_retries(c, sizeof(c), resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time);
res = iclass_send_cmd_with_retries(c, sizeof(c), resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time, shallow_mod);
if (res) {
memcpy(dataout + (8 * i), resp, 8);
} else {
@ -1759,7 +1764,7 @@ void iClass_Dump(uint8_t *msg) {
BigBuf_free();
}
static bool iclass_writeblock_ext(uint8_t blockno, uint8_t *data, uint8_t *mac, bool use_mac) {
static bool iclass_writeblock_ext(uint8_t blockno, uint8_t *data, uint8_t *mac, bool use_mac, bool shallow_mod) {
// write command: cmd, 1 blockno, 8 data, 4 mac
uint8_t write[14] = { 0x80 | ICLASS_CMD_UPDATE, blockno };
@ -1775,7 +1780,7 @@ static bool iclass_writeblock_ext(uint8_t blockno, uint8_t *data, uint8_t *mac,
uint8_t resp[10] = {0};
uint32_t eof_time = 0, start_time = 0;
bool isOK = iclass_send_cmd_with_retries(write, write_len, resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_UPDATE, &eof_time);
bool isOK = iclass_send_cmd_with_retries(write, write_len, resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_UPDATE, &eof_time, shallow_mod);
if (isOK == false) {
return false;
}
@ -1807,6 +1812,7 @@ void iClass_WriteBlock(uint8_t *msg) {
LED_A_ON();
iclass_writeblock_req_t *payload = (iclass_writeblock_req_t *)msg;
bool shallow_mod = payload->req.shallow_mod;
uint8_t write[14] = { 0x80 | ICLASS_CMD_UPDATE, payload->req.blockno };
uint8_t write_len = 14;
@ -1816,7 +1822,7 @@ void iClass_WriteBlock(uint8_t *msg) {
// select tag.
uint32_t eof_time = 0;
picopass_hdr_t hdr = {0};
uint8_t res = select_iclass_tag(&hdr, payload->req.use_credit_key, &eof_time);
uint8_t res = select_iclass_tag(&hdr, payload->req.use_credit_key, &eof_time, shallow_mod);
if (res == false) {
goto out;
}
@ -1871,7 +1877,7 @@ void iClass_WriteBlock(uint8_t *msg) {
uint8_t tries = 3;
while (tries-- > 0) {
iclass_send_as_reader(write, write_len, &start_time, &eof_time);
iclass_send_as_reader(write, write_len, &start_time, &eof_time, shallow_mod);
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
res = false;
@ -1939,6 +1945,8 @@ void iClass_Restore(iclass_restore_req_t *msg) {
return;
}
bool shallow_mod = msg->req.shallow_mod;
LED_A_ON();
Iso15693InitReader();
@ -1947,7 +1955,7 @@ void iClass_Restore(iclass_restore_req_t *msg) {
picopass_hdr_t hdr = {0};
// select
bool res = select_iclass_tag(&hdr, msg->req.use_credit_key, &eof_time);
bool res = select_iclass_tag(&hdr, msg->req.use_credit_key, &eof_time, shallow_mod);
if (res == false) {
goto out;
}
@ -1988,7 +1996,7 @@ void iClass_Restore(iclass_restore_req_t *msg) {
}
// data + mac
if (iclass_writeblock_ext(item.blockno, item.data, mac, use_mac)) {
if (iclass_writeblock_ext(item.blockno, item.data, mac, use_mac, shallow_mod)) {
Dbprintf("Write block [%3d/0x%02X] " _GREEN_("successful"), item.blockno, item.blockno);
written++;
} else {

View file

@ -38,8 +38,8 @@ void iClass_Authentication_fast(iclass_chk_t *p);
bool iclass_auth(iclass_auth_req_t *payload, uint8_t *out);
void iClass_ReadBlock(uint8_t *msg);
bool iclass_read_block(uint16_t blockno, uint8_t *data, uint32_t *start_time, uint32_t *eof_time);
bool iclass_read_block(uint16_t blockno, uint8_t *data, uint32_t *start_time, uint32_t *eof_time, bool shallow_mod);
bool select_iclass_tag(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time);
bool select_iclass_tag(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time, bool shallow_mod);
bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr_t *hdr, uint32_t *start_time, uint32_t *eof_time, uint8_t *mac_out);
#endif

View file

@ -262,9 +262,9 @@ void CodeIso15693AsTag(const uint8_t *cmd, size_t len) {
}
// Transmit the command (to the tag) that was placed in cmd[].
void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time) {
void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time, bool shallow_mod) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_FULL_MOD);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | (shallow_mod ? FPGA_HF_READER_MODE_SEND_SHALLOW_MOD : FPGA_HF_READER_MODE_SEND_FULL_MOD));
if (*start_time < DELAY_ARM_TO_TAG) {
*start_time = DELAY_ARM_TO_TAG;
@ -1585,7 +1585,7 @@ void AcquireRawAdcSamplesIso15693(void) {
tosend_t *ts = get_tosend();
uint32_t start_time = 0;
TransmitTo15693Tag(ts->buf, ts->max, &start_time);
TransmitTo15693Tag(ts->buf, ts->max, &start_time, false);
// wait for last transfer to complete
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)) ;
@ -1899,7 +1899,7 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t
}
tosend_t *ts = get_tosend();
TransmitTo15693Tag(ts->buf, ts->max, &start_time);
TransmitTo15693Tag(ts->buf, ts->max, &start_time, false);
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
*resp_len = 0;
@ -1922,7 +1922,7 @@ int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, ui
CodeIso15693AsReaderEOF();
tosend_t *ts = get_tosend();
TransmitTo15693Tag(ts->buf, ts->max, &start_time);
TransmitTo15693Tag(ts->buf, ts->max, &start_time, false);
uint32_t end_time = start_time + 32 * (8 * ts->max - 4); // subtract the 4 padding bits after EOF
LogTrace_ISO15693(NULL, 0, (start_time * 4), (end_time * 4), NULL, true);

View file

@ -40,7 +40,7 @@ void CodeIso15693AsTag(const uint8_t *cmd, size_t len);
void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t *start_time, uint32_t slot_time, bool slow);
int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eof_time);
void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time);
void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time, bool shallow_mod);
int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeout, uint32_t *eof_time, bool fsk, bool recv_speed, uint16_t *resp_len);
//void RecordRawAdcSamplesIso15693(void);

View file

@ -1247,6 +1247,14 @@
"Description": "PIV End Point Applet. Last 2 bytes designate version",
"Type": ""
},
{
"AID": "A000000308000010000100",
"Vendor": "National Institute of Standards and Technology",
"Country": "United States",
"Name": "Personal Identity Verification (PIV) / ID-ONE PIV BIO",
"Description": "PIV End Point Applet. Last 2 bytes designate version",
"Type": ""
},
{
"AID": "A00000031510100528",
"Vendor": "Currence Holding/PIN BV",

View file

@ -123,7 +123,7 @@ int CmdHFSearch(const char *Cmd) {
PROMPT_CLEARLINE;
PrintAndLogEx(INPLACE, " Searching for iCLASS / PicoPass tag...");
if (IfPm3Iclass()) {
if (read_iclass_csn(false, false) == PM3_SUCCESS) {
if (read_iclass_csn(false, false, false) == PM3_SUCCESS) {
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iCLASS tag / PicoPass tag") " found\n");
res = PM3_SUCCESS;
}

View file

@ -67,7 +67,7 @@ typedef struct {
// structure and database for uid -> tagtype lookups
typedef struct {
uint64_t uid;
int mask; // how many MSB bits used
uint64_t mask; // how many MSB bits used, or mask itself if larger than 64
const char *desc;
} productName_t;
@ -90,17 +90,22 @@ static const productName_t uidmapping[] = {
// E0 04 xx
// 04 = Manufacturer code (Philips/NXP)
// XX = IC id (Chip ID Family)
//I-Code SLI SL2 ICS20 [IC id = 01]
//I-Code SLI-S [IC id = 02]
//I-Code SLI-L [IC id = 03]
//I-Code SLIX [IC id = 01 + bit36 set to 1 (starting from bit0 - different from normal SLI)]
//I-Code SLI SL2 ICS20 [IC id = 01 + bit35 set to 0 + bit36 set to 0]
//I-Code SLIX [IC id = 01 + bit35 set to 0 + bit36 set to 1]
//I-Code SLIX2 [IC id = 01 + bit35 set to 1 + bit36 set to 0]
//I-Code SLI-S [IC id = 02 + bit36 set to 0]
//I-Code SLIX-S [IC id = 02 + bit36 set to 1]
//I-Code SLI-L [IC id = 03 + bit36 set to 0]
//I-Code SLIX-L [IC id = 03 + bit36 set to 1]
{ 0xE004000000000000LL, 16, "NXP Semiconductors Germany (Philips)" },
{ 0xE004010000000000LL, 24, "NXP(Philips); IC SL2 ICS20/ICS21(SLI) ICS2002/ICS2102(SLIX) ICS2602(SLIX2)" },
{ 0xE004020000000000LL, 24, "NXP(Philips); IC SL2 ICS53/ICS54(SLI-S) ICS5302/ICS5402(SLIX-S)" },
{ 0xE004030000000000LL, 24, "NXP(Philips); IC SL2 ICS50/ICS51(SLI-L) ICS5002/ICS5102(SLIX-L)" },
{ 0xE004010000000000LL, 0xFFFFFF1800000000LL, "NXP(Philips); IC SL2 ICS20/ICS21(SLI)" },
{ 0xE004011000000000LL, 0xFFFFFF1800000000LL, "NXP(Philips); IC SL2 ICS2002/ICS2102(SLIX)" },
{ 0xE004010800000000LL, 0xFFFFFF1800000000LL, "NXP(Philips); IC SL2 ICS2602(SLIX2)" },
{ 0xE004020000000000LL, 0xFFFFFF1000000000LL, "NXP(Philips); IC SL2 ICS53/ICS54(SLI-S)" },
{ 0xE004021000000000LL, 0xFFFFFF1000000000LL, "NXP(Philips); ICS5302/ICS5402(SLIX-S)" },
{ 0xE004030000000000LL, 0xFFFFFF1000000000LL, "NXP(Philips); IC SL2 ICS50/ICS51(SLI-L)" },
{ 0xE004031000000000LL, 0xFFFFFF1000000000LL, "NXP(Philips); ICS5002/ICS5102(SLIX-L)" },
// E0 05 XX .. .. ..
// 05 = Manufacturer code (Infineon)
@ -364,7 +369,11 @@ static const char *getTagInfo_15(uint8_t *uid) {
int i = 0, best = -1;
memcpy(&myuid, uid, sizeof(uint64_t));
while (uidmapping[i].mask > 0) {
mask = (~0ULL) << (64 - uidmapping[i].mask);
if (uidmapping[i].mask > 64) {
mask = uidmapping[i].mask;
} else {
mask = (~0ULL) << (64 - uidmapping[i].mask);
}
if ((myuid & mask) == uidmapping[i].uid) {
if (best == -1) {
best = i;

View file

@ -285,7 +285,7 @@ static int generate_config_card(const iclass_config_card_item_t *o, uint8_t *ke
// get header from card
PrintAndLogEx(INFO, "trying to read a card..");
int res = read_iclass_csn(false, false);
int res = read_iclass_csn(false, false, false);
if (res == PM3_SUCCESS) {
cc = &iclass_last_known_card;
// calc diversified key for selected card
@ -905,19 +905,25 @@ static int CmdHFiClassInfo(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool shallow_mod = arg_get_lit(ctx, 1);
CLIParserFree(ctx);
return info_iclass();
return info_iclass(shallow_mod);
}
int read_iclass_csn(bool loop, bool verbose) {
int read_iclass_csn(bool loop, bool verbose, bool shallow_mod) {
iclass_card_select_t payload = {
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE)
};
if (shallow_mod) {
payload.flags |= FLAG_ICLASS_READER_SHALLOW_MOD;
}
int res = PM3_SUCCESS;
do {
@ -973,17 +979,19 @@ static int CmdHFiClassReader(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("@", NULL, "optional - continuous reader mode"),
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool cm = arg_get_lit(ctx, 1);
bool shallow_mod = arg_get_lit(ctx, 2);
CLIParserFree(ctx);
if (cm) {
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
}
return read_iclass_csn(cm, true);
return read_iclass_csn(cm, true, shallow_mod);
}
static int CmdHFiClassELoad(const char *Cmd) {
@ -1547,12 +1555,16 @@ static int CmdHFiClassEncryptBlk(const char *Cmd) {
return PM3_SUCCESS;
}
static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool verbose) {
static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool verbose, bool shallow_mod) {
iclass_card_select_t payload = {
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE)
};
if (shallow_mod) {
payload.flags |= FLAG_ICLASS_READER_SHALLOW_MOD;
}
clearCommandBuffer();
PacketResponseNG resp;
SendCommandNG(CMD_HF_ICLASS_READER, (uint8_t *)&payload, sizeof(iclass_card_select_t));
@ -1608,6 +1620,7 @@ static int CmdHFiClassDump(const char *Cmd) {
arg_lit0(NULL, "nr", "replay of NR/MAC"),
arg_lit0("z", "dense", "dense dump output style"),
arg_lit0(NULL, "force", "force unsecure card read"),
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -1693,6 +1706,7 @@ static int CmdHFiClassDump(const char *Cmd) {
bool use_replay = arg_get_lit(ctx, 8);
bool dense_output = g_session.dense_output || arg_get_lit(ctx, 9);
bool force = arg_get_lit(ctx, 10);
bool shallow_mod = arg_get_lit(ctx, 11);
CLIParserFree(ctx);
@ -1711,6 +1725,11 @@ static int CmdHFiClassDump(const char *Cmd) {
iclass_card_select_t payload_rdr = {
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE)
};
if (shallow_mod) {
payload_rdr.flags |= FLAG_ICLASS_READER_SHALLOW_MOD;
}
clearCommandBuffer();
PacketResponseNG resp;
SendCommandNG(CMD_HF_ICLASS_READER, (uint8_t *)&payload_rdr, sizeof(iclass_card_select_t));
@ -1790,6 +1809,7 @@ static int CmdHFiClassDump(const char *Cmd) {
.req.use_replay = use_replay,
.req.send_reply = true,
.req.do_auth = auth,
.req.shallow_mod = shallow_mod,
.end_block = app_limit1,
};
memcpy(payload.req.key, key, 8);
@ -1950,7 +1970,7 @@ write_dump:
return PM3_SUCCESS;
}
static int iclass_write_block(uint8_t blockno, uint8_t *bldata, uint8_t *macdata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool replay, bool verbose, bool use_secure_pagemode) {
static int iclass_write_block(uint8_t blockno, uint8_t *bldata, uint8_t *macdata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool replay, bool verbose, bool use_secure_pagemode, bool shallow_mod) {
iclass_writeblock_req_t payload = {
.req.use_raw = rawkey,
@ -1960,6 +1980,7 @@ static int iclass_write_block(uint8_t blockno, uint8_t *bldata, uint8_t *macdata
.req.blockno = blockno,
.req.send_reply = true,
.req.do_auth = use_secure_pagemode,
.req.shallow_mod = shallow_mod,
};
memcpy(payload.req.key, KEY, 8);
memcpy(payload.data, bldata, sizeof(payload.data));
@ -2004,6 +2025,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) {
arg_lit0(NULL, "raw", "no computations applied to key"),
arg_lit0(NULL, "nr", "replay of NR/MAC"),
arg_lit0("v", "verbose", "verbose output"),
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -2072,6 +2094,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) {
bool rawkey = arg_get_lit(ctx, 8);
bool use_replay = arg_get_lit(ctx, 9);
bool verbose = arg_get_lit(ctx, 10);
bool shallow_mod = arg_get_lit(ctx, 11);
CLIParserFree(ctx);
@ -2080,7 +2103,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) {
return PM3_EINVARG;
}
int isok = iclass_write_block(blockno, data, mac, key, use_credit_key, elite, rawkey, use_replay, verbose, auth);
int isok = iclass_write_block(blockno, data, mac, key, use_credit_key, elite, rawkey, use_replay, verbose, auth, shallow_mod);
switch (isok) {
case PM3_SUCCESS:
PrintAndLogEx(SUCCESS, "Wrote block %3d/0x%02X successful", blockno, blockno);
@ -2116,6 +2139,7 @@ static int CmdHFiClassRestore(const char *Cmd) {
arg_lit0(NULL, "elite", "elite computations applied to key"),
arg_lit0(NULL, "raw", "no computations applied to key"),
arg_lit0("v", "verbose", "verbose output"),
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -2165,6 +2189,7 @@ static int CmdHFiClassRestore(const char *Cmd) {
bool elite = arg_get_lit(ctx, 7);
bool rawkey = arg_get_lit(ctx, 8);
bool verbose = arg_get_lit(ctx, 9);
bool shallow_mod = arg_get_lit(ctx, 10);
CLIParserFree(ctx);
@ -2215,6 +2240,7 @@ static int CmdHFiClassRestore(const char *Cmd) {
payload->req.blockno = startblock;
payload->req.send_reply = true;
payload->req.do_auth = true;
payload->req.shallow_mod = shallow_mod;
memcpy(payload->req.key, key, 8);
payload->item_cnt = (endblock - startblock + 1);
@ -2268,7 +2294,7 @@ static int CmdHFiClassRestore(const char *Cmd) {
return resp.status;
}
static int iclass_read_block(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool replay, bool verbose, bool auth, uint8_t *out) {
static int iclass_read_block(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool replay, bool verbose, bool auth, bool shallow_mod, uint8_t *out) {
iclass_auth_req_t payload = {
.use_raw = rawkey,
@ -2278,6 +2304,7 @@ static int iclass_read_block(uint8_t *KEY, uint8_t blockno, uint8_t keyType, boo
.blockno = blockno,
.send_reply = true,
.do_auth = auth,
.shallow_mod = shallow_mod,
};
memcpy(payload.key, KEY, 8);
@ -2331,6 +2358,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) {
arg_lit0(NULL, "raw", "no computations applied to key"),
arg_lit0(NULL, "nr", "replay of NR/MAC"),
arg_lit0("v", "verbose", "verbose output"),
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -2381,6 +2409,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) {
bool rawkey = arg_get_lit(ctx, 6);
bool use_replay = arg_get_lit(ctx, 7);
bool verbose = arg_get_lit(ctx, 8);
bool shallow_mod = arg_get_lit(ctx, 9);
CLIParserFree(ctx);
@ -2400,7 +2429,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) {
}
uint8_t data[8] = {0};
int res = iclass_read_block(key, blockno, keyType, elite, rawkey, use_replay, verbose, auth, data);
int res = iclass_read_block(key, blockno, keyType, elite, rawkey, use_replay, verbose, auth, shallow_mod, data);
if (res != PM3_SUCCESS)
return res;
@ -2975,7 +3004,7 @@ static int CmdHFiClassCalcNewKey(const char *Cmd) {
if (givenCSN == false) {
uint8_t CCNR[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
if (select_only(csn, CCNR, true) == false) {
if (select_only(csn, CCNR, true, false) == false) {
DropField();
return PM3_ESOFT;
}
@ -3173,6 +3202,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) {
arg_lit0(NULL, "credit", "key is assumed to be the credit key"),
arg_lit0(NULL, "elite", "elite computations applied to key"),
arg_lit0(NULL, "raw", "no computations applied to key (raw)"),
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -3184,6 +3214,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) {
bool use_credit_key = arg_get_lit(ctx, 2);
bool use_elite = arg_get_lit(ctx, 3);
bool use_raw = arg_get_lit(ctx, 4);
bool shallow_mod = arg_get_lit(ctx, 5);
CLIParserFree(ctx);
@ -3213,7 +3244,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) {
bool got_csn = false;
for (uint8_t i = 0; i < ICLASS_AUTH_RETRY; i++) {
got_csn = select_only(CSN, CCNR, false);
got_csn = select_only(CSN, CCNR, false, shallow_mod);
if (got_csn == false)
PrintAndLogEx(WARNING, "one more try");
else
@ -3295,6 +3326,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) {
}
packet->use_credit_key = use_credit_key;
packet->count = curr_chunk_cnt;
packet->shallow_mod = shallow_mod;
// copy chunk of pre calculated macs to packet
memcpy(packet->items, (pre + chunk_offset), (4 * curr_chunk_cnt));
@ -3799,6 +3831,7 @@ static int CmdHFiClassEncode(const char *Cmd) {
arg_u64_0(NULL, "fc", "<dec>", "facility code"),
arg_u64_0(NULL, "cn", "<dec>", "card number"),
arg_str0("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -3843,6 +3876,8 @@ static int CmdHFiClassEncode(const char *Cmd) {
int format_len = 0;
CLIParamStrToBuf(arg_get_str(ctx, 9), (uint8_t *)format, sizeof(format), &format_len);
bool shallow_mod = arg_get_lit(ctx, 10);
CLIParserFree(ctx);
if ((rawkey + elite) > 1) {
@ -3964,7 +3999,7 @@ static int CmdHFiClassEncode(const char *Cmd) {
int isok = PM3_SUCCESS;
// write
for (uint8_t i = 0; i < 4; i++) {
isok = iclass_write_block(6 + i, credential + (i * 8), NULL, key, use_credit_key, elite, rawkey, false, false, auth);
isok = iclass_write_block(6 + i, credential + (i * 8), NULL, key, use_credit_key, elite, rawkey, false, false, auth, shallow_mod);
switch (isok) {
case PM3_SUCCESS:
PrintAndLogEx(SUCCESS, "Write block %d/0x0%x ( " _GREEN_("ok") " ) --> " _YELLOW_("%s"), 6 + i, 6 + i, sprint_hex_inrow(credential + (i * 8), 8));
@ -4135,11 +4170,16 @@ int CmdHFiClass(const char *Cmd) {
// DESFIRE| | |
//}
int info_iclass(void) {
int info_iclass(bool shallow_mod) {
iclass_card_select_t payload = {
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE)
};
if (shallow_mod) {
payload.flags |= FLAG_ICLASS_READER_SHALLOW_MOD;
}
clearCommandBuffer();
PacketResponseNG resp;
SendCommandNG(CMD_HF_ICLASS_READER, (uint8_t *)&payload, sizeof(iclass_card_select_t));

View file

@ -24,8 +24,8 @@
int CmdHFiClass(const char *Cmd);
int info_iclass(void);
int read_iclass_csn(bool loop, bool verbose);
int info_iclass(bool shallow_mod);
int read_iclass_csn(bool loop, bool verbose, bool shallow_mod);
void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize, bool dense_output);
void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite);

View file

@ -41,6 +41,7 @@
#include "generator.h"
#include "cliparser.h"
#include "cmdhw.h"
#include "util.h"
//////////////// 4205 / 4305 commands
@ -1996,8 +1997,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
const char *cmdText;
char dataText[100];
char blkAddr[4];
char bits[80];
int i, bitidx;
int i;
int ZeroWidth; // 32-42 "1" is 32
int CycleWidth;
size_t pulseSamples;
@ -2018,6 +2018,10 @@ int CmdEM4x05Sniff(const char *Cmd) {
PrintAndLogEx(SUCCESS, "offset | Command | Data | blk | raw");
PrintAndLogEx(SUCCESS, "-------+-------------+----------+-----+------------------------------------------------------------");
smartbuf bits = { 0 };
bits.ptr = malloc(EM4X05_BITS_BUFSIZE);
bits.size = EM4X05_BITS_BUFSIZE;
bits.idx = 0;
size_t idx = 0;
// loop though sample buffer
while (idx < g_GraphTraceLen) {
@ -2037,8 +2041,8 @@ int CmdEM4x05Sniff(const char *Cmd) {
if (ZeroWidth <= 50) {
pktOffset -= ZeroWidth;
memset(bits, 0x00, sizeof(bits));
bitidx = 0;
memset(bits.ptr, 0, bits.size);
bits.idx = 0;
while ((idx < g_GraphTraceLen) && !eop) {
CycleWidth = idx;
@ -2047,7 +2051,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
CycleWidth = idx - CycleWidth;
if ((CycleWidth > 300) || (CycleWidth < (ZeroWidth - 5))) { // to long or too short
eop = true;
bits[bitidx++] = '0'; // Append last zero from the last bit find
sb_append_char(&bits, '0'); // Append last zero from the last bit find
cmdText = "";
// EM4305 command lengths
@ -2059,76 +2063,77 @@ int CmdEM4x05Sniff(const char *Cmd) {
// -> disable 1010 11111111 0 11111111 0 11111111 0 11111111 0 00000000 0
// Check to see if we got the leading 0
if (((strncmp(bits, "00011", 5) == 0) && (bitidx == 50)) ||
((strncmp(bits, "00101", 5) == 0) && (bitidx == 57)) ||
((strncmp(bits, "01001", 5) == 0) && (bitidx == 12)) ||
((strncmp(bits, "01100", 5) == 0) && (bitidx == 50)) ||
((strncmp(bits, "01010", 5) == 0) && (bitidx == 50))) {
memmove(bits, &bits[1], bitidx - 1);
bitidx--;
if (((strncmp(bits.ptr, "00011", 5) == 0) && (bits.idx == 50)) ||
((strncmp(bits.ptr, "00101", 5) == 0) && (bits.idx == 57)) ||
((strncmp(bits.ptr, "01001", 5) == 0) && (bits.idx == 12)) ||
((strncmp(bits.ptr, "01100", 5) == 0) && (bits.idx == 50)) ||
((strncmp(bits.ptr, "01010", 5) == 0) && (bits.idx == 50))) {
memmove(bits.ptr, &bits.ptr[1], bits.idx - 1);
bits.idx--;
PrintAndLogEx(INFO, "Trim leading 0");
}
bits[bitidx] = 0;
sb_append_char(&bits, 0);
bits.idx--;
// logon
if ((strncmp(bits, "0011", 4) == 0) && (bitidx == 49)) {
if ((strncmp(bits.ptr, "0011", 4) == 0) && (bits.idx == 49)) {
haveData = true;
pwd = true;
cmdText = "Logon";
strncpy(blkAddr, " ", sizeof(blkAddr));
tmpValue = em4x05_Sniff_GetBlock(&bits[4], fwd);
tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[4], fwd);
snprintf(dataText, sizeof(dataText), "%08X", tmpValue);
}
// write
if ((strncmp(bits, "0101", 4) == 0) && (bitidx == 56)) {
if ((strncmp(bits.ptr, "0101", 4) == 0) && (bits.idx == 56)) {
haveData = true;
cmdText = "Write";
tmpValue = (bits[4] - '0') + ((bits[5] - '0') << 1) + ((bits[6] - '0') << 2) + ((bits[7] - '0') << 3);
tmpValue = (bits.ptr[4] - '0') + ((bits.ptr[5] - '0') << 1) + ((bits.ptr[6] - '0') << 2) + ((bits.ptr[7] - '0') << 3);
snprintf(blkAddr, sizeof(blkAddr), "%u", tmpValue);
if (tmpValue == 2) {
pwd = true;
}
tmpValue = em4x05_Sniff_GetBlock(&bits[11], fwd);
tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd);
snprintf(dataText, sizeof(dataText), "%08X", tmpValue);
}
// read
if ((strncmp(bits, "1001", 4) == 0) && (bitidx == 11)) {
if ((strncmp(bits.ptr, "1001", 4) == 0) && (bits.idx == 11)) {
haveData = true;
pwd = false;
cmdText = "Read";
tmpValue = (bits[4] - '0') + ((bits[5] - '0') << 1) + ((bits[6] - '0') << 2) + ((bits[7] - '0') << 3);
tmpValue = (bits.ptr[4] - '0') + ((bits.ptr[5] - '0') << 1) + ((bits.ptr[6] - '0') << 2) + ((bits.ptr[7] - '0') << 3);
snprintf(blkAddr, sizeof(blkAddr), "%u", tmpValue);
strncpy(dataText, " ", sizeof(dataText));
}
// protect
if ((strncmp(bits, "1100", 4) == 0) && (bitidx == 49)) {
if ((strncmp(bits.ptr, "1100", 4) == 0) && (bits.idx == 49)) {
haveData = true;
pwd = false;
cmdText = "Protect";
strncpy(blkAddr, " ", sizeof(blkAddr));
tmpValue = em4x05_Sniff_GetBlock(&bits[11], fwd);
tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd);
snprintf(dataText, sizeof(dataText), "%08X", tmpValue);
}
// disable
if ((strncmp(bits, "1010", 4) == 0) && (bitidx == 49)) {
if ((strncmp(bits.ptr, "1010", 4) == 0) && (bits.idx == 49)) {
haveData = true;
pwd = false;
cmdText = "Disable";
strncpy(blkAddr, " ", sizeof(blkAddr));
tmpValue = em4x05_Sniff_GetBlock(&bits[11], fwd);
tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd);
snprintf(dataText, sizeof(dataText), "%08X", tmpValue);
}
// bits[bitidx] = 0;
} else {
i = (CycleWidth - ZeroWidth) / 28;
bits[bitidx++] = '0';
sb_append_char(&bits, '0');
for (int ii = 0; ii < i; ii++) {
bits[bitidx++] = '1';
sb_append_char(&bits, '1');
}
}
}
@ -2139,11 +2144,13 @@ int CmdEM4x05Sniff(const char *Cmd) {
// Print results
if (haveData) { //&& (minWidth > 1) && (maxWidth > minWidth)){
if (pwd)
PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _YELLOW_("%8s")" | " _YELLOW_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits);
PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _YELLOW_("%8s")" | " _YELLOW_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits.ptr);
else
PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _GREEN_("%8s")" | " _GREEN_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits);
PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _GREEN_("%8s")" | " _GREEN_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits.ptr);
}
}
free(bits.ptr);
bits.ptr = NULL;
// footer
PrintAndLogEx(SUCCESS, "---------------------------------------------------------------------------------------------------");

View file

@ -27,6 +27,8 @@
#define EM4305_PROT2_BLOCK 15
#define EM4469_PROT_BLOCK 3
#define EM4X05_BITS_BUFSIZE 128
// config blocks
#define EM4305_DEFAULT_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_MANCHESTER | EM4x05_SET_NUM_BLOCKS(4) ) // ASK/MAN , data rate 32, 4 data blocks
//#define EM4305_DEFAULT_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_BIPHASE | EM4x05_SET_NUM_BLOCKS(4) ) // ASK/BIPHASE , data rate 32, 4 data blocks

View file

@ -573,7 +573,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
//2 Not crc-command
//--- Draw the data column
char line[18][140] = {{0}};
char line[18][160] = {{0}};
if (data_len == 0) {
if (protocol == ICLASS && duration == 2048) {
@ -633,8 +633,9 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
}
uint8_t crc_format_string_offset = 0;
if (markCRCBytes) {
if (markCRCBytes && data_len > 2) {
//CRC-command
if (((protocol == PROTO_HITAG1) || (protocol == PROTO_HITAGS)) && (data_len > 1)) {
// Note that UID REQUEST response has no CRC, but we don't know
@ -647,6 +648,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
} else {
if (crcStatus == 0 || crcStatus == 1) {
char *pos1 = line[(data_len - 2) / 18];
pos1 += (((data_len - 2) % 18) * 4) - 1;

View file

@ -214,18 +214,23 @@ bool create_path(const char *dirname) {
}
*/
bool setDefaultPath(savePaths_t pathIndex, const char *Path) {
bool setDefaultPath(savePaths_t pathIndex, const char *path) {
if (pathIndex < spItemCount) {
if ((Path == NULL) && (g_session.defaultPaths[pathIndex] != NULL)) {
if ((path == NULL) && (g_session.defaultPaths[pathIndex] != NULL)) {
free(g_session.defaultPaths[pathIndex]);
g_session.defaultPaths[pathIndex] = NULL;
}
if (Path != NULL) {
g_session.defaultPaths[pathIndex] = (char *)realloc(g_session.defaultPaths[pathIndex], strlen(Path) + 1);
strcpy(g_session.defaultPaths[pathIndex], Path);
if (path == NULL) {
return false;
}
size_t len = strlen(path);
g_session.defaultPaths[pathIndex] = (char *)realloc(g_session.defaultPaths[pathIndex], len + 1);
strcpy(g_session.defaultPaths[pathIndex], path);
return true;
}
return false;
@ -234,47 +239,70 @@ bool setDefaultPath(savePaths_t pathIndex, const char *Path) {
static char *filenamemcopy(const char *preferredName, const char *suffix) {
if (preferredName == NULL) return NULL;
if (suffix == NULL) return NULL;
char *fileName = (char *) calloc(strlen(preferredName) + strlen(suffix) + 1, sizeof(uint8_t));
if (fileName == NULL)
if (fileName == NULL) {
return NULL;
}
strcpy(fileName, preferredName);
if (str_endswith(fileName, suffix))
if (str_endswith(fileName, suffix)) {
return fileName;
}
strcat(fileName, suffix);
return fileName;
}
static size_t path_size(savePaths_t a) {
if (a == spItemCount) {
return 0;
}
return strlen( g_session.defaultPaths[a] );
}
char *newfilenamemcopy(const char *preferredName, const char *suffix) {
if (preferredName == NULL) return NULL;
if (suffix == NULL) return NULL;
if (preferredName == NULL || suffix == NULL) {
return NULL;
}
uint16_t p_namelen = strlen(preferredName);
if (str_endswith(preferredName, suffix))
p_namelen -= strlen(suffix);
const size_t fileNameLen = p_namelen + strlen(suffix) + 1 + 10;
const size_t fileNameSize = fileNameLen * sizeof(uint8_t);
// 10: room for filenum to ensure new filename
const size_t len = p_namelen + strlen(suffix) + 1 + 10;
char *fileName = (char *) calloc(fileNameLen, sizeof(uint8_t)); // 10: room for filenum to ensure new filename
int foobar = path_size(spDefault);
(void) foobar;
char *fileName = (char *) calloc(len, sizeof(uint8_t));
if (fileName == NULL) {
return NULL;
}
int num = 1;
snprintf(fileName, fileNameSize, "%.*s%s", p_namelen, preferredName, suffix);
snprintf(fileName, len, "%.*s%s", p_namelen, preferredName, suffix);
while (fileExists(fileName)) {
snprintf(fileName, fileNameSize, "%.*s-%d%s", p_namelen, preferredName, num, suffix);
snprintf(fileName, len, "%.*s-%d%s", p_namelen, preferredName, num, suffix);
num++;
}
PrintAndLogEx(INFO, "FILE PATH: %s", fileName);
return fileName;
}
int saveFile(const char *preferredName, const char *suffix, const void *data, size_t datalen) {
if (data == NULL) return PM3_EINVARG;
if (data == NULL || datalen == 0) {
return PM3_EINVARG;
}
char *fileName = newfilenamemcopy(preferredName, suffix);
if (fileName == NULL) return PM3_EMALLOC;
if (fileName == NULL) {
return PM3_EMALLOC;
}
/* We should have a valid filename now, e.g. dumpdata-3.bin */
@ -295,9 +323,14 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si
int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t blocksize) {
if (data == NULL) return PM3_EINVARG;
if (data == NULL || datalen == 0) {
return PM3_EINVARG;
}
char *fileName = newfilenamemcopy(preferredName, ".eml");
if (fileName == NULL) return PM3_EMALLOC;
if (fileName == NULL) {
return PM3_EMALLOC;
}
int retval = PM3_SUCCESS;
int blocks = datalen / blocksize;
@ -343,10 +376,14 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s
}
int saveFileJSONex(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen, bool verbose, void (*callback)(json_t *)) {
if (data == NULL) return PM3_EINVARG;
if (data == NULL || datalen == 0) {
return PM3_EINVARG;
}
char *fileName = newfilenamemcopy(preferredName, ".json");
if (fileName == NULL) return PM3_EMALLOC;
if (fileName == NULL) {
return PM3_EMALLOC;
}
int retval = PM3_SUCCESS;
@ -704,9 +741,15 @@ int saveFileJSONrootEx(const char *preferredName, void *root, size_t flags, bool
int saveFileWAVE(const char *preferredName, const int *data, size_t datalen) {
if (data == NULL) return PM3_EINVARG;
if (data == NULL || datalen == 0) {
return PM3_EINVARG;
}
char *fileName = newfilenamemcopy(preferredName, ".wav");
if (fileName == NULL) return PM3_EMALLOC;
if (fileName == NULL) {
return PM3_EMALLOC;
}
int retval = PM3_SUCCESS;
struct wave_info_t wave_info = {
@ -731,11 +774,14 @@ int saveFileWAVE(const char *preferredName, const int *data, size_t datalen) {
retval = PM3_EFILE;
goto out;
}
fwrite(&wave_info, sizeof(wave_info), 1, wave_file);
for (int i = 0; i < datalen; i++) {
uint8_t sample = data[i] + 128;
fwrite(&sample, 1, 1, wave_file);
}
fclose(wave_file);
PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%zu") " bytes to wave file " _YELLOW_("'%s'"), 2 * datalen, fileName);
@ -747,9 +793,14 @@ out:
int saveFilePM3(const char *preferredName, int *data, size_t datalen) {
if (data == NULL) return PM3_EINVARG;
if (data == NULL || datalen == 0) {
return PM3_EINVARG;
}
char *fileName = newfilenamemcopy(preferredName, ".pm3");
if (fileName == NULL) return PM3_EMALLOC;
if (fileName == NULL) {
return PM3_EMALLOC;
}
int retval = PM3_SUCCESS;
@ -760,8 +811,9 @@ int saveFilePM3(const char *preferredName, int *data, size_t datalen) {
goto out;
}
for (uint32_t i = 0; i < datalen; i++)
for (uint32_t i = 0; i < datalen; i++) {
fprintf(f, "%d\n", data[i]);
}
fflush(f);
fclose(f);
@ -1862,14 +1914,18 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea
(strcmp(PYTHON_SCRIPTS_SUBDIR, pm3dir) == 0) ||
(strcmp(RESOURCES_SUBDIR, pm3dir) == 0))) {
char *path = calloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char));
if (path == NULL)
if (path == NULL) {
goto out;
}
strcpy(path, exec_path);
strcat(path, pm3dir);
strcat(path, filename);
if ((g_debugMode == 2) && (!silent)) {
PrintAndLogEx(INFO, "Searching %s", path);
}
if (fileExists(path)) {
free(filename);
*foundpath = path;
@ -2007,7 +2063,8 @@ int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumpl
}
int pm3_save_dump(const char *fn, uint8_t *d, size_t n, JSONFileType jsft, size_t blocksize) {
if (n == 0) {
if (d == NULL || n == 0) {
PrintAndLogEx(INFO, "No data to save. Skipping...");
return PM3_EINVARG;
}

View file

@ -60,7 +60,9 @@ typedef enum {
int fileExists(const char *filename);
//bool create_path(const char *dirname);
bool setDefaultPath(savePaths_t pathIndex, const char *Path); // set a path in the path list g_session.defaultPaths
// set a path in the path list g_session.defaultPaths
bool setDefaultPath(savePaths_t pathIndex, const char *path);
char *newfilenamemcopy(const char *preferredName, const char *suffix);

View file

@ -35,7 +35,9 @@ typedef enum logLevel {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG, INPLA
typedef enum emojiMode {EMO_ALIAS, EMO_EMOJI, EMO_ALTTEXT, EMO_NONE} emojiMode_t;
typedef enum clientdebugLevel {cdbOFF, cdbSIMPLE, cdbFULL} clientdebugLevel_t;
// typedef enum devicedebugLevel {ddbOFF, ddbERROR, ddbINFO, ddbDEBUG, ddbEXTENDED} devicedebugLevel_t;
typedef enum savePaths {spDefault, spDump, spTrace, spItemCount} savePaths_t; // last item spItemCount used to auto map to number of files
// last item spItemCount used to auto map to number of files
typedef enum savePaths {spDefault, spDump, spTrace, spItemCount} savePaths_t;
typedef struct {int x; int y; int h; int w;} qtWindow_t;
typedef struct {

View file

@ -303,7 +303,8 @@ void print_hex_noascii_break(const uint8_t *data, const size_t len, uint8_t brea
static void print_buffer_ex(const uint8_t *data, const size_t len, int level, uint8_t breaks) {
if (len < 1)
// sanity checks
if ((data == NULL) || (len < 1))
return;
char buf[UTIL_BUFFER_SIZE_SPRINT + 3];
@ -1260,3 +1261,12 @@ int byte_strstr(uint8_t *src, size_t srclen, uint8_t *pattern, size_t plen) {
}
return -1;
}
void sb_append_char(smartbuf *sb, unsigned char c) {
if (sb->idx >= sb->size) {
sb->size *= 2;
sb->ptr = realloc(sb->ptr, sb->size);
}
sb->ptr[sb->idx] = c;
sb->idx++;
}

View file

@ -146,4 +146,11 @@ uint32_t leadingzeros32(uint32_t a);
uint64_t leadingzeros64(uint64_t a);
int byte_strstr(uint8_t *src, size_t srclen, uint8_t *pattern, size_t plen);
struct smartbuf {
char *ptr;
size_t size;
size_t idx;
} typedef smartbuf;
void sb_append_char(smartbuf *sb, unsigned char c);
#endif

View file

@ -23,7 +23,14 @@
#include <stddef.h>
#include <stdbool.h>
#ifdef _WIN32
#define ABOVE "..\\"
#define PATHSEP "\\"
#else
#define ABOVE "../"
#define PATHSEP "/"
#endif
// PM3 share path relative to executable when installed
#define PM3_SHARE_RELPATH ".." PATHSEP "share" PATHSEP "proxmark3" PATHSEP

View file

@ -32,6 +32,7 @@
//#define FLAG_ICLASS_READER_ONLY_ONCE 0x04
#define FLAG_ICLASS_READER_CREDITKEY 0x08
#define FLAG_ICLASS_READER_AIA 0x10
#define FLAG_ICLASS_READER_SHALLOW_MOD 0x20
// iCLASS reader status flags
#define FLAG_ICLASS_NULL 0x00
@ -60,6 +61,7 @@ typedef struct {
bool use_replay;
bool send_reply;
bool do_auth;
bool shallow_mod;
uint8_t blockno;
} PACKED iclass_auth_req_t;
@ -103,6 +105,7 @@ typedef struct iclass_premac {
typedef struct {
bool use_credit_key;
bool shallow_mod;
uint8_t count;
iclass_premac_t items[];
} PACKED iclass_chk_t;

View file

@ -1,816 +0,0 @@
; ---------------------------------------------------------------------------
; Proxmark3 RDV4 SIM module firmware
;
; Copyright (C) 2109, 2022 Sentinel
;
; This program is free software: you can redistribute it and/or modify it
; under the terms of the GNU Lesser General Public License as published by the
; Free Software Foundation, either version 3 of the License, or (at your
; option) any later version.
;
; This program is distributed in the hope that it will be useful, but WITHOUT
; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
; more details.
;
; You should have received a copy of the GNU Lesser General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>
; ---------------------------------------------------------------------------
VERS_HI equ 4
VERS_LO equ 12
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
SCON_0 equ 098h
FE_0 equ 098h.7
SCON_1 equ 0F8h
RI_1 equ 0F8h.0
TI_1 equ 0F8h.1
FE_1 equ 0F8h.7
SBUF_1 equ 09Ah
T3CON equ 0C4h
RL3 equ 0C5h
RH3 equ 0C6h
P0M1 equ 0B1h
P0M2 equ 0B2h
P1M1 equ 0B3h
P1M2 equ 0B4h
P3M1 equ 0ACh;
P3M2 equ 0ADh;
EIE equ 09Bh
EIE1 equ 09Ch
TA equ 0C7h
RCTRIM0 equ 084h
; ---------------------------------------------------------------------------
CKCON equ 08Eh
CKDIV equ 095h
; ---------------------------------------------------------------------------
P1S equ 0B3h ;Page1
SFRS equ 091h ;TA Protection
; ---------------------------------------------------------------------------
;AUXR1 equ 0A2h
; ---------------------------------------------------------------------------
I2DAT equ 0BCh;
I2STAT equ 0BDh;
I2CLK equ 0BEh;
I2TOC equ 0BFh;
I2CON equ 0C0h;
; equ I2CON.7;8
I2CEN equ I2CON.6;4
STA equ I2CON.5;2
STO equ I2CON.4;1
SI equ I2CON.3;8
AA equ I2CON.2;4
; equ I2CON.1;2
I2CPX equ I2CON.0;1
I2ADDR equ 0C1h;
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
pin_TX1 equ P1.6
pin_TX0 equ P0.6
pin_RX0 equ P0.7
pin_SCL equ P1.3
pin_SDA equ P1.4
pin_RST equ P1.0
pin_CLC equ P1.1
pin_led equ P1.2
; ---------------------------------------------------------------------------
; ===========================================================================
CMD_GENERATE_ATR equ 01h
CMD_WRITE_DATA_SIM equ 02h
CMD_READ_DATA_SIM equ 03h
CMD_SET_BAUD_RATE equ 04h
CMD_SET_SIM_CLC equ 05h
CMD_GET_VERS equ 06h
CMD_WRITE_CONFIRM equ 07h
; ---------------------------------------------------------------------------
; ===========================================================================
bit_RX0 equ 32.0
bit_command_receive equ 32.1
bit_generate_ATR equ 32.2
i2c_write_mode equ 32.3
i2c_write_done equ 32.4
bit_data_sim_wr equ 32.5
; equ 32.6
bit_TX0 equ 32.7
bit_command_buff equ 33.0
i2c_write_command equ 33.1
i2c_command_done equ 33.2
bit_wait_confirm equ 33.3
bit_first_ATR equ 33.4 ;11/03/2019
bit_length_answerH equ 33.5
bit_length_answerL equ 33.6
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
bit_32 equ 32
bit_33 equ 33
time_data_read equ 34
time_confirm equ 35
pointer_RX1H equ 36 ;save SBUF(SIM) to XRAM
pointer_RX1L equ 37 ;save SBUF(SIM) to XRAM
pointer_RX2H equ 38 ;read XRAM to I2C
pointer_RX2L equ 39 ;read XRAM to I2C
pointer_TXH equ 40
pointer_TXL equ 41
length_send_to_simH equ 42
length_send_to_simL equ 43
length_answer_simH equ 44
length_answer_simL equ 45
length_command equ 46
buff_command equ 47
cmd_command equ 48
data_command equ 49
STACKKKKK equ 200
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
XRAM_TX_BUFF equ 0
XRAM_RX_BUFF equ 384
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
; Beginning of the main program
cseg at 00
Ljmp main_start
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
cseg at 11 ;1302Hz = 4MHZ(Fsys)/12/256
; ---------------------------------------------------------------------------
jb time_confirm.7, $+3+2 ;3
dec time_confirm ;2
; ---------------------------------------------------------------------------
jb time_data_read.7,reti_timer0
djnz time_data_read, reti_timer0
setb pin_scl
reti_timer0:
reti
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
cseg at 35 ;UART0
ajmp jmp_UART0_interrupt
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
cseg at 51 ;I2C
ajmp jmp_i2c_interrupt
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
cseg at 123 ;UART1
clr RI_1
clr TI_1
reti
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
jmp_UART0_interrupt:
jbc RI,jmp_byte_RI
jbc TI,jmp_byte_TI
reti
; ---------------------------------------------------------------------------
jmp_byte_RI:
jnb bit_first_ATR, jmp_not_collect ;11/03/2019
setb bit_RX0
jb i2c_write_done,jmp_not_collect
PUSH ACC
PUSH DPH
PUSH DPL
mov DPL,pointer_RX1L
mov DPH,pointer_RX1H
mov a,SBUF
movx @DPTR,a
inc DPTR
mov pointer_RX1L,DPL
mov pointer_RX1H,DPH
POP DPL
POP DPH
POP ACC
;09/08/2018
clr pin_scl
mov time_data_read,#52 ;52/1302Hz = 40mS
inc length_answer_simL
mov a,length_answer_simL
jnz $+2+2 ;2
inc length_answer_simH ;2
jmp_not_collect:
reti
; ---------------------------------------------------------------------------
jmp_byte_TI:
setb bit_TX0
reti
; ===========================================================================
; ---------------------------------------------------------------------------
jmp_i2c_interrupt:
PUSH ACC
PUSH PSW
mov PSW,#24
mov R7,I2STAT
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
cjne R7,#000h,nextttt00000
setb STO
clr SI
jb STO,$
ajmp pop_i2c_psw
nextttt00000:
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
cjne R7,#060h,nextttt00001 ;START+MY ADRESS
clr pin_led ;LED ON
clr bit_command_receive
clr i2c_write_mode
clr bit_data_sim_wr
clr bit_length_answerH
clr bit_length_answerL
clr bit_command_buff
clr i2c_write_command
ajmp end_i2c_interrupt
nextttt00001:
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
cjne R7,#080h,nextttt00002 ;RAM ADRESS
jb bit_command_receive,jmp_data_receive
setb bit_command_receive
mov a,I2DAT
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
cjne a,#CMD_WRITE_CONFIRM,next_comm001a
setb bit_wait_confirm
ajmp WRITEDATASIM
next_comm001a:
; ---------------------------------------------------------------------------
cjne a,#CMD_WRITE_DATA_SIM,next_comm001b
clr bit_wait_confirm
ajmp WRITEDATASIM
next_comm001b:
; ---------------------------------------------------------------------------
cjne a,#CMD_GENERATE_ATR,next_comm002
ajmp ATR_GENERATE
next_comm002:
; ---------------------------------------------------------------------------
cjne a,#CMD_GET_VERS,next_comm003
ajmp ANSWER_VERS
next_comm003:
; ---------------------------------------------------------------------------
cjne a,#CMD_SET_BAUD_RATE,next_comm004
ajmp BAUD_RATE_SET
next_comm004:
; ---------------------------------------------------------------------------
cjne a,#CMD_SET_SIM_CLC,next_comm005
ajmp SIM_CLC_SET
next_comm005:
; ---------------------------------------------------------------------------
ajmp end_i2c_interrupt
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
jmp_data_receive:
;What receive ? Data to SIM/Command to bridge
jb bit_data_sim_wr, jmp_data_sim_receive
jb i2c_write_command,jmp_comm_bridge_receive
ajmp end_i2c_interrupt
; ---------------------------------------------------------------------------
jmp_comm_bridge_receive:
mov @R0,I2DAT
inc R0
inc length_command
ajmp end_i2c_interrupt
; ---------------------------------------------------------------------------
jmp_data_sim_receive:
setb i2c_write_mode
PUSH DPH
PUSH DPL
mov DPL,pointer_TXL
mov DPH,pointer_TXH
mov a,I2DAT
movx @DPTR,a
inc DPTR
mov pointer_TXL,DPL
mov pointer_TXH,DPH
POP DPL
POP DPH
inc length_send_to_simL
mov a,length_send_to_simL
jnz $+2+2 ;2
inc length_send_to_simH ;2
ajmp end_i2c_interrupt
nextttt00002:
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
cjne R7,#0A0h,nextttt00003 ;STOP
setb pin_led ;LED OFF
;Command finish ?
jnb i2c_write_command,jmp_not_command
clr i2c_write_command
setb i2c_command_done
jmp_not_command:
;data to SIM finish ?
jnb i2c_write_mode,end_i2c_interrupt
clr i2c_write_mode
setb i2c_write_done
;Prepare to answer
mov length_answer_simH,#0
mov length_answer_simL,#0
mov pointer_RX1H,#HIGH(XRAM_RX_BUFF)
mov pointer_RX1L,#LOW (XRAM_RX_BUFF)
mov pointer_RX2H,#HIGH(XRAM_RX_BUFF)
mov pointer_RX2L,#LOW (XRAM_RX_BUFF)
ajmp end_i2c_interrupt
nextttt00003:
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
cjne R7,#0A8h,nextttt00004
sjmp read_byte_I2C
nextttt00004:
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
cjne R7,#0B8h,nextttt00005
read_byte_I2C:
jnb bit_command_buff,jmp_not_comm_buff2
mov I2DAT,@R0
inc R0
ajmp end_i2c_interrupt
jmp_not_comm_buff2:
jb bit_length_answerH,jmp_not_comm_buff3
setb bit_length_answerH
mov I2DAT,length_answer_simH
ajmp end_i2c_interrupt
jmp_not_comm_buff3:
jb bit_length_answerL,read_byte_APROM
setb bit_length_answerL
mov I2DAT,length_answer_simL
ajmp end_i2c_interrupt
read_byte_APROM:
PUSH DPH
PUSH DPL
mov DPL,pointer_RX2L
mov DPH,pointer_RX2H
movx a,@DPTR
mov I2DAT,a
inc DPTR
mov pointer_RX2L,DPL
mov pointer_RX2H,DPH
POP DPL
POP DPH
nextttt00005:
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
end_i2c_interrupt:
clr STA
clr STO
setb AA
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
pop_i2c_psw:
POP PSW
POP ACC
clr SI
reti
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
ANSWER_VERS:
mov R0,#data_command
mov cmd_command,#CMD_GET_VERS
mov (data_command+0),#2
mov (data_command+1),#VERS_HI
mov (data_command+2),#VERS_LO
setb bit_command_buff
ajmp end_i2c_interrupt
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
ATR_GENERATE:
setb bit_generate_ATR
;Prepare to answer
mov length_answer_simH,#0
mov length_answer_simL,#0
mov pointer_RX1H,#HIGH(XRAM_RX_BUFF)
mov pointer_RX1L,#LOW (XRAM_RX_BUFF)
mov pointer_RX2H,#HIGH(XRAM_RX_BUFF)
mov pointer_RX2L,#LOW (XRAM_RX_BUFF)
ajmp end_i2c_interrupt
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
BAUD_RATE_SET:
mov R0,#data_command
mov length_command,#0
mov cmd_command,#CMD_SET_BAUD_RATE
setb i2c_write_command
ajmp end_i2c_interrupt
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
SIM_CLC_SET:
mov R0,#data_command
mov length_command,#0
mov cmd_command,#CMD_SET_SIM_CLC
setb i2c_write_command
ajmp end_i2c_interrupt
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
WRITEDATASIM:
mov length_send_to_simH,#0
mov length_send_to_simL,#0
setb bit_data_sim_wr
mov pointer_TXH,#HIGH(XRAM_TX_BUFF)
mov pointer_TXL,#LOW (XRAM_TX_BUFF)
ajmp end_i2c_interrupt
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
main_start:
mov SP,#STACKKKKK
; ---------------------------------------------------------------------------
;0-bidirect 1-push pull 0-input only 1-open drain
;0 0 1 1
; ---------------------------------------------------------------------------
mov P0M2,#01000000b ;?0
mov P0M1,#11111111b ;P1.6-Tx0 SIM;
;
mov P1M2,#01011111b ;<3B>1
mov P1M1,#10111000b ;P1.6-Tx1 DEBUG; P1.4,P1.3 - I2C;
mov P3M2,#00000000b ;P3
mov P3M1,#11111111b ;
; ---------------------------------------------------------------------------
mov TMOD, #22h
mov TH0, #0 ;14400hz
mov TH1, #0E9h ;UART0 10800 Bit/sec
mov TCON, #55h
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
mov TA,#0AAh
mov TA,#055h
orl SFRS,#00000001b
mov P1S, #00010000b ;P1.4 trigger schmiddt
mov TA,#0AAh
mov TA,#055h
anl SFRS,#11111110b
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
;------- CONFIG I2C ---------
mov I2CON, #44h ;set AA, set I2C enable
setb pin_sda
setb pin_scl
mov I2ADDR,#0C0h
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
;mov SCON, #050h ;UART0 8bit
mov SCON, #0D0h ;UART0 9bit
;mov PCON, #11000000b;FE_0 enable
mov PCON, #10000000b;FE_0 disable
; ---------------------------------------------------------------------------
mov SCON_1,#050h ;UART1
;mov T3CON, #01101000b;FE_1 enable TIMER3 UART0 BAUD
;mov T3CON, #00101000b;FE_1 disable TIMER3 UART0 BAUD
mov T3CON, #00001000b;FE_1 disable TIMER1 UART0 BAUD
;mov RL3,#0E9h ;10800/21600
;mov RH3,#0FFh
; ---------------------------------------------------------------------------
;UART1
mov RL3,#0F7h ;27777/55556
mov RH3,#0FFh
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
mov CKDIV,#2 ;Fsys=4.00MHZ
;mov CKDIV,#1 ;Fsys=8.00MHZ
; ---------------------------------------------------------------------------
mov bit_32,#0
mov bit_33,#0
setb time_data_read.7
; ---------------------------------------------------------------------------
;orl CKCON,#00000010b ;ENABLE CLC TIMER1 Fsys/12
orl CKCON,#00010010b ;ENABLE CLC TIMER1 Fsys
; ---------------------------------------------------------------------------
;mov a,RCTRIM0
;add a,#31
;mov TA,#0AAh
;mov TA,#055h
;mov RCTRIM0,a
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
acall clr_buffer
; ---------------------------------------------------------------------------
mov EIE, #00000001b ;I2C Interrupt
;mov IE, #10010000b ;EA, SERIAL0
mov IE, #10010010b ;EA, SERIAL0, TIMER0
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
main_loop:
acall control_ATR
acall control_send_to_sim
acall control_command
sjmp main_loop
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
control_command:
jbc i2c_command_done,$+3+1 ;3
ret ;1
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
;Control Length command=1
mov a,length_command
cjne a,#1,next_commandEND ;error length_command != 1
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
mov a,cmd_command
cjne a,#CMD_SET_BAUD_RATE,next_command001
mov TH1,data_command ;Timer1 HIGH byte
ret
next_command001:
; ---------------------------------------------------------------------------
cjne a,#CMD_SET_SIM_CLC, next_command002
mov CKDIV,data_command ;Fsys DIV
ret
next_command002:
; ---------------------------------------------------------------------------
next_commandEND:
ret
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
control_send_to_sim:
jb i2c_write_done,$+3+1 ;3
ret ;1
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
jbc bit_wait_confirm,jmp_wait_confirm
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
mov DPTR,#XRAM_TX_BUFF
looop_send:
movx a,@DPTR
inc DPTR
acall for_coooooom0
clr c
mov a,length_send_to_simL
subb a,#1
mov length_send_to_simL,a
mov a,length_send_to_simH
subb a,#0
mov length_send_to_simH,a
orl a,length_send_to_simL
jnz looop_send
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
jnb bit_RX0,$
clr i2c_write_done
ret
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
jmp_wait_confirm:
mov DPTR,#(XRAM_TX_BUFF+1)
movx a,@DPTR
mov R3,a
mov R4,#5
; ---------------------------------------------------------------------------
mov DPTR,#XRAM_TX_BUFF
looop_seend:
movx a,@DPTR
inc DPTR
acall for_coooooom0
djnz R4,jmp_not_5byte
jnb bit_RX0,$
clr bit_RX0
;18/12/2018
mov time_confirm,#65 ;New timeout 50mS
looop_waitconf:
jb time_confirm.7,jmp_no_answer
jnb bit_RX0,looop_waitconf
;clr pin_scl ;TEST PULSE!
mov a,SBUF
xrl a,R3
;setb pin_scl ;TEST PULSE!
jnz jmp_no_correct_answer ;18/12/2018
;pause for next byte 17/12/2018
mov R7,#0
djnz R7,$ ;~260mkSec
djnz R7,$ ;~260mkSec
djnz R7,$ ;~260mkSec
jmp_not_5byte:
clr c
mov a,length_send_to_simL
subb a,#1
mov length_send_to_simL,a
mov a,length_send_to_simH
subb a,#0
mov length_send_to_simH,a
orl a,length_send_to_simL
jnz looop_seend
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
jnb bit_RX0,$
clr bit_RX0
jmp_no_answer:
clr i2c_write_done
ret
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
;18/12/2018
jmp_no_correct_answer:
clr EA
clr i2c_write_done
mov DPL,pointer_RX1L
mov DPH,pointer_RX1H
mov a,SBUF
movx @DPTR,a
inc DPTR
mov pointer_RX1L,DPL
mov pointer_RX1H,DPH
clr pin_scl
mov time_data_read,#52 ;52/1302Hz = 40mS
inc length_answer_simL
mov a,length_answer_simL
jnz $+2+2 ;2
inc length_answer_simH ;2
setb EA
ret
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
control_ATR:
jbc bit_generate_ATR,$+3+1 ;3
ret ;1
; ---------------------------------------------------------------------------
clr pin_RST
;acall clr_buffer
; Add rezet pause 17/12/2018
mov R6,#200
looop_pause50mS:
djnz R7,$ ;~260mkSec
djnz R6,looop_pause50mS
;Prepare to answer 11/03/2019
acall clr_buffer
mov length_answer_simH,#0
mov length_answer_simL,#0
mov pointer_RX1H,#HIGH(XRAM_RX_BUFF)
mov pointer_RX1L,#LOW (XRAM_RX_BUFF)
mov pointer_RX2H,#HIGH(XRAM_RX_BUFF)
mov pointer_RX2L,#LOW (XRAM_RX_BUFF)
setb bit_first_ATR
setb pin_RST
ret
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
for_coooooom0:
clr bit_RX0
mov c,P
mov TB8,c ;9bit parity
mov SBUF,a
jnb bit_TX0,$
clr bit_TX0
mov R7,#100
djnz R7,$
ret
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
clr_buffer:
mov DPTR,#0256 ;Receive SIM buffer
mov R7,#255
clr a
looop_clr_bufff:
movx @DPTR,a
inc DPTR
djnz R7,looop_clr_bufff
ret
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
;for_coooooom1:
; mov SBUF_1,a
; jnb TI_1,$
; clr TI_1
; ret
;
; ---------------------------------------------------------------------------
; ===========================================================================
; ---------------------------------------------------------------------------
end.