Menu

SWDocumentation

Gitte Bager
Attachments
00000.jpeg (759797 bytes)

SCSDT – Smart Card Sniffing and Debugging Tool - Documentation

This document contains the technical documentation of the software part
of the “Smart Card Sniffing and Debugging Tool” (SCSDT) project.

The software is used to log data that is being transmitted on a contact
interface between an ME and a smart card using a hardware unit developed
for this purpose. The software is able to – in one mode – to parse logged
data and present them in real-time in a readable format.

Contents

SCSDT – Smart Card Sniffing and Debugging Tool -
Documentation

Requirements

Initial files (for communicating with the hardware)

OKUSBLIB

SCSDT Generic

Sniffer Hardware

High Level Data

LowLevelLogger

Sniffer

USBPoller – The Producer for the HighlevelLogger

Flowchart

Sniffer classes

Polling mechanism

Change log

Requirements

  • The SCSDT software was written in C# which is part of .NET. You
    therefore need Microsoft .NET Framework 4.0.
  • Visual Studio 2010/2012 Express was the main IDE used as development
    tool. It is freely available from Microsoft.
  • The software was tested on Windows XP/7/8.

The software handles the setup, and communication with an Opal Kelly
XEM3001v2 board connected with a PC via a USB2 cable.

foobar

Figure 1: Sniffer connected via a connector to a ME to the left and via
an USB2 cable to a laptop on the right

Initial files (for communicating with the hardware)

A C# dynamic link library (DLL) along with an API was provided by the
manufacturer (Opal Kelly) for the board. This .dll along with the API
functions are the base foundation of the Sniffer Software.

The API provides the base for readings and initializations etc.

The Sniffer Software is built in the solution file Sniffer.sln.

The solution file (Sniffer.sln) consists of two projects:

  • OKUSBLib, handling the basic reading and writing using the basic API
    functions provided.

  • Sniffer, providing a GUI to let the user interact with the sniffer
    hardware as well as giving other features. There are two features
    worth mentioning here.

  • Feature 1: Using the Sniffer software to analyze an already recorded
    Sniffer log.

  • Feature 2: Using the Sniffer software to analyze data from another
    log but converted into a format that can be interpreted by the
    Sniffer and be used to analyze in a lower level manner providing:
    Number of CLKs between APDUs etc.


OKUSBLIB


The OKUSBLib project contains one class:

Class name Description
OKUSB2.cs Contains implemented functions as
defined in the abstract class IUSB.cs.
It is this class that interfaces to the
Sniffer with the provided API functions
provided by Opal Kelly.

Table 1: OKUSBLib classes

The OKUSBLib classes contain the interface code containing API function
calls for the initialization and resetting of the device along with
functions for reading buffer status and reading a specific number of
bytes from the hardware.

Either a single byte is read at the time, using ReadWireOut. This is
used when polling the device to check if there is data available.
Alternatively a range of bytes are read with ReadPipeOut.

The OKUSB2.cs contains a few functions for doing a few necessary
commands in order for the hardware to work as intended.

Function name Description
EmptyBuffers Empties the high level FIFO (handy
when resetting a session)
ResetSnifferLogger Resets the hardware and forces the
sniffer to negotiate PPS. A note:
The processing of the ATR + PPS is
done in the Hardware (Sniffer)
itself. This is due to the fact,
that it is a time critical process
and therefore the processing of the
ATR /PPS is put on the HW side,
instead of requiring the SW to be
able to handle this
 
ReadWireOut Reads data from a specified wire out
address, (used when polling for a
status byte, bit coded, to indicate
if there is data ready and how much)
for example.
ReadPipeOut Reads from a provided PipeOut
Register, data into a byte array as
per argument.
WriteWireIn Function for writing a data byte to
a specified wire in address.
Currently not used.
WritePipeIn Function for writing an array of
data from a byte array into a wire
in address. Currently not used.

On the hardware side of things – 2 FIFOs are used for providing data to
the software. The following is an overview of this.

SCSDT Generic

The SCSDTGeneric project contains classes that are used by both the
OKUSBLib and by the Sniffer project.

In this way the software is not dependent on the existence of the
hardware.

Class name Description
Constants.cs Contains addresses of Wires/Pipes used for reading/writing
data to the Sniffer.
It also contains data for transfer sizes and bit patterns
to be checked.
IUSB.cs Abstract class that contains all the functions that is
to be implemented to have a Sniffer.
It contains functions such as ResetSniffer, EmptyBuffers,
ReadBufferStatus, ReadNumberOfBytes

Sniffer Hardware

The hardware is based on an Opal Kelly XEM3001 FPGA board.

With the base in the above board and with the addition of a few level
converters, a SIM probe, a DB9 plug and knowledge about 7813-3, a VHDL
design was created to sample on the IO/RST and CLK pins – to put it
short. Dennis Vitus Lajer Rasmussen has done all design, construction
and development of the Sniffer hardware.

In the Sniffer hardware design the following definition is used to
differentiate between the 2 types of data that can be read out from it:

  • High level data – 2 byte event data consisting of whole bytes. I.e.
    a byte in the ATR/PPS or from an APDU communication. Each data byte
    comes along with 1 status byte. Data is put on a FIFO (for reference
    FIFO3).
  • Low level data – 6 bytes event data from sampling on the RST/IO pin.
    Each time the IO /RST pin on the SIM changes, 6 bytes of data is
    generated with information as specified later. Data is put on
    another FIFO. (For reference FIFO2).

The sample data is put into two FIFOs – FIFO2 and FIFO3, with addresses
as below and hardcoded in Constants.cs.

The direction IN is when data is sent to the FPGA.

The direction OUT is used when data is retrieved from the FPGA.

Wire In Name Address value
SPEED_ENHANCEMENT_WIREIN 0x10, (used to force the HW to do
the PPS negotiation) putting the
weight on the HW instead of in the
software.
HIGH_LEVEL_LOGGER_STATUS_WIREIN 0x35 (Used to check whether there is
high level /low level data).
SET_SPEED_ENHANCEMENT_WIREIN 0x90, 4 FFs are sent to this wirein
to force PPS negotiation to happen
in the HW.
RESET_SNIFFER_HW_WIRE 0x8E, (not used)
HIGH_LEVEL_LOGGER_PIPE_OUT 0xAF (after determining from the
status byte that there is either 2
or 2*512 bytes available), data is
fetched from this pipe out.
LOW_LEVEL_LOGGER_PIPE_OUT 0xB0 (after determining from the
status byte that there is either 6
or 6*512 bytes available), data is
fetched from this pipe out.

As mentioned several times, chunks of data is read from the hardware, by
reading of pipe outs, either for the high or the low level pipe.

But this is only done, when there is data to be fetched. Whether data is
available or not, is checked initially by polling 0x35, wire out.

The Wire out takes the pattern as indicated in Table 2.

B7 B6 B5 B4 B3 B2 B1 B0 Description
1               FIFO3 full,continue
but report warning
  1             512 events- 2*512
bytes available
    1           1 event (2 bytes)
are available
      1         Empty FIFO- at least
1 event, 2 bytes
are available
        1       FIFO2 full,
continue but
report warning
          1     512 events- 6*512
bytes available
            1   Almost empty (not needed
by the SW)
              1 Empty, at least 1
event (6 bytes
available)
Table 2: Bit pattern of wire out (0x35)

If there is data available, data bytes are fetched. Following
description is made to clarify what is understood by high level and low
level data. And what exactly is being fetched.

High Level Data

1 event, consisting of 2 bytes – takes the form as depicted in Error!
Reference source not found.

For each event there is a status byte. The status byte is coded as
depicted in [Table 3]

B7 B6 B5 B4 B3 B2 B1 B0 Description
1               FIFO full, continue
but report warning
  1             512 events-
2*512
bytes available
    1           1 event (2 bytes)
are available
      1         Empty FIFO-
at least 1
more event
(2 bytes)
are available
        RFU        
          1     Parity error bit
            1   Error signal bit
              1 Reset detected bit

Table 3: Content of status byte for an event

To summarize: The high level logger (which is the one described above)
gets its data from FIFO 3 on the hardware. The data is received by the
use of Read Wire Out as previously mentioned.

  • At startup or whenever there is no more data to be fetched, the
    polling type of reading is done.
  • As soon as data/events are ready, reading is done using Pipe Out.
    This is controlled by Polling Controller (described later).
  • Each event available when reading via Pipe Out consists of 2 bytes:
    A data byte and a status byte for the high level data.
  • The status byte contains information whether more data is available,
    and if so how much. It follows the same pattern as the data from
    reading the wire out in the top bits. In its lower nibble it
    contains details concerning parity/error. Please refer to Table 3.

LowLevelLogger

Similarly for the low level logger, 1 event consists of 6 bytes

Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
AA BB CC DATA DUMMY SS

Table 4: Low Level event illustration

Where

AA BB CC = 24 bits clock counter, AA=LSB.. CC=MSB, which is an
indicator for the number of clocks that has elapsed since the last
event.

DATA is coded as illustrated in Table 5

B7 B6 B5 B4 B3 B2 B1 B0 Description
1 x x x x x x x 000 = 0V
x 1 x x x x x x 001 = between 0V and 1.8V
010 = 1.8V
011 = between 1.8V and 3.0V
x x 1 x x x x x 100 = 3.0V
101 = between 3.0V and 5V
110 = 5V
x x x 1 x x x x RFU
x x x x 1 x x x RFU
x x x x x 1 IO state, high/low
x x x x x x 1 x RFU
x x x x x x x 1 Reset state, high/low

Table 5: Data byte meaning for Low Level Logger

DUMMY byte is reserved for future use.

SS is a status byte and takes the following, almost identical
pattern as that of the high level logger, except it also contains
information about the high level logger, (to avoid having to poll
again).

B7 B6 B5 B4 B3 B2 B1 B0 Description
1               FIFO3 full,
continue
but report warning
  1             512 events-
2*512 bytes
available
    1           1 event (2 bytes)
are available
      1         Empty FIFO-
at least 1
event, 2 bytes
are available
        1       FIFO2 full,
continue but
report warning
          1     512 events-
6*512
bytes available
            1   Almost empty
(not needed
by the SW)
              1 Empty,at least 1
event (6 bytes
available)

Table 6 Low Level Status Byte (SS) meaning

****Sniffer

With an idea about the data generated from the hardware, a second
project, the Sniffer project was created.

The Sniffer project is built on the concept of a “producer –consumer”
design.

Producer Consumer
USBPollerHigh HighLevelLogger
UBPollerLow LowLevelLogger

The USBPollerHigh/USBPollerLow class is the producer.

These two classes are both of the type, Poller. These are under the
control of a PollerController.

The HighlevelLogger/LowLevelLogger class is the consumer.

USBPoller – The Producer for the HighlevelLogger

Flowchart

Table 7: Flowchart of the USBPoller mechanism

In the Sniffer, there is a GUI that interacts with the user. The GUI
will allow enabling/disabling polling and processing of both high and
low level data – so control is added to the main form that will create
an instance of PollerController for each of the logs requested.

Classes exist to poll the USB2 port on the Sniffer hardware for data.
This is done by using some of the functions created in the OKUSB2, as
described above.

Initially the USBPoller reads a WireOut on the Sniffer until data is
available indicated by a bit mask in the read value as illustrated in
Table 2

If data is available events are fetched and put on a list.

Either 1 event is fetched, giving rise to a 2 byte data array.
Alternatively, 512 events are fetched – giving rise to a 1024 byte
array.

Each event is built as illustrated in Error! Reference source not
found.
.Error! Reference source not found.If more data is available
– as detected in the status byte, more events will be fetched.

If no more events are available – the USBPoller will read data from a
WireOut – as initially - to check for available data. This will continue
forever until the user terminates the session.

The interaction between the USBPoller and the HighLevelLogger can be
described in the following manner:

The USBPoller continuously adds events, formed as byte arrays to a list.
The byte arrays added are either 2 events long or 512 events long.

The HighLevelLogger will read the entries from the list of byte arrays
and interpret data according to a state machine – first processing an
ATR, PPS and then APDUs as they appear. The formatting of the APDUs
occurs based on an xml file, indicating the type of command.

The interaction between the HighLevelLogger and the Sniffer is as
follows:

The idea is that the USBPoller should always provide data, and the
HighLevelLogger will read entries and interpret them one entry at the
time.

Sniffer classes

GUI related classes

Class name Description
Changelog Inside about box – containing
information of what was done since
last release
Change Class for defining what defines a
change.
MainForm Main GUI holding all buttons, radio
buttons and also displays the live
stream of logged data.

The Sniffer project also contains the following classes for handling all
the other functionality

Class name Description
AnswerToReset This class contains a state machine
to decode the ATR (Answer To Reset).
The ATR is information presented by
the SIM to the ME in the beginning
of a card session. It is the way the
SIM can give information to the ME
about what it supports.
Command This is a serializable class that is
used in connection with the reading
of CommandInfo.xml.
 
CommandInfo is an xml file next to
the executable that takes the form
as displayed above. The xml file is
used when interpreting data on the
I: O: form, tagging the command and
splitting it accordingly into what
type it is.
 
DataPackage Datapackage is a class created with
the aim of separating a read event
read from a high level logger of the
form : [data, status] into two bytes
– where the second status byte can
be examined for whether a reset or a
parity error has occurred.
HighLevelLogger HighLevelLogger is created in the
MainForm on an initiation of a
logging session.
When the USBPoller has indicated
that there are events available, the
HighLevel logger will get data. It
will pack the data into data
packages and put data onto a
concurrent queue. Then the state
machine is called, which will put
the data onto the real time screen.
HighLevelLoggerFile  
LowLevelLogger  
PipeInfo Explained in the table polling
mechanism
Poller Explained in the table polling
mechanism
PollerController Explained in the table polling
mechanism
PPS Contains a state machine that
processes a PPS negotiation. It will
return true, when a full PPS has
been received. A PPS will take the
form :
PPS : PPSS PPS0 [PPS1 PPS2 PPS3]
PCKS - where PPS1..3 are optional
ProactiveCommand Contains a state machine for
determining when all bytes of a
command have been received.
Program Main program for the application,
does nothing except checks that
commandinfo.xml is present (more
files could be added here) and
starts the application.
ReleaseInformation Called by MainForm as part of the
Help/ChangeLog pressing. It is a
class with information about release
version number and changes (From the
Change.cs ) class that have occurred
since last.
Statemachine Contains a state machine with states
for ATR, possible PPS and APDUs.
This class is called from the High
Level Logger and will dequeue data
from a concurrent queue and write it
to an online real time box.
USB2Simulator This class is merely designed from
an existing log. It reads in data
already logged as if this is data
read live. It can then be used to
simulate a logging session and makes
it easy to debug code
USBPollerHigh Explained in the table polling
mechanism
USBPollerLow Explained in the table polling
mechanism
 

Polling mechanism

Filename Description
PipeInfo Class that holds a name, size and
type to be used by the
PollerController when creating named
pipes.
PollerController.cs Contains the constructor that makes
sure to instantiate as many pollers
as required (low and high level) as
requested via the MainForm’s
checkboxes. Starts a thread that
reads the status byte from the wire
out (0x35) (High level logger status
byte to check if there is either low
or high level data and in that case,
how much).
Before actually fetching data, the
PollerController creates Named pipes
which are a way of piping data from
a server to a client, which is part
of the producer ->consumer
structure that the Sniffer project
uses.
Data is fetched with the following
priority.
Priority list:
-a lot of data from the low level
logger
-a lot of data from the high level
logger
-small amount of data from the low
level logger
-small amount of data from the high
level logger
Poller.cs Abstract class with a few functions
that applies to both the
USBPollerHigh and Low, which are of
this type.
USBPollerHigh.cs Called by the Poller controller,
reads either 2 or 2*512 bytes at
the time and writes data to a binary
writer =named pipe server. After
reading 2 or 2*512 bytes it reads
to check if there are more data to
be fetched.
USBPollerLow.cs Called by the Poller controller,
reads either 6 or 6*512 bytes at
the time and writes data to a binary
writer =named pipe server. After
reading 6 or 6*512 bytes it reads
to check if there are more data to
be fetched.

Related

Wiki: Home

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.