Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper 14443-4a support #151

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions firmware/application/src/app_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,13 +491,17 @@ data_frame_tx_t *cmd_processor_get_mf1_anti_coll_data(uint16_t cmd, uint16_t sta
if (tag_type[0] == TAG_TYPE_UNKNOWN) {
return data_frame_make(cmd, STATUS_PAR_ERR, 0, data); // no data in slot, don't send garbage
}
uint8_t responseData[16] = {};
picc_14a_tag_t taginfo;
nfc_tag_14a_coll_res_reference_t *info = get_saved_mifare_coll_res();
memcpy(responseData, info->uid, *info->size);
responseData[10] = *info->size; // size is 2 byte len, but...
responseData[12] = info->sak[0];
memcpy(&responseData[13], info->atqa, 2);
return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, 16, responseData);
taginfo.uid_len = *info->size;
taginfo.cascade = (taginfo.uid_len + 2) / 4; //it's weird but it works for 4->1, 7->2, 10->3
taginfo.sak = *info->sak;
taginfo.ats_len = info->ats->length;
memcpy(taginfo.uid, info->uid, taginfo.uid_len);
memcpy(taginfo.atqa, info->atqa, 2);
memcpy(taginfo.ats, info->ats->data, taginfo.ats_len);

return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, sizeof(taginfo), (uint8_t*) &taginfo);
}

data_frame_tx_t *cmd_processor_set_mf1_detection_enable(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
Expand Down
5 changes: 5 additions & 0 deletions firmware/application/src/app_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,11 +648,16 @@ static void btn_fn_copy_ic_uid(void) {
status = pcd_14a_reader_scan_auto(&tag);
if (status == HF_TAG_OK) {
// copy uid
antres->size = tag.uid_len;
memcpy(antres->uid, tag.uid, tag.uid_len);
// copy atqa
memcpy(antres->atqa, tag.atqa, 2);
// copy sak
antres->sak[0] = tag.sak;
// copy ats
antres->ats.length = tag.ats_len;
memcpy(antres->ats.data, tag.ats, tag.ats_len);

NRF_LOG_INFO("Offline HF uid copied")
offline_status_ok();
} else {
Expand Down
2 changes: 1 addition & 1 deletion firmware/application/src/app_status.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#define HF_ERR_BCC (0x05) // IC card BCC error
#define MF_ERR_AUTH (0x06) // MF card verification failed
#define HF_ERR_PARITY (0x07) // IC card parity error

#define HF_ERR_ATS (0x08) // ATS should be present but card NAKed

/////////////////////////////////////////////////////////////////////
// MIFARE status
Expand Down
17 changes: 17 additions & 0 deletions firmware/application/src/rfid/reader/hf/rc522.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ uint8_t pcd_14a_reader_scan_once(picc_14a_tag_t *tag) {
if (tag) {
tag->uid_len = 0;
memset(tag->uid, 0, 10);
tag->ats_len = 0;
} else {
return STATUS_PAR_ERR; // Finding cards are not allowed to be transmitted to the label information structure
}
Expand Down Expand Up @@ -579,6 +580,22 @@ uint8_t pcd_14a_reader_scan_once(picc_14a_tag_t *tag) {
// Therefore + 1
tag->cascade = cascade_level + 1;
}
if (tag->sak & 0x20) {
// Tag supports 14443-4, sending RATS
uint16_t ats_size;
status = pcd_14a_reader_ats_request(tag->ats, &ats_size, 0xFF*8);
ats_size -= 2; // size returned by pcd_14a_reader_ats_request includes CRC
ASSERT(ats_size <= 0xFF);
if (tag->ats[0] != ats_size) {
NRF_LOG_INFO("Invalid ATS! First byte doesn't match received length\n");
return HF_ERR_ATS;
}
tag->ats_len = ats_size;
if (status != HF_TAG_OK) {
NRF_LOG_INFO("Tag SAK claimed to support ATS but tag NAKd RATS\n");
return HF_ERR_ATS;
}
}
return HF_TAG_OK;
}

Expand Down
2 changes: 2 additions & 0 deletions firmware/application/src/rfid/reader/hf/rc522.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ typedef struct {
uint8_t cascade; // theAntiCollisionLevelValueIs1Representation 4Byte,2Represents7Byte,3Means10Byte
uint8_t sak; // chooseToConfirm
uint8_t atqa[2]; // requestResponse
uint8_t ats[0xFF];// 14443-4 answer to select
uint8_t ats_len; // 14443-4 answer to select size
} picc_14a_tag_t;

#ifdef __cplusplus
Expand Down
6 changes: 6 additions & 0 deletions software/script/chameleon_cli_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,9 @@ def scan(self):
print(f"- UID Hex : {info['uid_hex'].upper()}")
print(f"- SAK Hex : {info['sak_hex'].upper()}")
print(f"- ATQA Hex : {info['atqa_hex'].upper()}")
if info['ats_size']:
print(f"- ATS Size: {info['ats_size']}")
print(f"- ATS Hex : {info['ats_hex'].upper()}")
return True
else:
print("ISO14443-A Tag no found")
Expand Down Expand Up @@ -853,6 +856,9 @@ def scan(self):
print(f"- UID Hex : {info['uid_hex'].upper()}")
print(f"- SAK Hex : {info['sak_hex'].upper()}")
print(f"- ATQA Hex : {info['atqa_hex'].upper()}")
if info['ats_size']:
print(f"- ATS Size: {info['ats_size']}")
print(f"- ATS Hex : {info['ats_hex'].upper()}")
return True
else:
print("No data loaded in slot")
Expand Down
6 changes: 4 additions & 2 deletions software/script/chameleon_cstruct.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ def parse_14a_scan_tag_result(data: bytearray):
"""
return {
'uid_size': data[10],
'uid_hex': data[0:data[10]].hex(),
'uid_hex': data[0:data[10]].hex(' '),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added space separator for clarity

'sak_hex': hex(data[12]).lstrip('0x').rjust(2, '0'),
'atqa_hex': data[13:15].hex().upper()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed .upper() because it's called anyways by the caller, added space separator for clarity

'atqa_hex': data[13:15].hex(' '),
'ats_size': data[270],
'ats_hex': data[15:15 + data[270]].hex(' '),
}


Expand Down
2 changes: 2 additions & 0 deletions software/script/chameleon_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Device(metaclass=MetaDevice):
HF_ERR_BCC = 0x05 # IC card BCC error
MF_ERR_AUTH = 0x06 # MF card verification failed
HF_ERR_PARITY = 0x07 # IC card parity error
HF_ERR_ATS = 0x08 # ATS should be present but card NAKed

# Darkside, the random number cannot be fixed, this situation may appear on the UID card
DARKSIDE_CANT_FIXED_NT = 0x20
Expand Down Expand Up @@ -63,6 +64,7 @@ class Device(metaclass=MetaDevice):
Device.HF_ERR_BCC: "HF tag uid bcc error",
Device.MF_ERR_AUTH: "HF tag auth fail",
Device.HF_ERR_PARITY: "HF tag data parity error",
Device.HF_ERR_ATS: "HF tag was supposed to send ATS but didn't",

Device.DARKSIDE_CANT_FIXED_NT: "Darkside Can't select a nt(PRNG is unpredictable)",
Device.DARKSIDE_LUCK_AUTH_OK: "Darkside try to recover a default key",
Expand Down