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

Send APDU and get challenge from ISO 14443-A Biometric Passport #492

Closed
tetrahydra opened this issue Sep 24, 2019 · 8 comments
Closed

Send APDU and get challenge from ISO 14443-A Biometric Passport #492

tetrahydra opened this issue Sep 24, 2019 · 8 comments
Labels
help_wanted 💉 here you can help others or/and make pull requests

Comments

@tetrahydra
Copy link

Step 1: Describe your environment

  • OS version: MacOS
  • Arduino IDE version: 1.8.9
  • MFRC522 Library version: 1.4.5
  • Arduino device: Arduino Uno
  • MFRC522 device: RC522

Step 2: Describe the problem

I would like to read DG1 from biometric passport.

I understood that in order to do that i must:

  1. Get Challenge using APDU
  2. Authenticate
  3. Read Binary (protected by secure messaging) - read the DG1 file which contains basic passport holder info

However, I failed to do the first part.

Observed Results:

Scan PICC to see UID and type...
PCD_TransceiveData() failed: Timeout in communication.

Relevant Code:

void loop() {

  // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    delay(50);
    return;
  }

  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    delay(50);
    return;
  }

  byte sendData[] = {0x00, 0x84, 0x00, 0x00, 0x08};
  byte backLen = 10;
  byte sendLen = sizeof(sendData);
  byte backData[backLen];
  MFRC522::StatusCode status = mfrc522.PCD_TransceiveData(sendData, sizeof(sendData), backData, &backLen);

  if ( status != MFRC522::STATUS_OK) {
    Serial.print(F("PCD_TransceiveData() failed: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  } else {
    Serial.println(F("PICC_TransceiveData() success "));
  }

}
@Rotzbua Rotzbua added the help_wanted 💉 here you can help others or/and make pull requests label Sep 25, 2019
@tolgasaglam
Copy link

any help?

@Rotzbua
Copy link
Collaborator

Rotzbua commented Jul 25, 2020

If you have found a solution, you are welcome to publish it here.

@Rotzbua Rotzbua closed this as completed Jul 25, 2020
@a-v-s
Copy link

a-v-s commented Sep 3, 2022

I may have found the solution. Prefix the ADPU with a alternating 0x02 and 0x03
This is a ISO 14443-4 header called "Protocol Control Byte" (PCB)
The answer will also be prefixed with this 0x02/0x03 value
And it will be suffixed with a status code

@mhaberler
Copy link

mhaberler commented Dec 14, 2023

@a-v-s I can confirm this works for me as well!

where did you find that solution?

I'm trying to read a Type 4 tag and doing the sequence "Select the NDEF Application", "Select CC File", "Read CC File", "Select NDEF File", "Read Length of NDEF File", "Read Data from NDEF File" as per "Exhibit E: Example of Mapping Version 2.0 Command Flow", p.65 of Type 4 Tag Technical Specification Version 1.2 2022-08-16

I had the symptom that the "Select the NDEF Application" step succeeded with 90 00 status, and the following "Select CC File" step would time out:

// Select the NDEF Application:
---> 02 00 A4 04 00 07 D2 76 00 00 85 01 01 00 35 C0 // reply status OK - 90 00:
<--- 02 90 00 F1 09 CRC is not taken care of by MFRC522: 0 // unsure why, but not harmful
// "Select CC File":
---> 02 00 A4 00 0C 02 E1 03 6D 2E
// no reply - timeout :
NDEF_SelectCapabilityContainer STATUS NOT OK: 3

If I apply your 2/3 recipe, all goes fine:

---> 02 00 A4 04 00 07 D2 76 00 00 85 01 01 00 35 C0
<--- 02 90 00 F1 09
CRC is not taken care of by MFRC522: 0
---> 03 00 A4 00 0C 02 E1 03 D2 AF
<--- 03 90 00 2D 53
CRC is not taken care of by MFRC522: 0

the low bit of an I-block PCB is the "Block number", its semantics is not touched upon in ISO/IEC 14443-4:2001 but the 2007 amendment ballot section 7.1.1.1 Protocol control byte field p16ff has some references

this looks like the alternating bit protocol for basic duplicate detection and retransmit to me

let me see if I can complete the T4T reading based on this clue..

edit: found a way to set the PCB block number by using this code as a start: https://github.com/Obsttube/MFRC522_NTAG424DNA/blob/main/src/MFRC522_NTAG424DNA.h#L108

@mhaberler
Copy link

mhaberler commented Dec 14, 2023

hm, actually the blockNumber toggling is in place for TCL_Transceive() and TCL_TransceiveRBlock(), see
https://github.com/miguelbalboa/rfid/blob/master/src/MFRC522Extended.cpp#L797-L800 ff

	// Set the block number
	if (tag->blockNumber) {
		out.prologue.pcb |= 0x01;
	}
....
        // Swap block number on success
	tag->blockNumber = !tag->blockNumber;
....

edit: turns out there are two TCL_Transceive() members with different signatures:

        StatusCode TCL_Transceive(PcbBlock *send, PcbBlock *back);
	StatusCode TCL_Transceive(TagInfo * tag, byte *sendData, byte sendLen, byte *backData = NULL, byte *backLen = NULL);
	StatusCode TCL_TransceiveRBlock(TagInfo *tag, bool ack, byte *backData = NULL, byte *backLen = NULL);
	StatusCode TCL_Deselect(TagInfo *tag);

the first one takes a fixed block number via the PcbBlock *send argument and does not try to toggle the BN
the other TCL_* methods take a Taginfo parameter, and that struct tracks the BN which gets toggled as needed

my code used the first TCL_Transceive() which doesnt do the BN toggling

edit: it helps to have a look at RFID-DESFire which is closely related/was used for/is derived from the code in MFRC522Extended.*

the methods talking to the card for business all use a custom tag structure which tracks the BN

@mhaberler
Copy link

mhaberler commented Dec 14, 2023

@Rotzbua would you be open to re-adopt MFRC522Extended.* into Arduino_MFRC522v2 ?

that would enable ISO 7816 style APDU handling

I have an uncleaned first stab here and here

if yes, I'd clean it up and add the RuuviTag reading example once I get it to work

edit: RuuviTag reading progressing without surprises, I should have something to show next week

@mhaberler
Copy link

here is a complete working example for reading a Type4 tag with MFRC522v2, based on the above suggestion:

https://github.com/mhaberler/MFRC522v2_t4tag/tree/master

@a-v-s
Copy link

a-v-s commented Jan 6, 2024

It has been a while since I wrote code for this. I was working on a C port of this library, that then evolved into something that supports multiple PCDs.

The answer is somewhere in the ISO 14443-4 specifications. Paragraph 7.5.3.1 states the block number should toggle.
I might have been testing with an app on my phone for debugging, possibly using an nRF52 with nfc so see what the phone was sending. Not sure if I found out by documentation or reverse engineering.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help_wanted 💉 here you can help others or/and make pull requests
Projects
None yet
Development

No branches or pull requests

5 participants