send response from key to pc in chaining mode. partially works.
GetVersion must work with pc (proxmark have errors)
This commit is contained in:
@ -44,11 +44,66 @@ void nfc_state_init()
|
||||
|
||||
void nfc_init()
|
||||
{
|
||||
|
||||
|
||||
nfc_state_init();
|
||||
ams_init();
|
||||
}
|
||||
void process_int0(uint8_t int0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ams_wait_for_tx(uint32_t timeout_ms)
|
||||
{
|
||||
uint32_t tstart = millis();
|
||||
while (tstart + timeout_ms > millis())
|
||||
{
|
||||
uint8_t int0 = ams_read_reg(AMS_REG_INT0);
|
||||
if (int0) process_int0(int0);
|
||||
if (int0 & AMS_INT_TXE)
|
||||
return true;
|
||||
|
||||
delay(1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//bool ams_receive_with_timeout(10, recbuf, sizeof(recbuf), &reclen))
|
||||
bool ams_receive_with_timeout(uint32_t timeout_ms, uint8_t * data, int maxlen, int *dlen)
|
||||
{
|
||||
uint8_t buf[32];
|
||||
*dlen = 0;
|
||||
|
||||
uint32_t tstart = millis();
|
||||
while (tstart + timeout_ms > millis())
|
||||
{
|
||||
uint8_t int0 = ams_read_reg(AMS_REG_INT0);
|
||||
uint8_t buffer_status2 = ams_read_reg(AMS_REG_BUF2);
|
||||
|
||||
if (buffer_status2 && (int0 & AMS_INT_RXE))
|
||||
{
|
||||
if (buffer_status2 & AMS_BUF_INVALID)
|
||||
{
|
||||
printf1(TAG_NFC,"Buffer being updated!\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t len = buffer_status2 & AMS_BUF_LEN_MASK;
|
||||
ams_read_buffer(buf, len);
|
||||
printf1(TAG_NFC,">> "); dump_hex1(TAG_NFC, buf, len);
|
||||
|
||||
*dlen = MIN(32, MIN(maxlen, len));
|
||||
memcpy(data, buf, *dlen);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
delay(1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void nfc_write_frame(uint8_t * data, uint8_t len)
|
||||
{
|
||||
@ -63,11 +118,6 @@ void nfc_write_frame(uint8_t * data, uint8_t len)
|
||||
printf1(TAG_NFC,"<< "); dump_hex1(TAG_NFC, data, len);
|
||||
}
|
||||
|
||||
void nfc_write_response_chaining(uint8_t req0, uint8_t * data, uint8_t len)
|
||||
{
|
||||
nfc_write_frame(data, len);
|
||||
}
|
||||
|
||||
bool nfc_write_response_ex(uint8_t req0, uint8_t * data, uint8_t len, uint16_t resp)
|
||||
{
|
||||
uint8_t res[32];
|
||||
@ -92,6 +142,72 @@ bool nfc_write_response(uint8_t req0, uint16_t resp)
|
||||
return nfc_write_response_ex(req0, NULL, 0, resp);
|
||||
}
|
||||
|
||||
void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len, uint16_t resp)
|
||||
{
|
||||
uint8_t res[32 + 2];
|
||||
int sendlen = 0;
|
||||
uint8_t iBlock = NFC_CMD_IBLOCK | (req0 & 3);
|
||||
printf1(TAG_NFC,"-- chain \r\n");
|
||||
if (len <= 32)
|
||||
{
|
||||
nfc_write_response_ex(req0, data, len, resp);
|
||||
} else {
|
||||
do {
|
||||
// transmit I block
|
||||
int vlen = MIN(31, len - sendlen);
|
||||
res[0] = iBlock;
|
||||
memcpy(&res[1], &data[sendlen], vlen);
|
||||
if (vlen + sendlen < len)
|
||||
{
|
||||
res[0] |= 0x10;
|
||||
} else {
|
||||
// here may be buffer overflow!!!
|
||||
res[vlen + 1] = resp >> 8;
|
||||
res[vlen + 2] = resp & 0xff;
|
||||
vlen += 2;
|
||||
}
|
||||
|
||||
nfc_write_frame(res, vlen + 1);
|
||||
sendlen += vlen;
|
||||
|
||||
printf1(TAG_NFC,"-- slen: %d res0: %02x\r\n", sendlen, res[0]);
|
||||
|
||||
// wait for transmit (32 bytes aprox 2,5ms)
|
||||
if (!ams_wait_for_tx(10))
|
||||
{
|
||||
printf1(TAG_NFC, "TX timeout. slen: %d \r\n", sendlen);
|
||||
break;
|
||||
}
|
||||
|
||||
// receive R block
|
||||
if (res[0] & 0x10)
|
||||
{
|
||||
uint8_t recbuf[32] = {0};
|
||||
int reclen;
|
||||
if (!ams_receive_with_timeout(100, recbuf, sizeof(recbuf), &reclen))
|
||||
{
|
||||
printf1(TAG_NFC, "R block RX timeout.\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (reclen != 1)
|
||||
{
|
||||
printf1(TAG_NFC, "R block length error. len: %d \r\n", reclen);
|
||||
break;
|
||||
}
|
||||
|
||||
if (((recbuf[0] & 0x01) != (res[0] & 1)) && ((recbuf[0] & 0xf6) == 0xa2))
|
||||
{
|
||||
printf1(TAG_NFC, "R block error. txdata: %02x rxdata: %02x \r\n", res[0], recbuf[0]);
|
||||
//break;
|
||||
}
|
||||
}
|
||||
|
||||
iBlock ^= 0x01;
|
||||
} while (sendlen < len);
|
||||
}
|
||||
}
|
||||
|
||||
int answer_rats(uint8_t parameter)
|
||||
{
|
||||
|
||||
@ -226,7 +342,7 @@ void nfc_process_iblock(uint8_t * buf, int len)
|
||||
|
||||
if (status == CTAP1_ERR_SUCCESS)
|
||||
{
|
||||
nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length);
|
||||
nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length, SW_SUCCESS);
|
||||
} else {
|
||||
nfc_write_response(buf[0], SW_INTERNAL_EXCEPTION | status);
|
||||
}
|
||||
@ -329,6 +445,9 @@ void nfc_loop()
|
||||
{
|
||||
t1 = millis();
|
||||
read_reg_block(&ams);
|
||||
|
||||
process_int0(ams.regs.int0);
|
||||
|
||||
// if (memcmp(def,ams.buf,sizeof(AMS_DEVICE)) != 0)
|
||||
// {
|
||||
// printf1(TAG_NFC,"regs: "); dump_hex1(TAG_NFC,ams.buf,sizeof(AMS_DEVICE));
|
||||
|
@ -67,6 +67,7 @@ typedef enum
|
||||
} APPLETS;
|
||||
|
||||
#define SW_SUCCESS 0x9000
|
||||
#define SW_GET_RESPONSE 0x6100 //Command successfully executed; 'XX' bytes of data are available and can be requested using GET RESPONSE.
|
||||
#define SW_COND_USE_NOT_SATISFIED 0x6985
|
||||
#define SW_FILE_NOT_FOUND 0x6a82
|
||||
#define SW_INS_INVALID 0x6d00
|
||||
|
Reference in New Issue
Block a user