Problem accessing all the bytes on NFC Tag with OMNIKEY 5426G2 reader using C# to send PC/SC commands - nfc

I am having trouble reading and writing to different NFC tags with OMNIKEY 5426G2.
I can read and write the first 16 pages (4 bytes each) but the moment I send a command to read the 17th page - I get an error 0x6A 0x82 which means that address does not exist.
For example sending 0xFF 0xB0 0x00 0x06 0x04 gets me the 4 bytes on the 6th page
But when I do 0xFF 0xB0 0x00 0x10 0x04 - I get 0x6A 0x82 in return saying that this address does not exist.
All the tags that I use have this problem - different NTAG's, Mifare Ultralight C tags but ICODE SLIX tags are fine.
P.S. The same PC/SC commands work perfectly fine with ACR1252 reader so this is something related to OMNIKEY reader. Maybe some extra commands are missing.
P.P.S. Strange thing is that I can read/write all the bytes and pages by using a demo version of this library https://smartcard-api.com/buy-smart-card-api-library-license/
And since they are also using PC/SC commands - it clearly says that I am missing something.
Please help me understand what is going on. Thanks!

Related

Relation between APDU and higher level NFC protocols (such as ISO 14443-3A)?

I started reading into the topic of NFC/Smartcard-Communication and I found many different standards and commands depending on the Tag type (for example see here)
I also came across the APDU-commands which seem universal to the communication of nfc/smartcards?
Does this mean, that these higher level protocols are all based on apdu and can be translated?
As an example, I found NFC 14443-A commands implemented with the android.nfc.tech.NfcA library, such as:
Action
Byte
Read
0x30
Write
0xA2
And APDU commands like these:
Action
CLA
INS
P1
P2
LC
READ BINARY
0xFF
0xB0
...
...
...
UPDATE BINARY
0xFF
0xD6
...
...
...
GET DATA
0xFF
0xCA
...
...
...
MIFARE CLASSIC READ
0xFF
0xF3
...
...
...
MIFARE CLASSIC WRITE
0xFF
0xF4
...
...
...
The commands seem to be completely different.
It would also help alot, if someone could point to good documentation on the topic
Documentation I have found so far:
The Android documentation on nfca (Link)
APDU description on wikipedia Link
(The german version contains some return codes)
APDU commands (by a card-reader manufacturer) Link
You have it a bit wrong, 14443-3A is lower level that APDU's which come from the higher level ISO 7816 protocol.
But the Byte's ( 0x30 and 0xA2) you reference as NFC 14443-A are not from NFC 14443-A but look like vendor specific Mifare Ultralight protocol commands which are again above NFC 14443-A
There is also a complication and probably the reason you are confused with APDU's you listed according to the ISO 7816 spec, all the APDU's you specified have a CLA of 0xFF are "invalid".
The reason for this is that a USB readers also use ISO 7816 for the host CPU to talk the NFC chip to work mainly with NFC Type 4 Tags, because 0xFF are invalid for ISO 7816 the reader uses them for other non ISO 7816 things the NFC chip can do, e.g. communicate to non standard Mifare classic commands, turn on/off the LED's on the USB reader, etc
So really CLA's of 0xFF are just a way to wrap other commands.
Or in a rough pictorial form
I would read as much of the Standard specification documents shown in the Stackoverflow you linked to and I wrote. There are a lot of specifications used/part used
I know that they are really pay for items but they are out there on the Internet.
e.g.
http://www.emutag.com/iso/14443-3.pdf
http://www.emutag.com/iso/14443-4.pdf
For the higher level NDEF stuff https://github.com/haldean/ndef/tree/master/docs
For the Various NFC Forum Standards
Google Index of the 4 Types

Read memory by Address - Read more than 255 bytes

I want to read around 336 bytes of data from NVRAM using Read Memory By Address UDS service. The command I am giving is "23 22 1C 22 01 50", where
0x23 - UDS command for Read Memory By Address
0x22 - Address and Length Format Identifier (Memory
address parameter - 2 and Memory size parameter 2)
0x1C 0x22 - Memory Address in 2 bytes
0x01 0x50 - Data length to read in 2 bytes (length is 336 bytes)
When I submit the command, I am getting "0x13 Incorrect Message Length or Invalid Format Error".
Can someone help me fixing this problem.
Thanks in advance.
Reference: https://piembsystech.com/uds-protocol/
What NRC 0x13 means
According to ISO 14229-1:2020:
This means:
SID 0x23 is supported by the server otherwise you would receive NRC 0x11 serviceNotSupported
Your request has inproper format (it is either too long or too short), in other cases you would receive other NRC (e.g. 0x31 requestOutOfRange). I suspect that address value is not 2 bytes long. It might be 4 bytes long (it depends on the memory type and size), but it is just a guess.
How to send the request properly
Well we do not know what is the exact format that the server accepts (it depends on memory of the server), but the ISO 14229-1:2020 define SID 0x23 request format as below:
I would try following request:
0x22 0x44 0x00 0x00 0x1C 0x22 0x00 0x00 0x01 0x50
where:
0x00 0x00 0x1C 0x22 - 4-byte memoryAddress
0x00 0x00 0x01 0x50 - memorySize (it is also 4 byte to make sure that addressAndLengthFormatIdentifier is properly interpreted by the server)
Other options
Server might have defect(s) (especially if you succesfully read memory using 2-byte-long address) and incorrectly display NRC 0x13 or have only support for certain value of addressAndLenghtFormatIdentifier. It is hard to judge with 100% certainty though. You would have provide at least one request with positive response.
Please do so in the comment and I am going to guide you through the problem.

Omnikey 5421 generic card command interface not working for Mifare plus SL1

I'm trying to switch a Mifare Plus card into SL1 mode using an Omnikey 5421, however using the "Generic card command" interface as instructed by the documentation does not seem to work (card does not return any kind of output except 0x9000 which seems to be only an ACK that the command was sent succesfully - there should be additionaly bytes in the response before 0x90 0x00 which come from the chip itself).
The sequence is sent using SCardTransmit:
0xFF 0xA0 0x00 0x07 0x03 0x01 0x00 0x01 - enter generic session - returns 0x9000
... additional commands using documentation:
0xFF 0xA0 0x00 0x05 6+n 01 00 F3 00 00 64 + Mifare+ command 00 - returns 0x9000 whatever the command, even if invalid Mifare+ commands
0xFF 0xA0 0x00 0x07 0x03 0x01 0x00 0x02 - exit generic session - returns 0x9000 still
The only commands that seem to work are enter and exit, any other command that I send in between does not seem to have any effect, including RATS, Writeperso or Commitperso. When I add the 00 Le byte at the end the return code is 0x6400 instead of 0x9000, even though the docs say that Le byte should be appended when issuing Mifare+ commands.
All other operations work ok once the cards is personalized in SL1 mode (read, write, authenticate). I can already switch the card to SL1 mode using android NFC, so it does not seem to be a problem with the algorithm or the card.
I've tried to use command from the PC/SC part 3 documentation, but the return code is "not supported", so it seems that only this mechanism of transparent channel is available to issue 14443A commands.
In SL0 and SL3, You may directly call the Plus command via Generic Card Command.
"generic session" should be for SL1 to accept Plus command(as by default it goes to mifare classic mode)

NFC NDEF message formatting : payload size (ISO 15693 header, NfcV)

"Hey bro, what's up ?"
I'm in trouble with NDEF message formatting.
I went through the NFC forum to know how to build a NDEF message with a single NDEF record (text RTD) with a payload, so I can program my tag (M24LR16E) through I2c.
In addition to this, I programmed my tag with an external writer to have an example of a well formatted record.
Then I programmed my tag through I2C with the exact same value, and everything worked well. Changing the payload characters gave me the proof of my success =)
"But you didn't come here to show us that anything worked well, no?"
You're right, know I'm trying to change the payload length and I get troubles. As soon as I change the PAYLOAD_LENGTH of the NDEF record it is no more recognized anymore as one. I changed the PAYLOAD_LENGTH from 10 down to 5, so it's not a problem of overflowing the config field.
"Great story, show me some code/config"
Here is my record configuration :
"Header" (MB ME CF SR IL TNF) : 0xD1
PAYLOAD_LENGTH : 0x0A
TYPE LENGTH : 0x01
TYPE : 0x54
PAYLOAD :
0x02 ; UTF-8, 2 byte language code
0x65 ; e
0x6E ; n
7 Other boring bytes
Also, I noticed that if I override the 6 bytes before my NDEF message, the NDEF message isn't recognized anymore. I have no idea on what could be this data as the NFC specification doesn't talk about this, neither the tag datasheet.
"You're supposed to ask a question..."
Uh, well...
Is there anything else than the PAYLOAD_LENGTH field of the NDEF record that I should change?
What are those essential data before my NDEF message?
My reader: Nexus 4 with NXP's "TagInfo" app
Unfortunately, you won't find much information on how to use that tag to store NDEF messages on the NFC Forum website. The reason for this is that there is currently no Tag Type specifiction for ISO 15693 tags (though standardization is ongoing).
I assume the memory contents of the tag looks like this (including the bytes you did not understand):
E1 4x yy 00
03 0E <YOUR NDEF MESSAGE> FE
If that's the case, the first 4 bytes are the capability container (indicated by the magic byte 0xE1 and the version nibble 0x4). x shoud be 0x0 indicating (application level!) read & write access. yy should be the overall size of your available data memory (excluding capability container) divided by 8. So far you should be able to keep those values...
But then there is the NDEF message TLV structure which embeds your NDEF message: 0x03 is the tag indicating an NDEF message. 0x0E is the length field. So that's what you need to change in addition to the payload length of your record. Android is quite picky when it comes to that length field. If this does not match the exact length of your NDEF message, most Android versions will ignore the message. The last byte, 0xFE is the (optional) terminator TLV. This should immediately follow the last data byte on your tag to tell the NDEF tag parser to stop parsing.

Read java card uid [duplicate]

i am looking for APDU to find UID of contact less ISO 14443 smart card and how to use it to print in Linux terminal. Problem is that i found many people talking about it, but there is no solution. Can anyone help is this regard???
Thanks
"Get Data Command" is defined in PCSC 3 v2. If your driver is PCSC v2 compliant, you can get UID using it:
Class = 0xFF
INS = 0xCA
P1 = 0x00
P2 = 0x00
Le = 0x00 (return full length: ISO14443A single 4 bytes, double 7 bytes, triple 10 bytes, for ISO14443B 4 bytes PUPI, for 15693 8 bytes UID)
Returned value is:
Data+SW1SW2
See the other answer, it is likely that most readers do support the pass through to the card reader by now.
Nobody can help as the UID is specified in the ISO 14443 T=CL transport protocol while APDU's are specified in the ISO 7816 application layer protocol.
So you need access to a lower level API for your contactless reader. PCSC will not suffice (unless there has been a pass through implemented for the specific reader that returns the UID).

Resources