The Smart Card Detective (SCD)
Defines | Functions
terminal.c File Reference

terminal.c source file for Smartcard Defender More...

#include <string.h>
#include <util/delay.h>
#include <stdlib.h>
#include "emv.h"
#include "scd_hal.h"
#include "terminal.h"
#include "emv_values.h"
#include "scd_values.h"
#include "scd_io.h"

Go to the source code of this file.

Defines

#define DEBUG   1
 Set this to 1 to enable debug code.
#define TRIGGER   1
 Set this to enable trigger signals, e.g. to use with oscilloscope.

Functions

RAPDUTerminalSendT0Command (CAPDU *cmd, uint8_t inverse_convention, uint8_t TC1, log_struct_t *logger)
 This function sends a T=0 command from the terminal to the ICC.
FCITemplateApplicationSelection (uint8_t convention, uint8_t TC1, const ByteArray *aid, uint8_t autoselect, log_struct_t *logger)
 Starts the application selection process.
APPINFOInitializeTransaction (uint8_t convention, uint8_t TC1, const FCITemplate *fci, log_struct_t *logger)
 Initialize a transaction by sending GET PROCESSING OPTS command.
RECORDGetTransactionData (uint8_t convention, uint8_t TC1, const APPINFO *appInfo, ByteArray *offlineAuthData, log_struct_t *logger)
 Retrieves all the Data Objects from the card.
FCITemplateSelectFromAID (uint8_t convention, uint8_t TC1, const ByteArray *aid, log_struct_t *logger)
 Selects application based on AID list.
FCITemplateSelectFromPSE (uint8_t convention, uint8_t TC1, uint8_t sfiPSE, uint8_t autoselect, log_struct_t *logger)
 Selects application based on PSE.
uint8_t VerifyPlaintextPIN (uint8_t convention, uint8_t TC1, const ByteArray *pin, log_struct_t *logger)
 Checks if the specified PIN is accepted by the card.
RAPDUSendGenerateAC (uint8_t convention, uint8_t TC1, AC_REQ_TYPE acType, const TLV *cdol, const GENERATE_AC_PARAMS *params, log_struct_t *logger)
 Send a GENERATE AC request with the specified amounts.
RAPDUSignDynamicData (uint8_t convention, uint8_t TC1, const ByteArray *data, log_struct_t *logger)
 Sign the Dynamic Application Data using INTERNAL AUTHENTICATE.
uint8_t ParsePSD (RECORDList *rlist, const uint8_t *data, uint8_t lenData)
 Extract the available applications from a Payment System Directory.
APPINFOParseApplicationInfo (const uint8_t *data, uint8_t len)
 Returns the AIP and AFL List from the response of GET PROCESSING OPTS.
uint8_t GetSFIFromSELECT (const RAPDU *response)
 Returns the SFI value from the response to a SELECT command.
TLVGetPDOLFromFCI (const FCITemplate *fci)
 Returns the PDOL TLV from a FCI.
TLVGetPDOL (const FCITemplate *fci)
 Returns a PDOL TLV from a FCI or a default one.
ByteArrayGetDataObject (uint8_t convention, uint8_t TC1, CARD_PDO pdo, log_struct_t *logger)
 Return the specified primitive data object from the card.
FCITemplateParseFCI (const uint8_t *data, uint8_t lenData)
 Parse a FCI Template object from a data stream.
TLVParseTLV (const uint8_t *data, uint8_t lenData, uint8_t includeValue)
 Parse a TLV object from a data stream.
TLVCopyTLV (const TLV *data)
 Makes a copy of a TLV.
RECORDParseRECORD (const uint8_t *data, uint8_t lenData)
 Parse a record from a stream of data.
uint8_t AddRECORD (RECORD *dest, const RECORD *src)
 Adds the contents of a record at the end of another one.
TLVGetTLVFromRECORD (RECORD *rec, uint8_t tag1, uint8_t tag2)
 Returns a TLV from a RECORD based on its tag.
RECORDParseManyTLV (const uint8_t *data, uint8_t lenData)
 Parses a data stream containing many TLV objects.
uint8_t AmountPositionInCDOLRecord (const RECORD *record)
 Get the position of the Authorized Amount value inside CDOL1 if exists.
ByteArraySerializeTLV (const TLV *tlv)
 Get a stream of bytes representing a TLV.
void FreeTLV (TLV *data)
 Eliberates the memory used by a TLV structure.
void FreeRECORD (RECORD *data)
 Eliberates the memory used by a RECORD structure.
void FreeRECORDList (RECORDList *data)
 Eliberates the memory used by a RECORDList structure.
void FreeFCITemplate (FCITemplate *data)
 Eliberates the memory used by a FCITemplate structure.
void FreeFCIList (FCIList *data)
 Eliberates the memory used by a FCIList structure.
void FreeAPPINFO (APPINFO *data)
 Eliberates the memory used by an APPINFO structure.

Detailed Description

terminal.c source file for Smartcard Defender

This file implements the functions for a terminal application

Copyright (C) 2012 Omar Choudary (omar.choudary@cl.cam.ac.uk)

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file terminal.c.


Define Documentation

#define DEBUG   1

Set this to 1 to enable debug code.

Definition at line 44 of file terminal.c.

#define TRIGGER   1

Set this to enable trigger signals, e.g. to use with oscilloscope.

Definition at line 47 of file terminal.c.


Function Documentation

uint8_t AddRECORD ( RECORD dest,
const RECORD src 
)

Adds the contents of a record at the end of another one.

This method copies the contents of the RECORD src after the existing contents of the RECORD dest.

Parameters:
destthe RECORD in which the new data from src will be appended
srcthe RECORD containing the data to be copied on dest
Returns:
0 if successful, non-zero otherwise This function allocates the necessary memory for the extra data needed in the dest RECORD object. If there is not sufficient memory (indicated by a non-zero return value) then the contents of this RECORD will be truncated or NULL.

Definition at line 1439 of file terminal.c.

uint8_t AmountPositionInCDOLRecord ( const RECORD record)

Get the position of the Authorized Amount value inside CDOL1 if exists.

This function parses a RECORD structure and searches for the CDOL1 tag. If found, it searches for the position of the Authorized Amount value inside the CDOL1. This function is used in applications like FilterGenerateAC to determine in which place is sent the amount of a transaction

Parameters:
recordRECORD structure to be parsed
Returns:
the position (starting at 1) of the Authorized Amount value inside CDOL1 if found, 0 if unsuccessful

Definition at line 1546 of file terminal.c.

FCITemplate* ApplicationSelection ( uint8_t  convention,
uint8_t  TC1,
const ByteArray aid,
uint8_t  autoselect,
log_struct_t logger 
)

Starts the application selection process.

This function handles the application selection process, where the first choice is the PSE selection and then a list of AIDs. See EMV 4.2 book 1, page 143.

Parameters:
conventionparameter from ATR
TC1parameter from ATR
aidthe AID of the desired application; pass NULL to use existing list
autoselectjust used for the case of PSE selection: use zero to enable user selection, non-zero to automatically select the first available application
loggera pointer to a log structure or NULL if no log is desired
Returns:
the FCI Template resulted from application selection or NULL if there is an error. The caller is responsible for eliberating the memory used by the FCI Template.

Definition at line 248 of file terminal.c.

TLV* CopyTLV ( const TLV data)

Makes a copy of a TLV.

This function copies the contents of a TLV into a new TLV structure

Parameters:
datathe TLV to be copied
Returns:
the new TLV object or NULL if there is an error. This function allocates the necessary memory for the TLV object. It is the caller responsability to free that memory after use.

Definition at line 1369 of file terminal.c.

void FreeAPPINFO ( APPINFO data)

Eliberates the memory used by an APPINFO structure.

Eliberates the memory used by an APPINFO structure

Parameters:
datathe APPINFO structure to be erased

Definition at line 1739 of file terminal.c.

void FreeFCIList ( FCIList data)

Eliberates the memory used by a FCIList structure.

Eliberates the memory used by a FCIList structure

Parameters:
datathe FCIList structure to be erased

Definition at line 1716 of file terminal.c.

void FreeFCITemplate ( FCITemplate data)

Eliberates the memory used by a FCITemplate structure.

Eliberates the memory used by a FCITemplate structure

Parameters:
datathe FCITemplate structure to be erased

Definition at line 1696 of file terminal.c.

void FreeRECORD ( RECORD data)

Eliberates the memory used by a RECORD structure.

Eliberates the memory used by a RECORD structure

Parameters:
datathe RECORD structure to be erased

Definition at line 1648 of file terminal.c.

void FreeRECORDList ( RECORDList data)

Eliberates the memory used by a RECORDList structure.

Eliberates the memory used by a RECORDList structure

Parameters:
datathe RECORDList structure to be erased

Definition at line 1673 of file terminal.c.

void FreeTLV ( TLV data)

Eliberates the memory used by a TLV structure.

Eliberates the memory used by a TLV structure

Parameters:
datathe TLV structure to be erased

Definition at line 1631 of file terminal.c.

ByteArray* GetDataObject ( uint8_t  convention,
uint8_t  TC1,
CARD_PDO  pdo,
log_struct_t logger 
)

Return the specified primitive data object from the card.

This function returns the specified primitive data object (see enum CARD_PDO) from the card using the GET DATA command.

Parameters:
conventionparameter from ATR
TC1parameter from ATR
pdothe kind of data object you want to retrieve (see CARD_PDO)
loggera pointer to a log structure or NULL if no log is desired
Returns:
a ByteArray structure containing the data retrieved or NULL if no data is available or there is an error. The caller is responsible to release the memory used by the ByteArray structure

Definition at line 1194 of file terminal.c.

TLV* GetPDOL ( const FCITemplate fci)

Returns a PDOL TLV from a FCI or a default one.

This method returns a TLV object containing a PDOL from either a FCI Template if the PDOL is available or makes a default one if the FCI Template is NULL or does not contain a PDOL. This method returns the tag as given in the FCI Template (usually '9F38'). In order to use it for GET_PROCESSING_OPTS you need to change to tag to '83'.

Parameters:
fciFCI Template containing or not a PDOL. If NULL then a default PDOL will be returned
Returns:
TLV object contianing a PDOL
See also:
GetPDOLFromFCI

Definition at line 1162 of file terminal.c.

TLV* GetPDOLFromFCI ( const FCITemplate fci)

Returns the PDOL TLV from a FCI.

Returns the PDOL object (TLV) from a FCI such as the one returned in application selection

Parameters:
fciFCI Template to search for the PDOL
Returns:
a pointer to the TLV representing the PDOL or NULL if the PDOL was not found or an error ocurred

Definition at line 1129 of file terminal.c.

uint8_t GetSFIFromSELECT ( const RAPDU response)

Returns the SFI value from the response to a SELECT command.

Parses the SFI value of the main directory (PSE) from the response of the first SELECT command (app selection)

Parameters:
responseRAPDU containing the response to a SELECT command
Returns:
SFI value or 0 if error

Definition at line 1107 of file terminal.c.

TLV* GetTLVFromRECORD ( RECORD rec,
uint8_t  tag1,
uint8_t  tag2 
)

Returns a TLV from a RECORD based on its tag.

This method can be used to find a TLV within a RECORD structure.

Parameters:
recthe RECORD structure to be searched for the TLV
tag1the first (or only) tag of the interested TLV
tag2the second tag of the interested TLV. This is to be used only in cases where the TLV we are looking for has a 2-byte tag. If the tag is only 1 byte then put 0 here.
Returns:
a const pointer to the TLV within the RECORD structure or NULL if the TLV cannot be found or some error occurs

Definition at line 1472 of file terminal.c.

RECORD* GetTransactionData ( uint8_t  convention,
uint8_t  TC1,
const APPINFO appInfo,
ByteArray offlineAuthData,
log_struct_t logger 
)

Retrieves all the Data Objects from the card.

This method retrieves all the Data Objects (TLVs) from the card as specified in the APPINFO structure, using READ RECORD commands. If the pointer to a ByteArray structure is non NULL then the offline authentication data is stored at that location

Parameters:
conventionparameter from ATR
TC1parameter from ATR
appInfothe APPINFO structure that specifies which files to read
offlineAuthDataarray of bytes representing the offline authentication data. The user should send an empty but initialized ByteArray if this data is required. This method will ignore any previous contents.
loggera pointer to a log structure or NULL if no log is desired
Returns:
a RECORD structure containing all the data objects read or NULL if there are no objects to read or an error ocurrs

Definition at line 353 of file terminal.c.

APPINFO* InitializeTransaction ( uint8_t  convention,
uint8_t  TC1,
const FCITemplate fci,
log_struct_t logger 
)

Initialize a transaction by sending GET PROCESSING OPTS command.

This function initiates a transaction by sending a GET PROCESSING OPTS command to the card. The caller is responsible for eliberating the memory used by the returned APPINFO.

Parameters:
conventionparameter from ATR
TC1parameter from ATR
fcithe FCI Template returned in application selection
loggera pointer to a log structure or NULL if no log is desired
Returns:
an APPINFO cotnaining the AIP and AFL or NULL if an error ocurrs

Definition at line 301 of file terminal.c.

APPINFO* ParseApplicationInfo ( const uint8_t *  data,
uint8_t  len 
)

Returns the AIP and AFL List from the response of GET PROCESSING OPTS.

This method parses a stream of data corresponding to the response of GET PROCESSING OPTS command, and returns an APPINFO structure containing the AIP and AFL list.

Parameters:
datathe stream to be parsed
lenthe length of the data to be parsed
Returns:
APPINFO structure containing the AIP and AFL List This function allocates the necessary memory for the APPINFO object. It is the caller responsability to free that memory after use. If the method is not successful it will return NULL.

Definition at line 993 of file terminal.c.

FCITemplate* ParseFCI ( const uint8_t *  data,
uint8_t  lenData 
)

Parse a FCI Template object from a data stream.

This function parses a stream of data and returns a FCI Template if the data is valid

Parameters:
datastream of bytes to be parsed
lenDatatotal length in bytes of data
Returns:
the parsed FCITemplate object. This function allocates the necessary memory for the FCITemplate object. It is the caller responsability to free that memory after use.

Definition at line 1253 of file terminal.c.

RECORD* ParseManyTLV ( const uint8_t *  data,
uint8_t  lenData 
)

Parses a data stream containing many TLV objects.

This method parses a stream of data containing several concatenated TLV objects and fills a RECORD structure

Parameters:
datathe stream to be parsed
lenDatathe length of the data to be parsed
Returns:
RECORD structure containing the TLV objects parsed This function allocates the necessary memory for the RECORD object. It is the caller responsability to free that memory after use. If the method is not successful it will return NULL.

Definition at line 1499 of file terminal.c.

uint8_t ParsePSD ( RECORDList rlist,
const uint8_t *  data,
uint8_t  lenData 
)

Extract the available applications from a Payment System Directory.

This method parses a stream of data corresponding to a Payment System Directory (such as the response to a READ RECORD command on the PSE) and adds it to an existing RECORDList structure containing the available applications as RECORD objects. The current implementation only handles a PSD wihtout directories. That means that it will parse only elements of type ADF, but none of type DDF

Parameters:
rlistRECORDList structure used to store retrieved ADFs. This structure should be initialized before being passed to this method, which will only allocate memory for new records on the list and update the count
datathe stream to be parsed
lenDatathe length of the data to be parsed
Returns:
zero if success, non-zero otherwise This function allocates the necessary memory for the RECORDList object. It is the caller responsability to free that memory after use. If the method is not successful it will return NULL.

Definition at line 950 of file terminal.c.

RECORD* ParseRECORD ( const uint8_t *  data,
uint8_t  lenData 
)

Parse a record from a stream of data.

This method parses a stream of data representing a constructed BER-TLV, such as the response to a READ RECORD command, and fills a RECORD structure

Parameters:
datathe stream to be parsed
lenDatathe length of the data to be parsed
Returns:
RECORD structure containing the TLV objects parsed This function allocates the necessary memory for the RECORD object. It is the caller responsability to free that memory after use. If the method is not successful it will return NULL.

Definition at line 1409 of file terminal.c.

TLV* ParseTLV ( const uint8_t *  data,
uint8_t  lenData,
uint8_t  includeValue 
)

Parse a TLV object from a data stream.

This function parses a stream of data and returns a TLV object if the data contains a valid BER-TLV object

Parameters:
datastream of bytes to be parsed
lenDatatotal length in bytes of data
includeValueif this parameter is 0 then only the tag and length of the TLV are parsed (useful for Data Object Lists). If this parameter is non-zero then also the value of the TLV is returned
Returns:
the parsed TLV object. This function allocates the necessary memory for the TLV object. It is the caller responsability to free that memory after use.

Definition at line 1321 of file terminal.c.

FCITemplate* SelectFromAID ( uint8_t  convention,
uint8_t  TC1,
const ByteArray aid,
log_struct_t logger 
)

Selects application based on AID list.

This function handles the application selection by AID. For the moment it automatically selects the first available application, based on the bAIDList configuration, but this could be improved by actually storing a list of available applications and allowing the user to choose.

Parameters:
conventionparameter from ATR
TC1parameter from ATR
aidif given will be used as Application ID (AID), else use predefined list. This parameter remains untouched
loggera pointer to a log structure or NULL if no log is desired
Returns:
the FCI Template resulted from application selection or NULL if there is an error. The caller is responsible for eliberating the memory used by the FCI Template.
See also:
ApplicationSelection

Definition at line 477 of file terminal.c.

FCITemplate* SelectFromPSE ( uint8_t  convention,
uint8_t  TC1,
uint8_t  sfiPSE,
uint8_t  autoselect,
log_struct_t logger 
)

Selects application based on PSE.

This function handles the application selection by PSE.

Parameters:
conventionparameter from ATR
TC1parameter from ATR
sfiPSEthe SFI of the PSE as returned from an initial SELECT command
autoselectif non-zero the first application will be used, else the user will select from a menu (LCD needed).
loggera pointer to a log structure or NULL if no log is desired
Returns:
the FCI Template resulted from application selection or NULL if there is an error. The caller is responsible for eliberating the memory used by the FCI Template.
See also:
ApplicationSelection

Definition at line 558 of file terminal.c.

RAPDU* SendGenerateAC ( uint8_t  convention,
uint8_t  TC1,
AC_REQ_TYPE  acType,
const TLV cdol,
const GENERATE_AC_PARAMS params,
log_struct_t logger 
)

Send a GENERATE AC request with the specified amounts.

This function sends a GENERATE AC command to the card with the specified amount and request (ARQC, AAC or TC) Any of the amount parameters can be sent as NULL in which case that field will be filled with zeros

Parameters:
conventionparameter from ATR
TC1parameter from ATR
cdolthe CDOL data object read from the card
acTypethe type of Applicatio Cryptogram (AC) requested (see AC_REQ_TYPE)
paramsa GENERATE_AC_PARAMS structure containing the data to be sent in the GENERATE AC command. This structure is mandatory for this command, even if some of the fields are unused.
loggera pointer to a log structure or NULL if no log is desired
Returns:
the response APDU given by the card or NULL if an error ocurred. The caller is responsible for eliberating this memory.

Definition at line 717 of file terminal.c.

ByteArray* SerializeTLV ( const TLV tlv)

Get a stream of bytes representing a TLV.

This method converts a TLV object into a stream of bytes, copying the contents of the TLV into the ByteArray. The caller is responsible for eliberating the memory used by the ByteArray returned.

Parameters:
tlvTLV object to serialize
Returns:
the stream of bytes representing the TLV

Definition at line 1592 of file terminal.c.

RAPDU* SignDynamicData ( uint8_t  convention,
uint8_t  TC1,
const ByteArray data,
log_struct_t logger 
)

Sign the Dynamic Application Data using INTERNAL AUTHENTICATE.

This function is used to make the card sign the Dynamic Application Data using the INTERNAL AUTHENTICATE command. This data is composed of some ICC-resident data and the data passed to this methdo.

Parameters:
conventionparameter from ATR
TC1parameter from ATR
dataByteArray structure containing the data that shall be passed to the INTERNAL AUTHENTICATE command
loggera pointer to a log structure or NULL if no log is desired
Returns:
the response APDU given by the card or NULL if an error ocurred. The caller is responsible for eliberating this memory.

Definition at line 914 of file terminal.c.

RAPDU* TerminalSendT0Command ( CAPDU cmd,
uint8_t  inverse_convention,
uint8_t  TC1,
log_struct_t logger 
)

This function sends a T=0 command from the terminal to the ICC.

This function handles the process of sending a command for the protocol T=0, including the intermediate GET_RESPONSE for the different command classes. Because of the recursivity of this method, it introduces an initial delay of 16 ICC ETUs to allow the card to be ready for a new command

Parameters:
cmdCommand APDU to be sent
inverse_conventiondifferent than 0 if inverse convention is to be used
TC1byte returned in the ATR
loggera pointer to a log structure or NULL if no log is desired
Returns:
the RAPDU created from the card reply, or NULL if a response APDU cannot be constructed

Definition at line 92 of file terminal.c.

uint8_t VerifyPlaintextPIN ( uint8_t  convention,
uint8_t  TC1,
const ByteArray pin,
log_struct_t logger 
)

Checks if the specified PIN is accepted by the card.

This function tests if the specified PIN is accepted by the card using the VERIFY command

Parameters:
conventionparameter from ATR
TC1parameter from ATR
pinthe PIN as a ByteArray having the structure required by the VERIFY command. The data in the ByteArray will be copied as it is on the VERIFY payload
loggera pointer to a log structure or NULL if no log is desired
Returns:
0 if the PIN is correct, non-zero otherwise or if an error ocurred

Definition at line 666 of file terminal.c.

 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines