Card responds with 6985 - apdu

I'm constructing a generate AC command for a Mastercard contactless card. I have retrieved the CDOL1 from the ICC data, however the card respond with 6985. Any advice on what the problem might be.
Card Risk Management Data Object List 1 (CDOL1) [8C]:
Amount, Authorised (Numeric) [9F02]:
Length: 06
Amount, Other (Numeric) [9F03]:
Length: 06
Terminal Country Code [9F1A]:
Length: 02
Terminal Verification Results (TVR) [95]:
Length: 05
Transaction Currency Code [5F2A]:
Length: 02
Transaction Date [9A]:
Length: 03
Transaction Type [9C]:
Length: 01
Unpredictable Number (UN) [9F37]:
Length: 04
Terminal Type [9F35]:
Length: 01
Data Authentication Code [9F45]:
Length: 02
ICC Dynamic Number [9F4C]:
Length: 08
Cardholder Verification Method (CVM) Results [9F34]:
Length: 03
Transaction Time [9F21]:
Length: 03
Customer Exclusive Data (CED) [9F7C]:
Length: 14
80AE - Generate Application Cryptogram
80 - ARQC
00
42 - Length
000000000100 - 9F02
000000000000 - 9F03
0710 - 9F1A
8000040800 - 95
0710 - 5F2A
191111 - 9A
00 - 9C
3357A30B - 9F37
21 - 9F35
0000 - 9F45
0000000000000000 - 9F4C
1F0302 - 9F34
142005 - 9F21
0000000000000000000000000000000000000000 - 9F7C

The first thing you need to do is to look at the PDOL you get in response to the GPO message, and check that these are exactly the fields and lengths the card is asking for. Post the answer to the GPO message here if you are unsure. A common cause for this error is if you don't provide all the data the card wants, or if you send it too much.
I have a MasterCard that asks for exactly the data you have here and it response correctly to a GEN AC command of:
80AE900042000000000100000000000000082600000000000826190819003357A30A21000000000000000000001F0302120505000000000000000000000000000000000000000000
Comparing this with your message there are a few small differences. Below I list what you send and what I'm sending:
80AE - same
80 - I use 90, see EMV book 4, Section 6.5.5 on how to build the P1 value.
00 - same
42 - same
000000000100 - same
000000000000 - same
0710 - I use 0826 UK rather than Estonia, shouldn't matter.
8000040800 - I use 0000000000 which means no errors
0710 - Again I use 0826 UK, not Estonia
191111 - 9A I use a different date, shouldn't matter.
00 - same
3357A30B - Our UN numbers are only 1 different, which is odd! Where did you find yours?
21 - same
0000 - same
0000000000000000 - same
1F0302 - same
142005 - different time, shouldn't matter.
0000000000000000000000000000000000000000 - same
I also have 00 on the end for the Le.
Tom

Application SELECT Command may return Tag 0x9F38 Processing Options DOL (PDOL).
The Tag Values required by PDOL need to be sent by terminal/reader to the card in the next step Get Processing Options (GPO) Command.
In case PDOL is unknown after application selection you may send GPO Command with empty Tag 0x83 to retrieve Tags 0x82 Application Interchange Profile (AIP) and 0x94 Application File Locator (AFL) from card.
Having AFL you should READ all mentioned records and analyze card tags. They may have CDOL1 value required for Generate AC.
Then, if it is still needed by card transaction scenario, you can send Generate AC Command with CDOL1 Tag Values.
Please refer to EMVCo EMV Contactless Specifications for Payment Systems, Book C-2, Kernel 2 Specification where MasterCard scenarios described.

Related

why SET STATUS APDU command returns 6985?

I have a USIM card and the Card Life Cycle is OP_READY:
Connected to the Card...
<--> [Mutual Auth]
---> 80 F2 80 00 02 4F 00
<--- 08 A0 00 00 00 03 00 00 00
01 <== LifeCycle = OP_READY
98
90 00
I want to change the card Life Cycle to SECURED. Based on the GlobalPlatform Card Specification I have to first change the card life cycle to INITIALIZED and then to SECURED state:
And this is the coding of differnet Life Cycles in SET STATUS APDU command:
So I tried to change the life cycle as below:
Connected to Card.
<--> [Mutual Auth with SecLevel = 0x00]
---> 80 F0 80 07 00
<--- **Fail** 6A 86
---> 80 F0 80 0F 00
<--- **Fail** 69 85
As you see above, I received 6A86 (INCORRECT P1-P2 Parameters) for INITIALIZED and 6985 (CONDITIONS OF USE NOT SATISFIED) for SECURED life cycle.
I also tried the same process with SecLevel=0x03, but nothing changes:
Connected to Card.
<--> [Mutual Auth with SecLevel = 0x03]
---> 84 F0 80 07 08 <MAC>
<--- **Fail** 6A 86
---> 84 F0 80 0F 08 <MAC>
<--- **Fail** 69 85
What is wrong?
It might be that your card is imposing additional requirements for the state change. If you have a manual consult it if some special behavior is described.
If this is not available my strongest guess would be that the card would like to see some keys to be personalized on the card before the state change is allowed. Use a PUT KEY command to update the keys. If updating the key using the same key version and index does not work try to create an additional key version.
Although unlikely to succeed, you can also try a STORE DATA command to set the life cycle status. The mapping guidelines, 6.13 allows to set the tag 9F70.

Ntag424 DNA Integrity Error (911e) when attempting CMD.ChangeFileSettings

So I've been working on a Nodejs tag writer for the NTAG424 DNA and I am still getting the hang of APDU commands. I am tracing the steps of the example from https://www.nxp.com/docs/en/application-note/AN12196.pdf but the documentation is confusing at times. I am attempting to write to file02 to take advantage of the SUN/CMAC mirroring of the tag by using Cmd.WriteData in CommMode.Full. When I write the data I get an <9100> OK response code but in CommMode.Full I believe I should be receiving an encrypted response with more data. Then when I attempt to do Cmd.ChangeFileSetting after WriteData in CommMode.Full, I receive a <911e> error. I have looked up and down for 2 days at my code to see if maybe I fumbled the Initialization Vector or encrypted data step, but I think those parts are all good. I am truly lost as to why this is happening. I am using the example provided on the documentation mentioned above, except I modified the header for CMD.write data to make the command length valid (I was getting <917e> before I changed it from <80> to <98>) since I believe the documentation has a typo for this step.
CMD for WriteData to NDEF: 90 8d 00 00 9f 02 00 00 00 98 00 00 {encData} + {macT} + {LE}
CMD for ChangeFileSettings: 90 5f 00 00 19 02 {encData} + {macT} + {LE}
This is all in reference to 6.8.2 and 6.9 of the personalization example in the https://www.nxp.com/docs/en/application-note/AN12196.pdf document.

EMV - GPO with PDOL

I'm working on a C platform and I want to read the AFL of a card.
If the previous command, select of the AID, don't give me a PDOL tag, it's ok: I can read the AFL without issues.
But I need to write a method that can generate a GET PROCESSING OPTION regardless the PDOL.
So the questions are:
How can I write an universal method that work despite the PDOL?
Have I to map every single possible TAG?
How can I format the GPO
command with the correct data? Look the following example:
SELECT AID Response
PDOL: 9F 1A 02
So I have to put the Terminal Country Code, in my case Italy: 380
So the GPO call is:
80 A0 00 00 04 83 02 03 80 00
But the response that I have is 6D 00: Instruction code not supported or invalid
Where am I wrong?
I'm programming on Ingenico Pos (Point of sale).
Good to know that you are aware with the concept of PDOL very well. As far I can understand with your question, you are comfortable to construct GPO command if PDOL is not present. I think You are in doubt to write a generic function to construct GPO APDU command.
First of all I want to tell you that if PDOL information is present in SELECT response then you should send PDOL data in GPO command APDU, otherwise card application may throw some error.
So you can set an indicator when you receive PDOL in SELECT command. If PDOL is not there you can simply send 80 A8 00 00 02 83 00 00 and if your indicator stated that PDOL is required then simply parse the PDOL and from SELECT response and prepare a value for PDOL data if you know (as you described in your question) to be send in GPO command APDU.
If you don't know what value then you can simply fill hexadecimal zeros in value field.
Taking your example : 80 A8 00 00 04 83 02 03 80 00. This is the correct command (I have corrected INS byte). Or you can also send 80 A8 00 00 04 83 02 00 00 00 (PDOL value is replace by zeros)
I think this explanation can help you to get the answers of both the questions. Try it and let us know if there is any further clarification needed.
You have two options:
Issue a command with data field of "8300" - 80 A8 00 00 02 83 00 00
Issue a command with data field of all hexadecimal zeroes - 80 A8 00 00 04 83 02 00 00 00
You receive the error, because in option 1 you omit the Le byte of the C-APDU - this byte is mandatory for all CASE 4 commands and in option 2 you give wrong INS byte, A0 instead of A8.
Card Issuers don't put just any tag and expect the terminal to provide the data. You can get the best practices(recommended tags) from each payment scheme you are certifying with. Besides, if it is some tag which you don't support, you can always zero fill and proceed.

Why I receive `6C0B` instead of data that I expected?

I now have a Hello World project according this link and I made its .cap
file successfully. I have "DE-ABCM_TB" reader and a SAM card also.
My applet AID is 01 02 03 04 05 06 07 08 09 00 00
I could select my applet on the card.( I sent SELECT APDU command via "DualCard
Ver 2.8"/ pcsc tab) . I now must be receive hello in hex format when I send
8000000000. But i receive 6C0B ! Why did I get this response and
how can I resolve this ? I searched but no solving found.
You didn't searched good enough!
If you do a quick look at status words table you will see SW1=6CXX means Wrong Le field; SW2 encodes the exact number of available data bytes
So you must send the below command:
80|00|00|00|0B!
Table of Status Words :

What kind of block format is the Desfire authentication message?

After selection of the card and RATS, i want to start the authentication.
In the mifare documentation is described that an 0A 00 should be sent. This data is supposed to be ISO14443-4. I have to frame it to fit ISO14443-3.
The Block format goes like that
PCB|CID|INF|EDC
In the PCB I am supposed to say if it is an I-block, R-block or S-block.
I saw an example in this thread where he sent something like that:
90 0A 00 00 01 00 00
Where is it documented this frame, it looks like none of the blocks described in ISO14443-4
The Block format PCB|CID|INF|EDC with I-block, R-block or S-block you described is actually ISO 7816-3 T=1 frame (not ISO 14443 frame, not ISO 7816-4 APDU). This is low-level ISO 7816 that implemented in driver level.
The thread you mentioned uses 7816 APDU.
1st "to card" is actually 7816 APDU: CLA=90 INS=0A P1=00 P2=00 LC=01 Data=00 Le=00
2nd "to card" is another APDU: CLA=90 INS=AF P1=00 P2=00 Lc=10 Data=43 9D 17 8E 9A 5F BA 70 8D 23 57 10 C9 32 D5 17 Le=00.
Depending on the version of Mifare DESFire, you can use native, native-wrapped or ISO 7816-4 command set styles.
7816 wraps Mifare native command as follow:
90 [mifare native ins] 00 00 Lc [data] 00
From the 2 commands above, native commands are 0x0A (Authenticate) & 0xAF (More data).
You can't get the mifare native command set documentation freely. You need to sign an NDA. However, take a look at this doc to see learn more: http://www.nxp.com/documents/application_note/AN11004.pdf
Another resource: http://ridrix.wordpress.com/2009/09/19/mifare-desfire-communication-example/
This is not a ISO 14443 frame; it is an ISO 7816-4 APDU.

Resources