The Smart Card Detective (SCD)
emv.c
Go to the documentation of this file.
00001 
00034 #include <avr/io.h>
00035 #include <avr/interrupt.h>
00036 #include <avr/sleep.h>
00037 #include <avr/power.h>
00038 #include <util/delay.h>
00039 #include <string.h>
00040 #include <stdlib.h>
00041 #include <stdarg.h>
00042 
00043 #include "emv.h"
00044 #include "scd_hal.h"
00045 #include "scd_io.h"
00046 #include "emv_values.h"
00047 #include "scd_values.h"
00048 #include "counter.h"
00049 
00050 #define DEBUG 1   // Set DEBUG to 1 to enable debug code
00051 
00052 
00066 uint8_t ResetICC(
00067         uint8_t warm,
00068         uint8_t *inverse_convention,
00069         uint8_t *proto,
00070         uint8_t *TC1,
00071         uint8_t *TA3,
00072         uint8_t *TB3,
00073         log_struct_t *logger)
00074 {
00075     uint32_t time;
00076     uint16_t atr_selection;
00077     uint8_t atr_bytes[32];
00078     uint8_t atr_tck;
00079     uint8_t icc_T0, icc_TS;
00080     uint8_t error;
00081 
00082     // Activate the ICC
00083     time = GetCounter();
00084     error = ActivateICC(warm);
00085     if(error)
00086     {
00087         error = RET_ICC_INIT_ACTIVATE;
00088         goto enderror;
00089     }
00090     if(logger)
00091     {
00092         LogByte4(
00093                 logger,
00094                 LOG_TIME_GENERAL,
00095                 (time & 0xFF),
00096                 ((time >> 8) & 0xFF),
00097                 ((time >> 16) & 0xFF),
00098                 ((time >> 24) & 0xFF));
00099         LogByte1(logger, LOG_ICC_ACTIVATED, 0);
00100     }
00101 
00102     // Wait for approx 42000 ICC clocks = 112 ETUs
00103     LoopICCETU(112);
00104 
00105     // Set RST to high
00106     SetICCResetLine(1);
00107     if(logger)
00108         LogByte1(logger, LOG_ICC_RST_HIGH, 0);
00109 
00110     // Wait for ATR from ICC for a maximum of 42000 ICC clock cycles + 40 ms
00111     if(WaitForICCData(ICC_RST_WAIT))
00112     {
00113         if(warm == 0)
00114             return ResetICC(1, inverse_convention, proto, TC1, TA3, TB3, logger);
00115 
00116         error = RET_ICC_INIT_RESPONSE;
00117         goto enderror;
00118     }
00119 
00120     // Get ATR
00121     error = GetATRICC(
00122             inverse_convention, proto, &icc_TS, &icc_T0,
00123             &atr_selection, atr_bytes, &atr_tck, logger);
00124     if(error)
00125     {
00126         if(warm == 0)
00127             return ResetICC(1, inverse_convention, proto, TC1, TA3, TB3, logger);
00128         goto enderror;
00129     }
00130     *TC1 = atr_bytes[2];
00131     *TA3 = atr_bytes[8];
00132     *TB3 = atr_bytes[9];
00133 
00134     return 0;
00135 
00136 enderror:
00137     DeactivateICC();
00138     if(logger)
00139         LogByte1(logger, LOG_ICC_DEACTIVATED, 0);
00140 
00141     return error;
00142 }
00143 
00144 
00145 /* T=0 protocol functions */
00146 /* All commands are received from the terminal and sent to the ICC */
00147 /* All responses are received from the ICC and sent to the terminal */
00148 
00160 void SendT0ATRTerminal(
00161     uint8_t inverse_convention,
00162     uint8_t TC1,
00163     log_struct_t *logger)
00164 {
00165     if(inverse_convention)
00166     {
00167         SendByteTerminalNoParity(0x3F, inverse_convention);
00168         if(logger)
00169           LogByte1(logger, LOG_BYTE_ATR_TO_TERMINAL, 0x3F);
00170     }
00171     else
00172     {
00173         SendByteTerminalNoParity(0x3B, inverse_convention);
00174         if(logger)
00175           LogByte1(logger, LOG_BYTE_ATR_TO_TERMINAL, 0x3B);
00176     }
00177 
00178     LoopTerminalETU(250);
00179     SendByteTerminalNoParity(0x60, inverse_convention);
00180     if(logger)
00181       LogByte1(logger, LOG_BYTE_ATR_TO_TERMINAL, 0x60);
00182     LoopTerminalETU(2);
00183     SendByteTerminalNoParity(0x00, inverse_convention);
00184     if(logger)
00185       LogByte1(logger, LOG_BYTE_ATR_TO_TERMINAL, 0x00);
00186     LoopTerminalETU(2);
00187     SendByteTerminalNoParity(TC1, inverse_convention);
00188     if(logger)
00189       LogByte1(logger, LOG_BYTE_ATR_TO_TERMINAL, TC1);
00190     LoopTerminalETU(2);
00191 }
00192 
00219 uint8_t GetATRICC(
00220         uint8_t *inverse_convention,
00221         uint8_t *proto,
00222         uint8_t *TS,
00223         uint8_t *T0,
00224         uint16_t *selection,
00225         uint8_t bytes[32],
00226         uint8_t *tck,
00227         log_struct_t *logger)
00228 {   
00229     uint8_t history, i, ta, tb, tc, td, nb;
00230     uint8_t check = 0; // used only for T=1
00231     uint8_t error, index;
00232 
00233     if(inverse_convention == NULL ||
00234             proto == NULL || TS == NULL || T0 == NULL ||
00235             selection == NULL || bytes == NULL || tck == NULL)
00236     {
00237         error = RET_ERR_PARAM;
00238         goto enderror;
00239     }
00240 
00241     *selection = 0;
00242     memset(bytes, 0, 32);
00243 
00244     // Get TS
00245     GetByteICCNoParity(0, TS);
00246     if(logger)
00247         LogByte1(logger, LOG_BYTE_ATR_FROM_ICC, *TS);
00248     if(*TS == 0x3B) *inverse_convention = 0;
00249     else if(*TS == 0x03) *inverse_convention = 1;
00250     else
00251     {
00252         error = RET_ICC_INIT_ATR_TS;
00253         goto enderror;
00254     }
00255 
00256     // Get T0
00257     error = GetByteICCNoParity(*inverse_convention, T0);
00258     if(error)
00259         goto enderror;
00260     if(logger)
00261         LogByte1(logger, LOG_BYTE_ATR_FROM_ICC, *T0);
00262     check ^= *T0;
00263     history = *T0 & 0x0F;
00264     ta = *T0 & 0x10;
00265     tb = *T0 & 0x20;
00266     tc = *T0 & 0x40;
00267     td = *T0 & 0x80;
00268     if(tb == 0)
00269     {
00270         error = RET_ICC_INIT_ATR_T0;
00271         goto enderror;
00272     }
00273 
00274     index = 0;
00275     if(ta){
00276         // Get TA1, coded as [FI, DI], where FI and DI are used to derive
00277         // the work etu. ETU = (1/D) * (F/f) where f is the clock frequency.
00278         // From ISO/IEC 7816-3 pag 12, F and D are mapped to FI/DI as follows:
00279         //
00280         // FI:  0x1  0x2  0x3  0x4  0x5  0x6  0x9  0xA  0xB  0xC  0xD
00281         // F:   372  558  744  1116 1488 1860 512  768  1024 1536 2048 
00282         //
00283         // DI:  0x1 0x2 0x3 0x4 0x5 0x6 0x8 0x9 0xA 0xB 0xC 0xD  0xE  0xF
00284         // D:   1   2   4   8   16  32  12  20  1/2 1/4 1/8 1/16 1/32 1/64
00285         //
00286         // For the moment the SCD only works with D = 1, F = 372
00287         // which should be used even for different values of TA1 if the
00288         // negotiable mode of operation is selected (abscence of TA2)
00289         error = GetByteICCNoParity(*inverse_convention, &bytes[index]);
00290         if(error)
00291             goto enderror;
00292         if(logger)
00293             LogByte1(logger, LOG_BYTE_ATR_FROM_ICC, bytes[index]);
00294         check ^= bytes[index];
00295         *selection |= (1 << (15-index));
00296     }
00297     index++;
00298 
00299     // Get TB1
00300     error = GetByteICCNoParity(*inverse_convention, &bytes[index]);
00301     if(error)
00302         goto enderror;
00303     if(logger)
00304         LogByte1(logger, LOG_BYTE_ATR_FROM_ICC, bytes[index]);
00305     check ^= bytes[index];
00306     *selection |= (1 << (15-index));
00307     if(bytes[index] != 0)
00308     {
00309         error = RET_ICC_INIT_ATR_TB1;
00310         goto enderror;
00311     }
00312     index++;
00313 
00314     // Get TC1
00315     if(tc)
00316     {
00317         error = GetByteICCNoParity(*inverse_convention, &bytes[index]);
00318         if(error)
00319             goto enderror;
00320         if(logger)
00321             LogByte1(logger, LOG_BYTE_ATR_FROM_ICC, bytes[index]);
00322         check ^= bytes[index];
00323         *selection |= (1 << (15-index));
00324     }
00325     index++;
00326 
00327     if(td){
00328         // Get TD1
00329         error = GetByteICCNoParity(*inverse_convention, &bytes[index]);
00330         if(error)
00331             goto enderror;
00332         if(logger)
00333             LogByte1(logger, LOG_BYTE_ATR_FROM_ICC, bytes[index]);
00334         check ^= bytes[index];
00335         *selection |= (1 << (15-index));
00336         nb = bytes[index] & 0x0F;
00337         ta = bytes[index] & 0x10;
00338         tb = bytes[index] & 0x20;
00339         tc = bytes[index] & 0x40;
00340         td = bytes[index] & 0x80;
00341         if(nb == 0x01) *proto = 1;
00342         else if(nb == 0x00) *proto = 0;
00343         else
00344         {
00345             error = RET_ICC_INIT_ATR_TD1;
00346             goto enderror;
00347         }
00348         index++;
00349 
00350         // The SCD does not currently support specific modes of operation.
00351         // Perhaps we can trigger a PTS selection or reset in the future.
00352         if(ta)
00353         {
00354             error = RET_ICC_INIT_ATR_TA2;
00355             goto enderror;
00356         }
00357         index++;
00358 
00359         if(tb)
00360         {
00361             error = RET_ICC_INIT_ATR_TB2;
00362             goto enderror;
00363         }
00364         index++;
00365 
00366         if(tc){
00367             // Get TC2
00368             error = GetByteICCNoParity(*inverse_convention, &bytes[index]);
00369             if(error)
00370                 goto enderror;
00371             if(logger)
00372                 LogByte1(logger, LOG_BYTE_ATR_FROM_ICC, bytes[index]);
00373             check ^= bytes[index];
00374             *selection |= (1 << (15-index));
00375             if(bytes[index] != 0x0A)
00376             {
00377                 error = RET_ICC_INIT_ATR_TC2;
00378                 goto enderror;
00379             }
00380         }
00381         index++;
00382 
00383         if(td){
00384             // Get TD2
00385             error = GetByteICCNoParity(*inverse_convention, &bytes[index]);
00386             if(error)
00387                 goto enderror;
00388             if(logger)
00389                 LogByte1(logger, LOG_BYTE_ATR_FROM_ICC, bytes[index]);
00390             check ^= bytes[index];
00391             *selection |= (1 << (15-index));
00392             nb = bytes[index] & 0x0F;
00393             ta = bytes[index] & 0x10;
00394             tb = bytes[index] & 0x20;
00395             tc = bytes[index] & 0x40;
00396             td = bytes[index] & 0x80;
00397             index++;
00398             // we allow any value of nb although EMV restricts to some values
00399             // these values could be used if we implement PTS
00400 
00401             if(ta)
00402             {
00403                 // Get TA3
00404                 error = GetByteICCNoParity(*inverse_convention, &bytes[index]);
00405                 if(error)
00406                     goto enderror;
00407                 if(logger)
00408                     LogByte1(logger, LOG_BYTE_ATR_FROM_ICC, bytes[index]);
00409                 check ^= bytes[index];
00410                 *selection |= (1 << (15-index));
00411                 if(bytes[index] < 0x0F || bytes[index] == 0xFF)
00412                 {
00413                     error = RET_ICC_INIT_ATR_TA3;
00414                     goto enderror;
00415                 }
00416             }
00417             else
00418                 bytes[index] = 0x20;
00419             index++;
00420 
00421             if(*proto == 1 && tb == 0)
00422             {
00423                 error = RET_ICC_INIT_ATR_TB3;
00424                 goto enderror;
00425             }
00426 
00427             if(tb)
00428             {
00429                 // Get TB3
00430                 error = GetByteICCNoParity(*inverse_convention, &bytes[index]);
00431                 if(logger)
00432                     LogByte1(logger, LOG_BYTE_ATR_FROM_ICC, bytes[index]);
00433                 check ^= bytes[index];
00434                 *selection |= (1 << (15-index));
00435                 nb = bytes[index] & 0x0F;
00436                 if(nb > 5)
00437                 {
00438                     error = RET_ICC_INIT_ATR_TB3;
00439                     goto enderror;
00440                 }
00441                 nb = bytes[index] & 0xF0;
00442                 if(nb > 64)
00443                 {
00444                     error = RET_ICC_INIT_ATR_TB3;
00445                     goto enderror;
00446                 }
00447             }
00448             index++;
00449 
00450             if(*proto == 0 && tc != 0)
00451             {
00452                 error = RET_ICC_INIT_ATR_TC3;
00453                 goto enderror;
00454             }
00455             if(tc)
00456             {
00457                 // Get TC3
00458                 error = GetByteICCNoParity(*inverse_convention, &bytes[index]);
00459                 if(error)
00460                     goto enderror;
00461                 if(logger)
00462                     LogByte1(logger, LOG_BYTE_ATR_FROM_ICC, bytes[index]);
00463                 check ^= bytes[index];
00464                 *selection |= (1 << (15-index));
00465                 if(bytes[index] != 0)
00466                 {
00467                     error = RET_ICC_INIT_ATR_TC3;
00468                     goto enderror;
00469                 }
00470             }
00471             index++;
00472         }
00473     }
00474     else
00475         *proto = 0;
00476 
00477     // Get historical bytes
00478     index = 16;
00479     for(i = 0; i < history; i++)
00480     {
00481         error = GetByteICCNoParity(*inverse_convention, &bytes[index + i]);
00482         if(logger)
00483             LogByte1(logger, LOG_BYTE_ATR_FROM_ICC, bytes[index + i]);
00484         check ^= bytes[index + i];
00485     }
00486 
00487     // get TCK if T=1 is used
00488     if(*proto == 1)
00489     {
00490         error = GetByteICCNoParity(*inverse_convention, tck);
00491         if(error)
00492             goto enderror;
00493         if(logger)
00494             LogByte1(logger, LOG_BYTE_ATR_FROM_ICC, *tck);
00495         check ^= *tck;
00496         if(check != 0)
00497         {
00498             error = RET_ICC_INIT_ATR_T1_CHECK;
00499             goto enderror;
00500         }
00501     }
00502 
00503     error = 0;
00504 
00505 enderror:
00506     return error;
00507 }
00508 
00509 
00510 
00511 
00525 EMVCommandHeader* MakeCommandHeader(uint8_t cla, uint8_t ins, uint8_t p1, 
00526                                                 uint8_t p2, uint8_t p3)
00527 {
00528         EMVCommandHeader *cmd = (EMVCommandHeader*)malloc(sizeof(EMVCommandHeader));
00529         if(cmd == NULL) return NULL;
00530 
00531         cmd->cla = cla;
00532         cmd->ins = ins;
00533         cmd->p1 = p1;
00534         cmd->p2 = p2;
00535         cmd->p3 = p3;
00536 
00537         return cmd;
00538 }
00539 
00552 EMVCommandHeader* MakeCommandHeaderC(EMV_CMD command)
00553 {
00554    EMVCommandHeader *cmd = (EMVCommandHeader*)malloc(sizeof(EMVCommandHeader));
00555    if(cmd == NULL) return NULL;
00556 
00557    // the default case, modified below where needed
00558    cmd->cla = 0;
00559    cmd->ins = 0;  
00560    cmd->p1 = 0;
00561    cmd->p2 = 0;  
00562    cmd->p3 = 0;  
00563 
00564    switch(command)
00565    {
00566       case CMD_SELECT:
00567          cmd->ins = 0xA4;
00568          cmd->p1 = 0x04;
00569       break;
00570 
00571       case CMD_GET_RESPONSE:
00572          cmd->ins = 0xC0;
00573       break;
00574 
00575       case CMD_READ_RECORD:
00576          cmd->ins = 0xB2;
00577          cmd->p1 = 0x01;
00578       break;
00579 
00580       case CMD_GET_PROCESSING_OPTS:
00581          cmd->cla = 0x80;
00582          cmd->ins = 0xA8;
00583       break;
00584 
00585       case CMD_VERIFY:
00586          cmd->ins = 0x20;
00587          cmd->p2 = 0x80;
00588       break;
00589 
00590       case CMD_GENERATE_AC:
00591          cmd->cla = 0x80;
00592          cmd->ins = 0xAE;
00593       break;
00594 
00595       case CMD_GET_DATA:
00596          cmd->cla = 0x80;
00597          cmd->ins = 0xCA;
00598          cmd->p1 = 0x9F;
00599          cmd->p2 = 0x17;
00600       break;
00601 
00602       case CMD_INTERNAL_AUTHENTICATE:
00603          cmd->ins = 0x88;
00604       break;
00605 
00606       case CMD_PIN_CHANGE_UNBLOCK:
00607          cmd->cla = 0x8C;
00608          cmd->ins = 0x24;
00609       break;
00610    }
00611 
00612    return cmd;
00613 }
00614 
00615 
00636 CAPDU* MakeCommand(uint8_t cla, uint8_t ins, uint8_t p1,
00637       uint8_t p2, uint8_t p3, const uint8_t cmdData[], uint8_t lenData)
00638 {
00639    CAPDU *cmd = (CAPDU*)malloc(sizeof(CAPDU));
00640    if(cmd == NULL) return NULL;
00641 
00642    cmd->cmdHeader = MakeCommandHeader(cla, ins, p1, p2, p3);
00643    if(cmd->cmdHeader == NULL)
00644    {
00645       free(cmd);
00646       return NULL;
00647    }
00648 
00649    if(cmdData != NULL && lenData != 0)
00650    {
00651       cmd->cmdData = (uint8_t*)malloc(lenData * sizeof(uint8_t));
00652       if(cmd->cmdData == NULL)
00653       {
00654          FreeCAPDU(cmd);
00655          return NULL;
00656       }
00657       memcpy(cmd->cmdData, cmdData, lenData);
00658       cmd->lenData = lenData;
00659    }
00660    else
00661    {
00662       cmd->cmdData = NULL;
00663       cmd->lenData = 0;
00664    }
00665    
00666    return cmd;
00667 }
00668 
00687 CAPDU* MakeCommandP(const EMVCommandHeader *cmdHdr, const uint8_t cmdData[],
00688       uint8_t lenData)
00689 {
00690    if(cmdHdr == NULL) return NULL;
00691 
00692    CAPDU *cmd = (CAPDU*)malloc(sizeof(CAPDU));
00693    if(cmd == NULL) return NULL;
00694 
00695    cmd->cmdHeader = MakeCommandHeader(cmdHdr->cla, cmdHdr->ins,
00696       cmdHdr->p1, cmdHdr->p2, cmdHdr->p3);
00697    if(cmd->cmdHeader == NULL)
00698    {
00699       free(cmd);
00700       return NULL;
00701    }
00702 
00703    if(cmdData != NULL && lenData != 0)
00704    {
00705       cmd->cmdData = (uint8_t*)malloc(lenData * sizeof(uint8_t));
00706       if(cmd->cmdData == NULL)
00707       {
00708          FreeCAPDU(cmd);
00709          return NULL;
00710       }
00711       memcpy(cmd->cmdData, cmdData, lenData);
00712       cmd->lenData = lenData;
00713    }
00714    else
00715    {
00716       cmd->cmdData = NULL;
00717       cmd->lenData = 0;
00718    }
00719 
00720    return cmd;
00721 }
00722 
00741 CAPDU* MakeCommandC(EMV_CMD command, const uint8_t cmdData[],
00742       uint8_t lenData)
00743 {
00744    CAPDU *cmd = (CAPDU*)malloc(sizeof(CAPDU));
00745    if(cmd == NULL) return NULL;
00746 
00747    cmd->cmdHeader = MakeCommandHeaderC(command);
00748    if(cmd->cmdHeader == NULL)
00749    {
00750       free(cmd);
00751       return NULL;
00752    }
00753 
00754    if(cmdData != NULL && lenData != 0)
00755    {
00756       cmd->cmdData = (uint8_t*)malloc(lenData * sizeof(uint8_t));
00757       if(cmd->cmdData == NULL)
00758       {
00759          FreeCAPDU(cmd);
00760          return NULL;
00761       }
00762       memcpy(cmd->cmdData, cmdData, lenData);
00763       cmd->lenData = lenData;
00764       cmd->cmdHeader->p3 = lenData;
00765    }
00766    else
00767    {
00768       cmd->cmdData = NULL;
00769       cmd->lenData = 0;
00770    }
00771 
00772    return cmd;
00773 }
00774 
00809 uint8_t InitSCDTransaction(uint8_t t_inverse, uint8_t t_TC1, 
00810         uint8_t *inverse_convention, uint8_t *proto, uint8_t *TC1, 
00811         uint8_t *TA3, uint8_t *TB3, log_struct_t *logger)
00812 {
00813         uint8_t tmp;
00814         uint16_t tfreq, tdelay;
00815         int8_t tmpi;
00816     uint32_t time;
00817     uint16_t atr_selection;
00818     uint8_t atr_bytes[32];
00819     uint8_t atr_tck;
00820     uint8_t icc_T0, icc_TS;
00821     uint8_t error;
00822     uint8_t index;
00823     uint8_t history;
00824 
00825         // start timer for terminal
00826         StartCounterTerminal(); 
00827         
00828         // wait for terminal CLK
00829         while(ReadCounterTerminal() < 10); // this will be T0
00830     time = GetCounter();
00831     if(logger)
00832     {
00833         LogByte4(
00834                 logger,
00835                 LOG_TIME_GENERAL,
00836                 (time & 0xFF),
00837                 ((time >> 8) & 0xFF),
00838                 ((time >> 16) & 0xFF),
00839                 ((time >> 24) & 0xFF));
00840         LogByte1(logger, LOG_TERMINAL_CLK_ACTIVE, 0);
00841     }
00842 
00843         // get the terminal frequency
00844         tfreq = GetTerminalFreq();
00845         tdelay = 10 * tfreq;
00846         
00847         // activate ICC after (60000 - 10500*tfreq) terminal clocks
00848         // so that we rise ICC RST to high just after sending the 
00849         // TS byte to the terminal
00850         tmp = (uint8_t)((60000 - tdelay) / 372);
00851         LoopTerminalETU(tmp);
00852         if(ActivateICC(0))
00853     {
00854         error = RET_ERROR;
00855         goto enderror;
00856     }
00857     if(logger)
00858         LogByte1(logger, LOG_ICC_ACTIVATED, 0);
00859         
00860         // Send TS to terminal when RST line should be high     
00861         tmpi = (int8_t)((tdelay - 10000) / 372);
00862         if(tmpi < 0) tmpi = 0;
00863         LoopTerminalETU(tmpi);
00864         if(t_inverse)
00865     {
00866                 SendByteTerminalNoParity(0x3F, t_inverse);
00867         if(logger)
00868             LogByte1(logger, LOG_BYTE_ATR_TO_TERMINAL, 0x3F);
00869     }
00870         else
00871     {
00872                 SendByteTerminalNoParity(0x3B, t_inverse);
00873         if(logger)
00874             LogByte1(logger, LOG_BYTE_ATR_TO_TERMINAL, 0x3B);
00875     }
00876 
00877         // Set ICC RST line to high and receive ATR from ICC
00878         LoopTerminalETU(12);
00879         PORTD |= _BV(PD4);              
00880     if(logger)
00881         LogByte1(logger, LOG_ICC_RST_HIGH, 0);
00882         
00883         // Wait for ATR from ICC for a maximum of 42000 clock cycles + 40 ms
00884         // this number is based on the assembler of this function
00885         if(WaitForICCData(50000))       
00886         {
00887                 error = RET_ERROR;                              // May be changed with a warm reset
00888         DeactivateICC();
00889         if(logger)
00890             LogByte1(logger, LOG_ICC_DEACTIVATED, 0);
00891         goto enderror;
00892         }
00893 
00894     error = GetATRICC(
00895             inverse_convention, proto, &icc_TS, &icc_T0,
00896             &atr_selection, atr_bytes, &atr_tck, logger);
00897         if(error)
00898     {
00899         DeactivateICC();
00900         if(logger)
00901             LogByte1(logger, LOG_ICC_DEACTIVATED, 0);
00902                 goto enderror;
00903     }
00904     *TC1 = atr_bytes[2];
00905     *TA3 = atr_bytes[8];
00906     *TB3 = atr_bytes[9];
00907     history = icc_T0 & 0x0F;
00908 
00909         // Send the rest of the ATR to the terminal
00910         SendByteTerminalNoParity(icc_T0, t_inverse);
00911     if(logger)
00912         LogByte1(logger, LOG_BYTE_ATR_TO_TERMINAL, icc_T0);
00913         LoopTerminalETU(2);
00914 
00915     for(index = 0; index < 16; index++)
00916     {
00917         if(atr_selection & (1 << (15-index)))
00918         {
00919             SendByteTerminalNoParity(atr_bytes[index], t_inverse);
00920             if(logger)
00921                 LogByte1(logger, LOG_BYTE_ATR_TO_TERMINAL, atr_bytes[index]);
00922             LoopTerminalETU(2);
00923         }
00924     }
00925         
00926     for(index = 0; index < history; index++)
00927     {
00928         SendByteTerminalNoParity(atr_bytes[16 + index], t_inverse);
00929         if(logger)
00930             LogByte1(logger, LOG_BYTE_ATR_TO_TERMINAL, atr_bytes[16 + index]);
00931         LoopTerminalETU(2);
00932     }
00933 
00934     error = 0;
00935 
00936 enderror:
00937         return 0;       
00938 }
00939 
00940 
00958 uint8_t GetCommandCase(uint8_t cla, uint8_t ins)
00959 {
00960         switch(cla)
00961         {
00962                 case 0:
00963                 {
00964                         switch(ins)
00965                         {
00966                                 case 0xC0: // GET RESPONSE
00967                                         return 2;
00968                                 break;
00969 
00970                                 case 0xB2: // READ RECORD
00971                                         return 2;
00972                                 break;
00973 
00974                                 case 0xA4: // SELECT
00975                                         return 4;
00976                                 break;
00977 
00978                                 case 0x82: // EXTERNAL AUTHENTICATE
00979                                         return 3;
00980                                 break;
00981 
00982                                 case 0x84: // GET CHALLENGE
00983                                         return 2;
00984                                 break;
00985 
00986                                 case 0x88: // INTERNAL AUTHENTICATE
00987                                         return 4;
00988                                 break;
00989 
00990                                 case 0x20: // VERIFY
00991                                         return 3;
00992                                 break;                          
00993 
00994                                 default: return 0;
00995                         }
00996                 }
00997                 break;
00998 
00999                 case 0x8C:
01000                 case 0x84:
01001                 {
01002                         switch(ins)
01003                         {
01004                                 case 0x1E: // APPLICATION BLOCK
01005                                         return 3;
01006                                 break;
01007 
01008                                 case 0x18: // APPLICATION UNBLOCK
01009                                         return 3;
01010                                 break;
01011 
01012                                 case 0x16: // CARD BLOCK
01013                                         return 3;
01014                                 break;
01015 
01016                                 case 0x24: // PIN CHANGE/UNBLOCK
01017                                         return 3;
01018                                 break;
01019 
01020                                 default: return 0;
01021                         }
01022                 }
01023                 break;
01024 
01025                 case 0x80:
01026                 {
01027                         switch(ins)
01028                         {
01029                                 case 0xAE: // GENERATE AC
01030                                         return 4;
01031                                 break;
01032 
01033                                 case 0xCA: // GET DATA
01034                                         return 2;
01035                                 break;
01036 
01037                                 case 0xA8: // GET PROCESSING OPTS
01038                                         return 4;
01039                                 break;
01040 
01041                                 default: return 0;
01042                         }                       
01043                 }
01044                 break;
01045 
01046                 default: return 0;
01047         }
01048 
01049         return 0;
01050 }
01051 
01052 
01065 EMVCommandHeader* ReceiveT0CmdHeader(
01066         uint8_t inverse_convention,
01067         uint8_t TC1,
01068         log_struct_t *logger)
01069 {
01070         uint8_t tdelay, result;
01071         EMVCommandHeader *cmdHeader;
01072     uint32_t time;
01073 
01074         cmdHeader = (EMVCommandHeader*)malloc(sizeof(EMVCommandHeader));
01075         if(cmdHeader == NULL)
01076     {
01077         if(logger)
01078             LogByte1(logger, LOG_ERROR_MEMORY, 0);
01079         return NULL;
01080     }
01081 
01082         tdelay = 1 + TC1;
01083 
01084     result = GetByteTerminalParity(
01085             inverse_convention, &(cmdHeader->cla), MAX_WAIT_TERMINAL);
01086     if(result != 0)
01087         goto enderror;
01088     if(logger)
01089         LogByte1(logger, LOG_BYTE_FROM_TERMINAL, cmdHeader->cla);
01090         LoopTerminalETU(tdelay);        
01091 
01092     result = GetByteTerminalParity(
01093             inverse_convention, &(cmdHeader->ins), MAX_WAIT_TERMINAL);
01094     if(result != 0)
01095         goto enderror;
01096     if(logger)
01097         LogByte1(logger, LOG_BYTE_FROM_TERMINAL, cmdHeader->ins);
01098         LoopTerminalETU(tdelay);        
01099 
01100     result = GetByteTerminalParity(
01101             inverse_convention, &(cmdHeader->p1), MAX_WAIT_TERMINAL);
01102     if(result != 0)
01103         goto enderror;
01104     if(logger)
01105         LogByte1(logger, LOG_BYTE_FROM_TERMINAL, cmdHeader->p1);
01106         LoopTerminalETU(tdelay);        
01107 
01108     result = GetByteTerminalParity(
01109             inverse_convention, &(cmdHeader->p2), MAX_WAIT_TERMINAL);
01110     if(result != 0)
01111         goto enderror;
01112     if(logger)
01113         LogByte1(logger, LOG_BYTE_FROM_TERMINAL, cmdHeader->p2);
01114         LoopTerminalETU(tdelay);        
01115 
01116     result = GetByteTerminalParity(
01117             inverse_convention, &(cmdHeader->p3), MAX_WAIT_TERMINAL);
01118     if(result != 0)
01119         goto enderror;
01120     if(logger)
01121         LogByte1(logger, LOG_BYTE_FROM_TERMINAL, cmdHeader->p3);
01122 
01123         return cmdHeader;
01124 
01125 enderror:
01126     free(cmdHeader);
01127     if(logger)
01128     {
01129         time = GetCounter();
01130         LogByte4(
01131                 logger,
01132                 LOG_TIME_GENERAL,
01133                 (time & 0xFF),
01134                 ((time >> 8) & 0xFF),
01135                 ((time >> 16) & 0xFF),
01136                 ((time >> 24) & 0xFF));
01137 
01138         if(result == RET_TERMINAL_RESET_LOW)
01139         {
01140             LogByte1(logger, LOG_TERMINAL_RST_LOW, 0);
01141         }
01142         else if(result == RET_TERMINAL_TIME_OUT)
01143         {
01144             LogByte1(logger, LOG_TERMINAL_TIME_OUT, 0);
01145         }
01146         else if(result == RET_TERMINAL_NO_CLOCK)
01147         {
01148             LogByte1(logger, LOG_TERMINAL_NO_CLOCK, 0);
01149         }
01150         else if(result == RET_ERROR)
01151         {
01152             LogByte1(logger, LOG_TERMINAL_ERROR_RECEIVE, 0);
01153         }
01154     }
01155     return NULL;
01156 }
01157 
01173 uint8_t* ReceiveT0CmdData(
01174         uint8_t inverse_convention,
01175         uint8_t TC1,
01176         uint8_t len,
01177         log_struct_t *logger)
01178 {
01179         uint8_t tdelay, i, result;
01180         uint8_t *cmdData;
01181 
01182         cmdData = (uint8_t*)malloc(len*sizeof(uint8_t));
01183         if(cmdData == NULL)
01184     {
01185         if(logger)
01186             LogByte1(logger, LOG_ERROR_MEMORY, 0);
01187         return NULL;
01188     }
01189 
01190         tdelay = 1 + TC1;
01191 
01192         for(i = 0; i < len - 1; i++)
01193         {
01194         result = GetByteTerminalParity(
01195                 inverse_convention, &(cmdData[i]), MAX_WAIT_TERMINAL);
01196         if(result != 0)
01197             goto enderror;
01198         if(logger)
01199             LogByte1(logger, LOG_BYTE_FROM_TERMINAL, cmdData[i]);
01200                 LoopTerminalETU(tdelay);        
01201         }
01202 
01203         // Do not add a delay after the last byte
01204     result = GetByteTerminalParity(
01205             inverse_convention, &(cmdData[i]), MAX_WAIT_TERMINAL);
01206     if(result != 0)
01207         goto enderror;
01208     if(logger)
01209         LogByte1(logger, LOG_BYTE_FROM_TERMINAL, cmdData[i]);
01210         
01211         return cmdData; 
01212 
01213 enderror:
01214     free(cmdData);
01215     if(logger)
01216     {
01217         if(result == RET_TERMINAL_RESET_LOW)
01218         {
01219             LogByte1(logger, LOG_TERMINAL_RST_LOW, 0);
01220         }
01221         else if(result == RET_TERMINAL_TIME_OUT)
01222         {
01223             LogByte1(logger, LOG_TERMINAL_TIME_OUT, 0);
01224         }
01225         else if(result == RET_ERROR)
01226         {
01227             LogByte1(logger, LOG_TERMINAL_ERROR_RECEIVE, 0);
01228         }
01229     }
01230     return NULL;
01231 }
01232 
01247 CAPDU* ReceiveT0Command(
01248         uint8_t inverse_convention, 
01249         uint8_t TC1,
01250         log_struct_t *logger)
01251 {
01252         uint8_t tdelay, tmp;
01253         CAPDU *cmd;
01254 
01255         tdelay = 1 + TC1;
01256 
01257         cmd = (CAPDU*)malloc(sizeof(CAPDU));
01258         if(cmd == NULL)
01259     {
01260         if(logger)
01261             LogByte1(logger, LOG_ERROR_MEMORY, 0);
01262         return NULL;
01263     }
01264         cmd->cmdHeader = NULL;
01265         cmd->cmdData = NULL;
01266         cmd->lenData = 0;
01267 
01268         cmd->cmdHeader = ReceiveT0CmdHeader(inverse_convention, TC1, logger);
01269         if(cmd->cmdHeader == NULL)
01270         {
01271                 free(cmd);              
01272                 return NULL;
01273         }       
01274         tmp = GetCommandCase(cmd->cmdHeader->cla, cmd->cmdHeader->ins);
01275         if(tmp == 0)
01276         {
01277                 FreeCAPDU(cmd);
01278                 return NULL;
01279         }
01280 
01281         // for case 1 and case 2 commands there is no command data to receive
01282         if(tmp == 1 || tmp == 2)
01283                 return cmd;
01284 
01285         // for other cases (3, 4) receive command data
01286     // wait for terminal to be ready to accept the byte
01287         LoopTerminalETU(6);
01288         if(SendByteTerminalParity(cmd->cmdHeader->ins, inverse_convention))
01289         {
01290                 free(cmd->cmdHeader);
01291                 cmd->cmdHeader = NULL;
01292                 free(cmd);              
01293         if(logger)
01294             LogByte1(logger, LOG_TERMINAL_ERROR_SEND, 0);
01295                 return NULL;
01296         }
01297     if(logger)
01298         LogByte1(logger, LOG_BYTE_TO_TERMINAL, cmd->cmdHeader->ins);
01299 
01300         LoopTerminalETU(tdelay);        
01301         cmd->lenData = cmd->cmdHeader->p3;
01302         cmd->cmdData = ReceiveT0CmdData(
01303             inverse_convention, TC1, cmd->lenData, logger);
01304         if(cmd->cmdData == NULL)
01305         {
01306                 free(cmd->cmdHeader);
01307                 cmd->cmdHeader = NULL;
01308                 free(cmd);              
01309                 return NULL;    
01310         }
01311 
01312         return cmd;     
01313 }
01314 
01315 
01326 uint8_t SendT0CmdHeader(
01327         uint8_t inverse_convention,
01328         uint8_t TC1,
01329         EMVCommandHeader *cmdHeader,
01330         log_struct_t *logger)
01331 {
01332         uint8_t tdelay;
01333 
01334         if(cmdHeader == NULL) return RET_ERROR;
01335 
01336         tdelay = 1 + TC1;
01337 
01338         if(SendByteICCParity(cmdHeader->cla, inverse_convention))
01339     {
01340         if(logger)
01341             LogByte1(logger, LOG_ICC_ERROR_SEND, 0);
01342         return RET_ERROR;
01343     }
01344     if(logger)
01345         LogByte1(logger, LOG_BYTE_TO_ICC, cmdHeader->cla);
01346         LoopICCETU(tdelay);     
01347 
01348         if(SendByteICCParity(cmdHeader->ins, inverse_convention))
01349     {
01350         if(logger)
01351             LogByte1(logger, LOG_ICC_ERROR_SEND, 0);
01352         return RET_ERROR;
01353     }
01354     if(logger)
01355         LogByte1(logger, LOG_BYTE_TO_ICC, cmdHeader->ins);
01356         LoopICCETU(tdelay);     
01357 
01358         if(SendByteICCParity(cmdHeader->p1, inverse_convention))
01359     {
01360         if(logger)
01361             LogByte1(logger, LOG_ICC_ERROR_SEND, 0);
01362         return RET_ERROR;
01363     }
01364     if(logger)
01365         LogByte1(logger, LOG_BYTE_TO_ICC, cmdHeader->p1);
01366         LoopICCETU(tdelay);     
01367 
01368         if(SendByteICCParity(cmdHeader->p2, inverse_convention))
01369     {
01370         if(logger)
01371             LogByte1(logger, LOG_ICC_ERROR_SEND, 0);
01372         return RET_ERROR;
01373     }
01374     if(logger)
01375         LogByte1(logger, LOG_BYTE_TO_ICC, cmdHeader->p2);
01376         LoopICCETU(tdelay);     
01377 
01378         if(SendByteICCParity(cmdHeader->p3, inverse_convention))
01379     {
01380         if(logger)
01381             LogByte1(logger, LOG_ICC_ERROR_SEND, 0);
01382         return RET_ERROR;
01383     }
01384     if(logger)
01385         LogByte1(logger, LOG_BYTE_TO_ICC, cmdHeader->p3);
01386 
01387         return 0;
01388 }
01389 
01390 
01402 uint8_t SendT0CmdData(
01403         uint8_t inverse_convention,
01404         uint8_t TC1,
01405         uint8_t *cmdData,
01406         uint8_t len,
01407         log_struct_t *logger)
01408 {
01409         uint8_t tdelay, i;
01410 
01411         if(cmdData == NULL) return RET_ERROR;
01412 
01413         tdelay = 1 + TC1;
01414 
01415         for(i = 0; i < len - 1; i++)
01416         {
01417                 if(SendByteICCParity(cmdData[i], inverse_convention))
01418         {
01419             if(logger)
01420                 LogByte1(logger, LOG_ICC_ERROR_SEND, 0);
01421                         return RET_ERROR;       
01422         }
01423         if(logger)
01424             LogByte1(logger, LOG_BYTE_TO_ICC, cmdData[i]);
01425                 LoopICCETU(tdelay);     
01426         }
01427 
01428         // Do not add a delay after the last byte
01429         if(SendByteICCParity(cmdData[i], inverse_convention))
01430     {
01431         if(logger)
01432             LogByte1(logger, LOG_ICC_ERROR_SEND, 0);
01433         return RET_ERROR;       
01434     }
01435     if(logger)
01436         LogByte1(logger, LOG_BYTE_TO_ICC, cmdData[i]);
01437         
01438         return 0;
01439 }
01440 
01441 
01454 uint8_t SendT0Command(
01455         uint8_t inverse_convention,
01456         uint8_t TC1,
01457         CAPDU *cmd,
01458         log_struct_t *logger)
01459 {
01460     uint8_t tdelay, tmp, tmp2, i;       
01461     uint32_t time;
01462 
01463     if(cmd == NULL) return RET_ERROR;
01464     tdelay = 1 + TC1;
01465     if(logger)
01466     {
01467         time = GetCounter();
01468         LogByte4(
01469                 logger,
01470                 LOG_TIME_DATA_TO_ICC,
01471                 (time & 0xFF),
01472                 ((time >> 8) & 0xFF),
01473                 ((time >> 16) & 0xFF),
01474                 ((time >> 24) & 0xFF));
01475     }
01476 
01477     tmp = GetCommandCase(cmd->cmdHeader->cla, cmd->cmdHeader->ins);     
01478     if(tmp == 0)
01479         return RET_ERROR;
01480     if(SendT0CmdHeader(inverse_convention, TC1, cmd->cmdHeader, logger))
01481         return RET_ERROR;
01482 
01483     // for case 1 and case 2 commands there is no command data to send
01484     if(tmp == 1 || tmp == 2)
01485        return 0;
01486 
01487     // for other cases (3, 4) get procedure byte and send command data
01488     LoopICCETU(6);
01489 
01490     // Get firs byte (can be INS, ~INS, 60, 61, 6C or other in case of error)
01491     if(GetByteICCParity(inverse_convention, &tmp))
01492     {
01493         if(logger)
01494             LogByte1(logger, LOG_ICC_ERROR_RECEIVE, 0);
01495         return RET_ERROR;
01496     }
01497     if(logger)
01498         LogByte1(logger, LOG_BYTE_FROM_ICC, tmp);
01499 
01500     while(tmp == SW1_MORE_TIME)
01501     {
01502         LoopICCETU(1);
01503         if(GetByteICCParity(inverse_convention, &tmp))
01504         {
01505             if(logger)
01506                 LogByte1(logger, LOG_ICC_ERROR_RECEIVE, 0);
01507             return RET_ERROR;
01508         }
01509         if(logger)
01510             LogByte1(logger, LOG_BYTE_FROM_ICC, tmp);
01511     }
01512 
01513     // if we don't get INS or ~INS then
01514     // get another byte and then exit, operation unexpected
01515     if((tmp != cmd->cmdHeader->ins) && (tmp != ~(cmd->cmdHeader->ins)))
01516     {
01517         if(GetByteICCParity(inverse_convention, &tmp2))
01518         {
01519             if(logger)
01520                 LogByte1(logger, LOG_ICC_ERROR_RECEIVE, 0);
01521             return RET_ERROR;
01522         }
01523         if(logger)
01524             LogByte1(logger, LOG_BYTE_FROM_ICC, tmp2);
01525         return RET_ERR_CHECK; 
01526     }
01527     
01528     // Wait for card to be ready before sending any bytes
01529     LoopICCETU(6);
01530     
01531     i = 0;
01532     // Send first byte if sending byte by byte
01533     if(tmp != cmd->cmdHeader->ins)
01534     {
01535         if(SendByteICCParity(cmd->cmdData[i++], inverse_convention))
01536         {
01537             if(logger)
01538                 LogByte1(logger, LOG_ICC_ERROR_SEND, 0);
01539             return RET_ERROR;
01540         }
01541         if(logger)
01542             LogByte1(logger, LOG_BYTE_TO_ICC, cmd->cmdData[i-1]);
01543         if(i < cmd->lenData)
01544             LoopICCETU(6);
01545     }
01546     
01547     // send byte after byte in case we receive !INS instead of INS
01548     while(tmp != cmd->cmdHeader->ins && i < cmd->lenData)
01549     {
01550         if(GetByteICCParity(inverse_convention, &tmp))
01551         {
01552             if(logger)
01553                 LogByte1(logger, LOG_ICC_ERROR_RECEIVE, 0);
01554             return RET_ERROR;
01555         }
01556         if(logger)
01557             LogByte1(logger, LOG_BYTE_FROM_ICC, tmp);
01558         LoopICCETU(6);
01559     
01560         if(tmp != cmd->cmdHeader->ins)
01561         {
01562             if(SendByteICCParity(cmd->cmdData[i++], inverse_convention))
01563             {
01564                 if(logger)
01565                     LogByte1(logger, LOG_ICC_ERROR_SEND, 0);
01566                 return RET_ERROR;
01567             }
01568             if(logger)
01569                 LogByte1(logger, LOG_BYTE_TO_ICC, cmd->cmdData[i-1]);
01570             if(i < cmd->lenData)
01571                     LoopICCETU(6);
01572         }
01573     }
01574                         
01575     // send remaining of bytes, if any
01576     for(; i < cmd->lenData - 1; i++)
01577     {
01578         if(SendByteICCParity(cmd->cmdData[i], inverse_convention))
01579         {
01580             if(logger)
01581                 LogByte1(logger, LOG_ICC_ERROR_SEND, 0);
01582             return RET_ERROR;
01583         }
01584         if(logger)
01585             LogByte1(logger, LOG_BYTE_TO_ICC, cmd->cmdData[i]);
01586         LoopICCETU(tdelay);
01587     }
01588     if(i == cmd->lenData - 1)
01589     {
01590         if(SendByteICCParity(cmd->cmdData[i], inverse_convention))
01591         {
01592             if(logger)
01593                 LogByte1(logger, LOG_ICC_ERROR_SEND, 0);
01594             return RET_ERROR;
01595         }
01596         if(logger)
01597             LogByte1(logger, LOG_BYTE_TO_ICC, cmd->cmdData[i]);
01598     }
01599     
01600     return 0;
01601 }
01602 
01603 
01617 CAPDU* ForwardCommand(
01618         uint8_t tInverse,
01619         uint8_t cInverse,
01620         uint8_t tTC1,
01621         uint8_t cTC1,
01622         log_struct_t *logger)
01623 {
01624         CAPDU* cmd;
01625 
01626         cmd = ReceiveT0Command(tInverse, tTC1, logger);
01627         if(cmd == NULL) return NULL;
01628 
01629         if(SendT0Command(cInverse, cTC1, cmd, logger))
01630         {
01631                 FreeCAPDU(cmd);
01632                 return NULL;
01633         }
01634 
01635         return cmd;
01636 }
01637 
01638 
01649 uint8_t* SerializeCommand(CAPDU *cmd, uint8_t *len)
01650 {
01651         uint8_t *stream, i = 0;
01652         
01653         if(cmd == NULL || len == NULL || cmd->cmdHeader == NULL) return NULL;
01654         if(cmd->lenData > 0 && cmd->cmdData == NULL) return NULL;
01655         
01656         *len = 5 + cmd->lenData;
01657         stream = (uint8_t*)malloc((*len)*sizeof(uint8_t));
01658         if(stream == NULL)
01659         {
01660                 *len = 0;
01661                 return NULL;
01662         }
01663 
01664         stream[i++] = cmd->cmdHeader->cla;
01665         stream[i++] = cmd->cmdHeader->ins;
01666         stream[i++] = cmd->cmdHeader->p1;
01667         stream[i++] = cmd->cmdHeader->p2;
01668         stream[i++] = cmd->cmdHeader->p3;
01669 
01670     while(i < cmd->lenData)
01671     {
01672                 stream[i] = cmd->cmdData[i];
01673         i++;
01674     }
01675 
01676         return stream;
01677 }
01678 
01679 
01697 RAPDU* ReceiveT0Response(
01698         uint8_t inverse_convention,
01699         EMVCommandHeader *cmdHeader,
01700         log_struct_t *logger)
01701 {
01702         uint8_t tmp, i;
01703         RAPDU* rapdu;
01704 
01705         if(cmdHeader == NULL) return NULL;
01706 
01707         rapdu = (RAPDU*)malloc(sizeof(RAPDU));
01708         if(rapdu == NULL) return 0;
01709         rapdu->repStatus = NULL;
01710         rapdu->repData = NULL;
01711         rapdu->lenData = 0;
01712         tmp = GetCommandCase(cmdHeader->cla, cmdHeader->ins);           
01713         if(tmp == 0)
01714         {
01715                 free(rapdu);
01716                 return NULL;
01717         }
01718 
01719         
01720         // for case 1 and case 3 there is no data expected, just status
01721         if(tmp == 1 || tmp == 3)
01722         {
01723                 rapdu->repStatus = (EMVStatus*)malloc(sizeof(EMVStatus));
01724                 if(rapdu->repStatus == NULL)
01725                 {
01726                         free(rapdu);
01727                         return NULL;
01728                 }
01729 
01730                 if(GetByteICCParity(inverse_convention, &(rapdu->repStatus->sw1)))
01731                 {
01732                         free(rapdu->repStatus);
01733                         rapdu->repStatus = NULL;
01734                         free(rapdu);
01735                         return NULL;
01736                 }
01737         if(logger)
01738             LogByte1(logger, LOG_BYTE_FROM_ICC, rapdu->repStatus->sw1);
01739 
01740                 if(rapdu->repStatus->sw1 == 0x60)
01741                 {
01742                         // requested more time, recall
01743                         free(rapdu->repStatus);
01744                         rapdu->repStatus = NULL;
01745                         free(rapdu);
01746                         
01747                         return ReceiveT0Response(inverse_convention, cmdHeader, logger);
01748 
01749                 }
01750 
01751                 if(GetByteICCParity(inverse_convention, &(rapdu->repStatus->sw2)))
01752                 {
01753                         free(rapdu->repStatus);
01754                         rapdu->repStatus = NULL;
01755                         free(rapdu);
01756                         return NULL;
01757                 }
01758         if(logger)
01759             LogByte1(logger, LOG_BYTE_FROM_ICC, rapdu->repStatus->sw2);
01760 
01761                 return rapdu;
01762         }
01763 
01764         // for case 2 and 4, we might get data based on first byte of response  
01765         if(GetByteICCParity(inverse_convention, &tmp))
01766         {
01767                 free(rapdu);
01768                 return NULL;
01769         }
01770     if(logger)
01771         LogByte1(logger, LOG_BYTE_FROM_ICC, tmp);
01772 
01773         if(tmp == 0x60)
01774         {
01775                 // requested more time, recall
01776                 free(rapdu);
01777                 
01778                 return ReceiveT0Response(inverse_convention, cmdHeader, logger);
01779         }
01780 
01781         if(tmp == cmdHeader->ins || tmp == ~cmdHeader->ins)     // get data
01782         {
01783                 if(tmp == cmdHeader->ins)
01784                         rapdu->lenData = cmdHeader->p3;
01785                 else
01786                         rapdu->lenData = 1;
01787 
01788                 rapdu->repData = (uint8_t*)malloc(rapdu->lenData*sizeof(uint8_t));
01789                 if(rapdu->repData == NULL)
01790                 {
01791 #if DEBUG
01792             fprintf(stderr, "Failed  MALLOC\n");
01793             _delay_ms(1000);
01794 #endif
01795                         free(rapdu);
01796                         return NULL;
01797                 }
01798 
01799                 for(i = 0; i < rapdu->lenData; i++)
01800                 {
01801                         if(GetByteICCParity(inverse_convention, &(rapdu->repData[i])))
01802                         {
01803                                 free(rapdu->repData);
01804                                 rapdu->repData = NULL;
01805                                 free(rapdu);
01806                                 return NULL;
01807                         }
01808             if(logger)
01809                 LogByte1(logger, LOG_BYTE_FROM_ICC, rapdu->repData[i]);
01810                 }               
01811 
01812                 rapdu->repStatus = (EMVStatus*)malloc(sizeof(EMVStatus));
01813                 if(rapdu->repStatus == NULL)
01814                 {
01815                         free(rapdu->repData);
01816                         rapdu->repData = NULL;
01817                         free(rapdu);
01818                         return NULL;
01819                 }
01820 
01821                 if(GetByteICCParity(inverse_convention, &(rapdu->repStatus->sw1)))
01822                 {
01823                         free(rapdu->repData);
01824                         rapdu->repData = NULL;
01825                         free(rapdu->repStatus);
01826                         rapdu->repStatus = NULL;
01827                         free(rapdu);
01828                         return NULL;
01829                 }
01830         if(logger)
01831             LogByte1(logger, LOG_BYTE_FROM_ICC, rapdu->repStatus->sw1);
01832 
01833                 if(GetByteICCParity(inverse_convention, &(rapdu->repStatus->sw2)))
01834                 {
01835                         free(rapdu->repData);
01836                         rapdu->repData = NULL;
01837                         free(rapdu->repStatus);
01838                         rapdu->repStatus = NULL;
01839                         free(rapdu);
01840                         return NULL;
01841                 }
01842         if(logger)
01843             LogByte1(logger, LOG_BYTE_FROM_ICC, rapdu->repStatus->sw2);
01844 
01845         }       
01846         else    // get second byte of response (no data)
01847         {
01848                 rapdu->repStatus = (EMVStatus*)malloc(sizeof(EMVStatus));
01849                 if(rapdu->repStatus == NULL)
01850                 {                       
01851                         free(rapdu);
01852                         return NULL;
01853                 }
01854 
01855                 rapdu->repStatus->sw1 = tmp;
01856                 if(GetByteICCParity(inverse_convention, &(rapdu->repStatus->sw2)))
01857                 {
01858                         free(rapdu->repStatus);
01859                         rapdu->repStatus = NULL;
01860                         free(rapdu);
01861                         return NULL;
01862                 }
01863         if(logger)
01864             LogByte1(logger, LOG_BYTE_FROM_ICC, rapdu->repStatus->sw2);
01865         }
01866 
01867         return rapdu;
01868 }
01869 
01870 
01882 uint8_t SendT0Response(
01883         uint8_t inverse_convention,
01884         EMVCommandHeader *cmdHeader,
01885         RAPDU *response,
01886         log_struct_t *logger)
01887 {
01888         uint8_t i;      
01889 
01890         if(cmdHeader == NULL || response == NULL) return RET_ERROR;     
01891 
01892         if(response->lenData > 0 && response->repData != NULL)
01893         {
01894                 if(SendByteTerminalParity(cmdHeader->ins, inverse_convention))
01895                         return RET_ERROR;
01896         if(logger)
01897             LogByte1(logger, LOG_BYTE_TO_TERMINAL, cmdHeader->ins);
01898                 LoopTerminalETU(2);
01899 
01900                 for(i = 0; i < response->lenData; i++)
01901                 {                       
01902                         if(SendByteTerminalParity(response->repData[i], inverse_convention))
01903                                 return RET_ERROR;
01904             if(logger)
01905                 LogByte1(logger, LOG_BYTE_TO_TERMINAL, response->repData[i]);
01906                         LoopTerminalETU(2);
01907                 }
01908         }
01909 
01910         if(response->repStatus == NULL) return RET_ERROR;
01911 
01912         if(SendByteTerminalParity(response->repStatus->sw1, inverse_convention))
01913                 return RET_ERROR;
01914     if(logger)
01915         LogByte1(logger, LOG_BYTE_TO_TERMINAL, response->repStatus->sw1);
01916         LoopTerminalETU(2);
01917         if(SendByteTerminalParity(response->repStatus->sw2, inverse_convention))
01918                 return RET_ERROR;       
01919     if(logger)
01920         LogByte1(logger, LOG_BYTE_TO_TERMINAL, response->repStatus->sw2);
01921         LoopTerminalETU(2);
01922 
01923         return 0;
01924 }
01925 
01938 RAPDU* ForwardResponse(
01939         uint8_t tInverse,
01940         uint8_t cInverse,
01941         EMVCommandHeader *cmdHeader,
01942         log_struct_t *logger)
01943 {
01944         RAPDU* response;
01945 
01946         if(cmdHeader == NULL) return NULL;
01947 
01948         response = ReceiveT0Response(cInverse, cmdHeader, logger);
01949         if(response == NULL) return NULL;
01950 
01951         if(SendT0Response(tInverse, cmdHeader, response, logger))
01952         {
01953                 FreeRAPDU(response);            
01954                 return NULL;
01955         }
01956 
01957         return response;
01958 }
01959 
01970 uint8_t* SerializeResponse(RAPDU *response, uint8_t *len)
01971 {
01972         uint8_t *stream, i = 0;
01973         
01974         if(response == NULL || len == NULL || response->repStatus == NULL)
01975                 return NULL;
01976         if(response->lenData > 0 && response->repData == NULL) return NULL;
01977         
01978         *len = 2 + response->lenData;
01979         stream = (uint8_t*)malloc((*len)*sizeof(uint8_t));
01980         if(stream == NULL)
01981         {
01982                 *len = 0;
01983                 return NULL;
01984         }
01985 
01986         stream[i++] = response->repStatus->sw1;
01987         stream[i++] = response->repStatus->sw2; 
01988 
01989     while(i < response->lenData)
01990     {
01991                 stream[i] = response->repData[i];
01992         i++;
01993     }
01994 
01995         return stream;
01996 }
01997 
01998 
02015 CRP* ExchangeData(
02016         uint8_t tInverse,
02017         uint8_t cInverse,
02018         uint8_t tTC1,
02019         uint8_t cTC1,
02020         log_struct_t *logger)
02021 {
02022         CRP* data;
02023 
02024         data = (CRP*)malloc(sizeof(CRP));
02025         if(data == NULL)
02026     {
02027         if(logger)
02028             LogByte1(logger, LOG_ERROR_MEMORY, 0);
02029         return NULL;
02030     }
02031 
02032         data->cmd = ForwardCommand(tInverse, cInverse, tTC1, cTC1, logger);
02033         if(data->cmd == NULL)
02034         {
02035                 free(data);
02036                 return NULL;
02037         }
02038 
02039         data->response = ForwardResponse(
02040             tInverse, cInverse, data->cmd->cmdHeader, logger);
02041         if(data->response == NULL)
02042         {
02043                 FreeCAPDU(data->cmd);
02044                 free(data);
02045                 return NULL;
02046         }
02047 
02048         return data;
02049 }
02050 
02070 CRP* ExchangeCompleteData(
02071         uint8_t tInverse,
02072         uint8_t cInverse,
02073         uint8_t tTC1,
02074         uint8_t cTC1,
02075         log_struct_t *logger)
02076 {
02077         CRP *data, *tmp;
02078         uint8_t cont;
02079 
02080         data = (CRP*)malloc(sizeof(CRP));
02081         if(data == NULL)
02082     {
02083         if(logger)
02084             LogByte1(logger, LOG_ERROR_MEMORY, 0);
02085         return NULL;
02086     }
02087         data->cmd = NULL;
02088         data->response = NULL;
02089 
02090         // store command from first exchange
02091         tmp = ExchangeData(tInverse, cInverse, tTC1, cTC1, logger);
02092         if(tmp == NULL)
02093         {
02094                 FreeCRP(data);
02095                 return NULL;
02096         }
02097         data->cmd = tmp->cmd;
02098         tmp->cmd = NULL;        
02099 
02100         cont = (tmp->response->repStatus->sw1 == 0x61 ||
02101                 tmp->response->repStatus->sw1 == 0x6C); 
02102         if(cont) FreeCRP(tmp);
02103 
02104         while(cont)
02105         {
02106                 tmp = ExchangeData(tInverse, cInverse, tTC1, cTC1, logger);
02107                 if(tmp == NULL)
02108                 {
02109                         FreeCRP(data);
02110                         return NULL;
02111                 }
02112 
02113                 cont = (tmp->response->repStatus->sw1 == 0x61 ||
02114                         tmp->response->repStatus->sw1 == 0x6C); 
02115                 
02116                 if(cont) FreeCRP(tmp);
02117         }
02118 
02119         data->response = tmp->response;
02120         tmp->response = NULL;
02121         FreeCRP(tmp);   
02122 
02123         return data;
02124 }
02125 
02137 ByteArray* MakeByteArray(uint8_t *data, uint8_t len)
02138 {
02139    ByteArray *stream = (ByteArray*)malloc(sizeof(ByteArray));
02140    if(stream == NULL) return NULL;
02141    stream->bytes = data;
02142    stream->len = len;
02143 
02144    return stream;
02145 }
02146 
02157 ByteArray* MakeByteArrayV(uint8_t nargs, ...)
02158 {
02159    ByteArray *ba;
02160    va_list ap;
02161    uint8_t i;
02162 
02163    ba = (ByteArray*)malloc(sizeof(ByteArray));
02164    if(ba == NULL) return NULL;
02165    ba->len = nargs;
02166    ba->bytes = (uint8_t*)malloc(ba->len * sizeof(uint8_t));
02167    if(ba->bytes == NULL)
02168    {
02169       free(ba);
02170       return NULL;
02171    }
02172 
02173    va_start(ap, nargs);
02174    // according to avr-libc documentation, variable arguments
02175    // are passed on the stack as ints
02176    for(i = 0; i < nargs; i++)
02177       ba->bytes[i] = (uint8_t)va_arg(ap, int); 
02178    va_end(ap);
02179 
02180    return ba;
02181 }
02182 
02193 ByteArray* CopyByteArray(const uint8_t *data, uint8_t len)
02194 {
02195    ByteArray *stream = (ByteArray*)malloc(sizeof(ByteArray));
02196    if(stream == NULL) return NULL;
02197    stream->bytes = NULL;
02198    stream->len = 0;
02199 
02200    if(data != NULL && len > 0)
02201    {
02202       stream->bytes = (uint8_t*)malloc(len * sizeof(uint8_t));
02203       if(stream->bytes == NULL)
02204       {
02205          free(stream);
02206          return NULL;
02207       }
02208       memcpy(stream->bytes, data, len);
02209       stream->len = len;
02210    }
02211 
02212    return stream;
02213 }
02214 
02220 void FreeByteArray(ByteArray* data)
02221 {
02222    if(data == NULL) return;
02223 
02224    if(data->bytes != NULL)
02225    {
02226       free(data->bytes);
02227       data->bytes = NULL;
02228    }
02229    free(data);
02230 }
02231 
02237 void FreeCAPDU(CAPDU* cmd)
02238 {
02239         if(cmd == NULL) return;
02240 
02241         if(cmd->cmdHeader != NULL)
02242         {
02243                 free(cmd->cmdHeader);
02244                 cmd->cmdHeader = NULL;          
02245         }
02246 
02247         if(cmd->cmdData != NULL)
02248         {               
02249                 free(cmd->cmdData);
02250                 cmd->cmdData = NULL;
02251         }
02252         free(cmd);
02253 }
02254 
02261 CAPDU* CopyCAPDU(CAPDU* cmd)
02262 {
02263    CAPDU *command;
02264 
02265    if(cmd == NULL || cmd->cmdHeader == NULL) return NULL;
02266 
02267    command = (CAPDU*)malloc(sizeof(CAPDU));
02268    if(command == NULL) return NULL;
02269    command->cmdHeader = (EMVCommandHeader*)malloc(sizeof(EMVCommandHeader));
02270    if(command->cmdHeader == NULL)
02271    {
02272       free(command);
02273       return NULL;
02274    }
02275    memcpy(command->cmdHeader, cmd->cmdHeader, sizeof(EMVCommandHeader));
02276    if(cmd->cmdData != NULL && cmd->lenData != 0)
02277    {
02278       command->cmdData = (uint8_t*)malloc(cmd->lenData * sizeof(uint8_t));
02279       if(command->cmdData == NULL)
02280       {
02281          FreeCAPDU(command);
02282          return NULL;
02283       }
02284       memcpy(command->cmdData, cmd->cmdData, cmd->lenData);
02285       command->lenData = cmd->lenData;
02286    }
02287    else
02288    {
02289       command->cmdData = NULL;
02290       command->lenData = 0;
02291    }
02292    
02293    return command;
02294 }
02295 
02301 void FreeRAPDU(RAPDU* response)
02302 {
02303         if(response == NULL) return;
02304 
02305         if(response->repStatus != NULL)
02306         {
02307                 free(response->repStatus);
02308                 response->repStatus = NULL;             
02309         }
02310 
02311         if(response->repData != NULL)
02312         {               
02313                 free(response->repData);
02314                 response->repData = NULL;
02315         }
02316         free(response);
02317 }
02318 
02325 RAPDU* CopyRAPDU(RAPDU* resp)
02326 {
02327    RAPDU *response;
02328 
02329    if(resp == NULL || resp->repStatus == NULL) return NULL;
02330 
02331    response = (RAPDU*)malloc(sizeof(RAPDU));
02332    if(response == NULL) return NULL;
02333    response->repStatus = (EMVStatus*)malloc(sizeof(EMVStatus));
02334    if(response->repStatus == NULL)
02335    {
02336       free(response);
02337       return NULL;
02338    }
02339    memcpy(response->repStatus, resp->repStatus, sizeof(EMVStatus));
02340    if(resp->repData != NULL && resp->lenData != 0)
02341    {
02342       response->repData = (uint8_t*)malloc(resp->lenData * sizeof(uint8_t));
02343       if(response->repData == NULL)
02344       {
02345          FreeRAPDU(response);
02346          return NULL;
02347       }
02348       memcpy(response->repData, resp->repData, resp->lenData);
02349       response->lenData = resp->lenData;
02350    }
02351    else
02352    {
02353       response->repData = NULL;
02354       response->lenData = 0;
02355    }
02356    
02357    return response;
02358 }
02359 
02365 void FreeCRP(CRP* data)
02366 {
02367         if(data == NULL) return;
02368 
02369         if(data->cmd != NULL)
02370         {
02371                 FreeCAPDU(data->cmd);
02372                 data->cmd = NULL;               
02373         }
02374 
02375         if(data->response != NULL)
02376         {               
02377                 FreeRAPDU(data->response);
02378                 data->response = NULL;
02379         }
02380         free(data);
02381 }
02382 
02383 
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines