ISO 15693: read multiple security blocks

1.8k views Asked by At

I am trying to modify an existing SCardTransmit() command (C#) that currently reads one security status/block from a ISO 15693 vicinity RFID card (TI Tag-it HF), to one that will retrieve the security status for all 64 blocks on the card. The existing code is as follows:

Byte[] sendHeader = { 0xFF, 0x30, 0x00, 0x03, 0x05, 0x01, 0x00, 0x00, 0x00, Convert.ToByte(blockNum), 0x01 };

Byte[] sendBuffer = new Byte[255]; //Send Buffer in SCardTransmit
int sendbufferlen;                 //Send Buffer length in SCardTransmit

SmartCardData pack = new SmartCardData();

sendHeader.CopyTo(sendBuffer, 0);
sendbufferlen = Convert.ToByte(sendHeader.Length);

SCardTransmitReceived rxBuf = SmartCardTransmit(sendBuffer, sendbufferlen);

The way I understand it, the bytes preceding Convert.ToByte(blockNum) represent the command to get a security status, followed by the block in question, and the number of blocks to read. The only reference I have seen regarding security status reads is in section 10.3.4 in the "Contactless Smart Card Reader Dev Guide"

NOTE: SmartCardTransmit takes care of calling SCardTransmit with the correct card handle and the other needed parameters. I'm more interested in the format of the send header that represents a request for security blocks 0 to 63.

2

There are 2 answers

0
Ionut Ciobanu On

From this document: link it appears that your tag complies with ISO15693 standard. From the documentation you have provided it appears that the command you need is at page 59. Now, from the description of the command it appears 0x01 is Version and the following two bytes (0x00 and 0x00) means reading by block. The byte before Convert.ToByte() seams to be the MSB of the starting block (0x00). The Convert.ToByte() is the LSB of the starting block. The next is Le in command description (the number of blocks to be read).

4
Michael Roland On

Unfortunately, that is not possible. The Get Security Status command of the HID/Omnikey smartcard reader can only retrieve the security status of one block with each command. So regardless of what Le byte you try to provide, the reader will always only return the security status of the block you specify with blockNum.

So the only way to get the security status for all blocks is by iterating through all blocks and issuing the command for each of them:

bool moreBlocks = true;
int blockNum = 0;
while (moreBlocks) {
    byte[] sendBuffer = {
        0xFF, 0x30, 0x00, 0x03,
        0x05,
        0x01,
        0x00, 0x00,
        (byte)((blockNum>>8) & 0xFF), (byte)(blockNum & 0xFF),
        0x00
    };
    SCardTransmitReceived rxBuf = SmartCardTransmit(sendBuffer, sendBuffer.Length);
    moreBlocks = check_if_rxBuf_ends_with_sw9000(rxBuf);
    ++blockNum;
}