#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "emv.h"
Go to the source code of this file.
Defines | |
#define | DEBUG 0 |
Functions | |
EMVCommandHeader * | MakeCommandHeader (uint8_t cla, uint8_t ins, uint8_t p1, uint8_t p2, uint8_t p3) |
This function will return a command header structure. | |
EMVCommandHeader * | MakeCommandHeaderC (EMV_CMD command) |
This function will return a command header structure. | |
CAPDU * | MakeCommand (uint8_t cla, uint8_t ins, uint8_t p1, uint8_t p2, uint8_t p3, const uint8_t cmdData[], uint8_t lenData) |
This function will return a command APDU (CAPDU) structure. | |
CAPDU * | MakeCommandP (const EMVCommandHeader *cmdHdr, const uint8_t cmdData[], uint8_t lenData) |
This function will return a command APDU (CAPDU) structure. | |
CAPDU * | MakeCommandC (EMV_CMD command, const uint8_t cmdData[], uint8_t lenData) |
This function will return a command APDU (CAPDU) structure. | |
uint8_t | InitSCDTransaction (uint8_t t_inverse, uint8_t t_TC1, uint8_t *inverse_convention, uint8_t *proto, uint8_t *TC1, uint8_t *TA3, uint8_t *TB3) |
Initiates the communication with both the ICC and terminal for T=0. | |
uint8_t | GetCommandCase (uint8_t cla, uint8_t ins) |
Returns the command case from the command header. | |
EMVCommandHeader * | ReceiveT0CmdHeader (uint8_t inverse_convention, uint8_t TC1) |
Receive a command header from the terminal using protocol T=0. | |
uint8_t * | ReceiveT0CmdData (uint8_t inverse_convention, uint8_t TC1, uint8_t len) |
Receive a command data from the terminal using protocol T=0. | |
CAPDU * | ReceiveT0Command (uint8_t inverse_convention, uint8_t TC1) |
Receive a command (including data) from the terminal using protocol T=0. | |
uint8_t | SendT0CmdHeader (uint8_t inverse_convention, uint8_t TC1, EMVCommandHeader *cmdHeader) |
Send a command header to the ICC using protocol T=0. | |
uint8_t | SendT0CmdData (uint8_t inverse_convention, uint8_t TC1, uint8_t *cmdData, uint8_t len) |
Send a command data to the ICC using protocol T=0. | |
uint8_t | SendT0Command (uint8_t inverse_convention, uint8_t TC1, CAPDU *cmd) |
Send a command (including data) to the ICC using protocol T=0. | |
CAPDU * | ForwardCommand (uint8_t tInverse, uint8_t cInverse, uint8_t tTC1, uint8_t cTC1) |
Forwards a command from the terminal to the ICC for T=0. | |
uint8_t * | SerializeCommand (CAPDU *cmd, uint8_t *len) |
Serialize a CAPDU structure. | |
RAPDU * | ReceiveT0Response (uint8_t inverse_convention, EMVCommandHeader *cmdHeader) |
Receive response from ICC for T=0. | |
uint8_t | SendT0Response (uint8_t inverse_convention, EMVCommandHeader *cmdHeader, RAPDU *response) |
Send a response to the terminal. | |
RAPDU * | ForwardResponse (uint8_t tInverse, uint8_t cInverse, EMVCommandHeader *cmdHeader) |
Forwards a response from the ICC to the terminal. | |
uint8_t * | SerializeResponse (RAPDU *response, uint8_t *len) |
Serialize a RAPDU structure. | |
CRP * | ExchangeData (uint8_t tInverse, uint8_t cInverse, uint8_t tTC1, uint8_t cTC1) |
Makes a command-response exchange between terminal and ICC. | |
CRP * | ExchangeCompleteData (uint8_t tInverse, uint8_t cInverse, uint8_t tTC1, uint8_t cTC1) |
Makes a complete command-response exchange between terminal and ICC. | |
ByteArray * | MakeByteArray (uint8_t *data, uint8_t len) |
Encapsulates data in a ByteArray structure. | |
ByteArray * | MakeByteArrayV (uint8_t nargs,...) |
Creates a ByteArray structure from values. | |
ByteArray * | CopyByteArray (const uint8_t *data, uint8_t len) |
Copies data into a ByteArray structure. | |
void | FreeByteArray (ByteArray *data) |
Eliberates the memory used by a ByteArray. | |
void | FreeCAPDU (CAPDU *cmd) |
Eliberates the memory used by a CAPDU. | |
CAPDU * | CopyCAPDU (CAPDU *cmd) |
Makes a copy of a CAPDU. | |
void | FreeRAPDU (RAPDU *response) |
Eliberates the memory used by a RAPDU. | |
RAPDU * | CopyRAPDU (RAPDU *resp) |
Makes a copy of a RAPDU. | |
void | FreeCRP (CRP *data) |
Eliberates the memory used by a CRP. |
emv.c source file
Contains the implementation of functions used to implement the EMV standard
Copyright (C) 2010 Omar Choudary (osc22@cam.ac.uk)
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
Definition in file emv.c.
ByteArray* CopyByteArray | ( | const uint8_t * | data, | |
uint8_t | len | |||
) |
Copies data into a ByteArray structure.
Create a ByteArray structure. This method copies the data to the ByteArray structure which means that the caller is responsible to eliberate the memory
data | the bytes to be copied to the structure | |
len | the length of the byte array |
CRP* ExchangeCompleteData | ( | uint8_t | tInverse, | |
uint8_t | cInverse, | |||
uint8_t | tTC1, | |||
uint8_t | cTC1 | |||
) |
Makes a complete command-response exchange between terminal and ICC.
This method exchange command-response pairs between terminal and ICC, similar to ExchangeData. However this method forwards data repeatedly until the response contains a success or error. The method returns the initial command and the final response. Intermediate stages are removed. If you need those stages use ExchangeData instead.
tInverse | different than 0 if inverse convention is to be used with the terminal | |
cInverse | different than 0 if inverse convention is to be used with the ICC | |
tTC1 | byte TC1 of ATR used with terminal | |
cTC1 | byte TC1 of ATR received from ICC |
CRP* ExchangeData | ( | uint8_t | tInverse, | |
uint8_t | cInverse, | |||
uint8_t | tTC1, | |||
uint8_t | cTC1 | |||
) |
Makes a command-response exchange between terminal and ICC.
This method sends a command from the terminal to the ICC and also returns to the terminal the answer from the ICC. Both the command and the response are returned to the caller.
tInverse | different than 0 if inverse convention is to be used with the terminal | |
cInverse | different than 0 if inverse convention is to be used with the ICC | |
tTC1 | byte TC1 of ATR used with terminal | |
cTC1 | byte TC1 of ATR received from ICC |
CAPDU* ForwardCommand | ( | uint8_t | tInverse, | |
uint8_t | cInverse, | |||
uint8_t | tTC1, | |||
uint8_t | cTC1 | |||
) |
Forwards a command from the terminal to the ICC for T=0.
Receive a command from the terminal and then send it to the ICC
tInverse | different than 0 if inverse convention is to be used with the terminal | |
cInverse | different than 0 if inverse convention is to be used with the ICC | |
tTC1 | the N parameter from byte TC1 of ATR used with terminal | |
cTC1 | the N parameter from byte TC1 of ATR received from ICC |
RAPDU* ForwardResponse | ( | uint8_t | tInverse, | |
uint8_t | cInverse, | |||
EMVCommandHeader * | cmdHeader | |||
) |
Forwards a response from the ICC to the terminal.
Receive a response from the terminal and then send it to the terminal
tInverse | different than 0 if inverse convention is to be used with the terminal | |
cInverse | different than 0 if inverse convention is to be used with the ICC | |
cmdHeader | the header of the command for which response is expected |
void FreeByteArray | ( | ByteArray * | data | ) |
void FreeCAPDU | ( | CAPDU * | cmd | ) |
void FreeCRP | ( | CRP * | data | ) |
void FreeRAPDU | ( | RAPDU * | response | ) |
uint8_t GetCommandCase | ( | uint8_t | cla, | |
uint8_t | ins | |||
) |
Returns the command case from the command header.
Returns the case of an EMV command based on the header
The significance of the case is given by this table:
case | command data | response data 1 | absent | absent 2 | absent | present 3 | present | absent 4 | present | present
cla | byte CLA | |
ins | byte INS |
uint8_t InitSCDTransaction | ( | uint8_t | t_inverse, | |
uint8_t | t_TC1, | |||
uint8_t * | inverse_convention, | |||
uint8_t * | proto, | |||
uint8_t * | TC1, | |||
uint8_t * | TA3, | |||
uint8_t * | TB3 | |||
) |
Initiates the communication with both the ICC and terminal for T=0.
This function is used as a starting point to start the communication between the terminal and the SCD and between the SCD and the ICC at the same time
If the function returs 0 (success) then both the terminal and the ICC should be in a good state, where the terminal is about to send the first command and the ICC is waiting for a command
This function assumes that the ICC was placed in the ICC holder before being called and it will loop until the terminal provides clock
t_inverse | specifies if direct(0) or inverse(non-zero) convention should be used in the communication with the terminal. Only direct convention should be used as specified in the standard. | |
t_TC1 | specifies the TC1 byte of the ATR sent to the terminal. This should be as small as possible in order to limit the latency of communication or large if a specific timeout between bytes is desired. | |
inverse_convention | direct (0) or inverse convention (1) is used by the ICC, as returned in the ATR | |
proto | protocol (T=0 or T=1) as returned by the ICC in the ATR | |
TC1 | as returned by the ICC in the ATR | |
TA3 | as returned by the ICC in the ATR | |
TB3 | as returned by the ICC in the ATR |
ByteArray* MakeByteArray | ( | uint8_t * | data, | |
uint8_t | len | |||
) |
Encapsulates data in a ByteArray structure.
Create a ByteArray structure. This method just links the data to the ByteArray structure which means that eliberating the data (calling free) of the ByteArray will have an effect on the data passed to this method.
data | the bytes to be linked to the structure | |
len | the length of the byte array |
ByteArray* MakeByteArrayV | ( | uint8_t | nargs, | |
... | ||||
) |
Creates a ByteArray structure from values.
Create a ByteArray structure. This method creates the structure based on the values directly passed to this method.
nargs | the number of values passed to this method | |
... | the variable number of values given |
CAPDU* MakeCommand | ( | uint8_t | cla, | |
uint8_t | ins, | |||
uint8_t | p1, | |||
uint8_t | p2, | |||
uint8_t | p3, | |||
const uint8_t | cmdData[], | |||
uint8_t | lenData | |||
) |
This function will return a command APDU (CAPDU) structure.
Makes a command APDU (CAPDU) for T=0 protocol
cla | byte CLA | |
ins | byte INS | |
p1 | byte P1 | |
p2 | byte P2 | |
p3 | byte P3. This value is not modified automatically to the value of lenData even if cmdData is not NULL. The caller needs to take care of this or use MakeCommandC instead | |
cmdData | command data. The data pointed by cmdData will be copied into the new CAPDU so the caller is responsible for handling the original cmdData | |
lenData | length in bytes of cmdData |
This function will return a command APDU (CAPDU) structure.
Makes a command APDU (CAPDU) for T=0 protocol. This method creates sets the default values based on the command type (see EMV_CMD). Also, the parameter p3 of the command header is given the value of lenData if cmdData is not NULL.
command | The speified command using the enum EMV_CMD. This function will create the default command header based on this. | |
cmdData | command data. The data pointed by cmdData will be copied into the new CAPDU so the caller is responsible for handling the original cmdData | |
lenData | length in bytes of cmdData |
EMVCommandHeader* MakeCommandHeader | ( | uint8_t | cla, | |
uint8_t | ins, | |||
uint8_t | p1, | |||
uint8_t | p2, | |||
uint8_t | p3 | |||
) |
This function will return a command header structure.
Makes a command header for T=0 protocol
cla | byte CLA | |
ins | byte INS | |
p1 | byte P1 | |
p2 | byte P2 | |
p3 | byte P3 |
EMVCommandHeader* MakeCommandHeaderC | ( | EMV_CMD | command | ) |
This function will return a command header structure.
Makes a command header for a given command. This function populates the command bytes with default values, where P3 is always 0. Calling functions should make sure to modify these bytes to the correct values.
command | type of command requested (see EMV_CMD) |
CAPDU* MakeCommandP | ( | const EMVCommandHeader * | cmdHdr, | |
const uint8_t | cmdData[], | |||
uint8_t | lenData | |||
) |
This function will return a command APDU (CAPDU) structure.
Makes a command APDU (CAPDU) for T=0 protocol. The difference to MakeCommand is that it takes a pointer to an EMVCommandHeader structure instead of values
cmdHdr | command header. The data pointed by cmdHdr will be copied into the new CAPDU so the caller is responsible for handling the original cmdHdr | |
cmdData | command data. The data pointed by cmdData will be copied into the new CAPDU so the caller is responsible for handling the original cmdData | |
lenData | length in bytes of cmdData |
uint8_t* ReceiveT0CmdData | ( | uint8_t | inverse_convention, | |
uint8_t | TC1, | |||
uint8_t | len | |||
) |
Receive a command data from the terminal using protocol T=0.
Receive a command data from terminal for protocol T = 0
inverse_convention | different than 0 if inverse convention is to be used | |
TC1 | the N parameter received in byte TC1 of ATR |
len | lenght in bytes of command data expected |
EMVCommandHeader* ReceiveT0CmdHeader | ( | uint8_t | inverse_convention, | |
uint8_t | TC1 | |||
) |
Receive a command header from the terminal using protocol T=0.
Receive a response from ICC for protocol T = 0
inverse_convention | different than 0 if inverse convention is to be used | |
TC1 | the N parameter received in byte TC1 of ATR |
CAPDU* ReceiveT0Command | ( | uint8_t | inverse_convention, | |
uint8_t | TC1 | |||
) |
Receive a command (including data) from the terminal using protocol T=0.
Receive a command (including data) from terminal for protocol T = 0. For command cases 3 and 4 a procedure byte is sent back to the terminal to obtain the command data
inverse_convention | different than 0 if inverse convention is to be used | |
TC1 | the N parameter received in byte TC1 of ATR |
RAPDU* ReceiveT0Response | ( | uint8_t | inverse_convention, | |
EMVCommandHeader * | cmdHeader | |||
) |
Receive response from ICC for T=0.
This method receives a response from ICC for protocol T = 0. If [SW1,SW2] != [0x90,0] then the response is not complete. Either another command (e.g. get response) is expected, or the previous command with different lc, or an error has occurred. If [SW1,SW2] returned are '9000' then the command is successful and it will also contain data if this was expected. Different codes for the return codes can be found in EMV Book 1 and Book 3.
inverse_convention | different than 0 if inverse convention is to be used | |
cmdHeader | the header of the command for which response is expected |
uint8_t SendT0CmdData | ( | uint8_t | inverse_convention, | |
uint8_t | TC1, | |||
uint8_t * | cmdData, | |||
uint8_t | len | |||
) |
Send a command data to the ICC using protocol T=0.
Send a command data to the ICC for protocol T = 0
inverse_convention | different than 0 if inverse convention is to be used | |
TC1 | the N parameter received in byte TC1 of ATR | |
cmdData | command data to be sent | |
len | lenght in bytes of command data to be sent |
uint8_t SendT0CmdHeader | ( | uint8_t | inverse_convention, | |
uint8_t | TC1, | |||
EMVCommandHeader * | cmdHeader | |||
) |
Send a command header to the ICC using protocol T=0.
Send a command header to the ICC for protocol T = 0
inverse_convention | different than 0 if inverse convention is to be used | |
TC1 | the N parameter received in byte TC1 of ATR | |
cmdHeader | command header to be sent |
uint8_t SendT0Command | ( | uint8_t | inverse_convention, | |
uint8_t | TC1, | |||
CAPDU * | cmd | |||
) |
Send a command (including data) to the ICC using protocol T=0.
Send a command (including data) to the ICC for protocol T = 0. For command cases 3 and 4 a procedure byte(s) is expected back before sending the data
inverse_convention | different than 0 if inverse convention is to be used | |
TC1 | the N parameter received in byte TC1 of ATR | |
cmd | command to be sent |
uint8_t SendT0Response | ( | uint8_t | inverse_convention, | |
EMVCommandHeader * | cmdHeader, | |||
RAPDU * | response | |||
) |
Send a response to the terminal.
Send a response (including data) to the terminal for protocol T = 0. Data (if available) is sent with a procedure byte prepended
inverse_convention | different than 0 if inverse convention is to be used | |
cmdHeader | header of command for which response is being sent | |
response | RAPDU containing the response to be sent |
uint8_t* SerializeCommand | ( | CAPDU * | cmd, | |
uint8_t * | len | |||
) |
Serialize a CAPDU structure.
This function serializes (converts to a sequence of bytes) a CAPDU structure.
cmd | command to be serialized | |
len | length of the resulted byte stream |
uint8_t* SerializeResponse | ( | RAPDU * | response, | |
uint8_t * | len | |||
) |
Serialize a RAPDU structure.
This function serializes (converts to a sequence of bytes) a RAPDU structure.
response | response to be serialized | |
len | length of the resulted byte stream |