00001
00035 #include <avr/boot.h>
00036 #include <avr/io.h>
00037 #include <avr/sleep.h>
00038 #include <stdlib.h>
00039 #include <string.h>
00040 #include <util/delay.h>
00041
00042 #include "apps.h"
00043 #include "emv.h"
00044 #include "emv_values.h"
00045 #include "scd.h"
00046 #include "scd_hal.h"
00047 #include "scd_io.h"
00048 #include "scd_logger.h"
00049 #include "scd_values.h"
00050 #include "serial.h"
00051 #include "terminal.h"
00052 #include "utils.h"
00053 #include "VirtualSerial.h"
00054
00056 #define LCD_ENABLED 1
00057
00059 #define DEBUG 0
00060
00062 #define EEPROM_SIZE 4096
00063
00065 #define BOOTLOADER_START_ADDRESS 0xF000
00066
00068 #define TERMINAL_RESET_IO_WAIT (ETU_TERMINAL * 42000)
00069
00070
00071 #if LCD_ENABLED
00072 static char* strDone = "All Done";
00073 static char* strLog = "Writing Log";
00074 static char* strScroll = "BC to scroll";
00075 static char* strDecide = "BA = yesBD = no";
00076 static char* strInsertCard = "Insert card";
00077 static char* strCardInserted = "Card inserted";
00078 static char* strTerminalReset = "Terminalreset";
00079 static char* strPINOK = "PIN OK";
00080 static char* strPINBAD = "PIN BAD";
00081 #endif
00082
00088 uint8_t VirtualSerial(log_struct_t *logger)
00089 {
00090 char *buf;
00091 char *response = NULL;
00092
00093 InitLCD();
00094 fprintf(stderr, "\n");
00095
00096 fprintf(stderr, "Set up VS\n");
00097 _delay_ms(500);
00098 power_usb_enable();
00099 SetupHardware();
00100
00101 LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
00102 sei();
00103
00104 for (;;)
00105 {
00106 fprintf(stderr, "VS Ready\n");
00107 _delay_ms(100);
00108
00109 buf = GetHostData(255);
00110 if(buf == NULL)
00111 {
00112 _delay_ms(100);
00113 continue;
00114 }
00115
00116 response = (char*)ProcessSerialData(buf, logger);
00117 free(buf);
00118
00119 if(response != NULL)
00120 {
00121 SendHostData(response);
00122 free(response);
00123 response = NULL;
00124 }
00125 }
00126 }
00127
00136 uint8_t SerialInterface(uint16_t baudUBRR, log_struct_t *logger)
00137 {
00138 char *buf;
00139 char *response = NULL;
00140
00141 InitLCD();
00142 fprintf(stderr, "\n");
00143
00144 fprintf(stderr, "Set up Serial\n");
00145 _delay_ms(500);
00146 power_usart1_enable();
00147 _delay_ms(500);
00148 InitUSART(baudUBRR);
00149
00150 fprintf(stderr, "Serial Ready\n");
00151 _delay_ms(500);
00152
00153 for (;;)
00154 {
00155
00156 fprintf(stderr, "Before GetLine\n");
00157 _delay_ms(500);
00158 buf = GetLineUSART();
00159 if(buf == NULL)
00160 {
00161 _delay_ms(100);
00162 continue;
00163 }
00164
00165 fprintf(stderr, "Got:%s\n", buf);
00166 _delay_ms(500);
00167
00168 response = (char*)ProcessSerialData(buf, logger);
00169 free(buf);
00170
00171 if(response != NULL)
00172 {
00173 SendLineUSART(response);
00174 free(response);
00175 }
00176 }
00177 }
00178
00183 void EraseEEPROM()
00184 {
00185 uint8_t sreg, k;
00186 uint16_t eeaddr = 0;
00187 uint8_t eeclear[32] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00188 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00189 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00190 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
00191
00192 sreg = SREG;
00193 cli();
00194
00195
00196 for(k = 0; k < EEPROM_SIZE / 32; k++)
00197 {
00198 eeprom_update_block(eeclear, (void*)eeaddr, 32);
00199 eeaddr = eeaddr + 32;
00200 }
00201
00202 SREG = sreg;
00203 }
00204
00213 void ResetEEPROM()
00214 {
00215 EraseEEPROM();
00216
00217 eeprom_write_byte((uint8_t*)EEPROM_WARM_RESET, 0);
00218 eeprom_write_dword((uint32_t*)EEPROM_TIMER_T2, 0);
00219 eeprom_write_dword((uint32_t*)EEPROM_TEMP_1, 0);
00220 eeprom_write_dword((uint32_t*)EEPROM_TEMP_2, 0);
00221 eeprom_write_byte((uint8_t*)EEPROM_APPLICATION, 0);
00222 eeprom_write_byte((uint8_t*)EEPROM_COUNTER, 0);
00223 eeprom_write_byte(
00224 (uint8_t*)EEPROM_TLOG_POINTER_HI, (EEPROM_TLOG_DATA >> 8) & 0xFF);
00225 eeprom_write_byte(
00226 (uint8_t*)EEPROM_TLOG_POINTER_LO, EEPROM_TLOG_DATA & 0xFF);
00227 }
00228
00236 void RunBootloader()
00237 {
00238 bootkey = MAGIC_BOOT_KEY;
00239 EnableWDT(100);
00240 while(1);
00241 }
00242
00243
00247 uint8_t TestDDA(uint8_t convention, uint8_t TC1)
00248 {
00249 uint8_t status = 0;
00250 RAPDU *response = NULL;
00251 FCITemplate *fci = NULL;
00252 APPINFO *appInfo = NULL;
00253 RECORD *tData = NULL;
00254 ByteArray *offlineAuthData = NULL;
00255 ByteArray *ddata = NULL;
00256
00257 EnableWDT(4000);
00258
00259
00260
00261 fci = SelectFromAID(convention, TC1, NULL, 0);
00262 if(fci == NULL)
00263 {
00264 fprintf(stderr, "Error\n");
00265 status = 1;
00266 goto endtransaction;
00267 }
00268 ResetWDT();
00269
00270
00271 appInfo = InitializeTransaction(convention, TC1, fci, 0);
00272 if(appInfo == NULL)
00273 {
00274 fprintf(stderr, "Error\n");
00275 status = 1;
00276 goto endfci;
00277 }
00278 ResetWDT();
00279
00280
00281 offlineAuthData = (ByteArray*)malloc(sizeof(ByteArray));
00282 tData = GetTransactionData(convention, TC1, appInfo, offlineAuthData, 0);
00283 if(tData == NULL)
00284 {
00285 fprintf(stderr, "Error\n");
00286 status = 1;
00287 goto endappinfo;
00288 }
00289 ResetWDT();
00290
00291
00292 ddata = MakeByteArrayV(4,
00293 0x05, 0x06, 0x07, 0x08
00294 );
00295 response = SignDynamicData(convention, TC1, ddata, 0);
00296 if(response == NULL)
00297 {
00298 fprintf(stderr, "Error\n");
00299 status = 1;
00300 goto endtdata;
00301 }
00302
00303 FreeRAPDU(response);
00304 FreeByteArray(ddata);
00305 endtdata:
00306 FreeRECORD(tData);
00307 endappinfo:
00308 FreeAPPINFO(appInfo);
00309 if(offlineAuthData != NULL)
00310 FreeByteArray(offlineAuthData);
00311 endfci:
00312 FreeFCITemplate(fci);
00313 endtransaction:
00314 DeactivateICC();
00315 asm volatile("nop\n\t"::);
00316 _delay_ms(50);
00317
00318 DisableWDT();
00319 return status;
00320 }
00321
00322
00331 uint8_t Terminal(log_struct_t *logger)
00332 {
00333 uint8_t convention, proto, TC1, TA3, TB3;
00334 uint8_t error;
00335 uint8_t tmp;
00336 RAPDU *response = NULL;
00337 FCITemplate *fci = NULL;
00338 APPINFO *appInfo = NULL;
00339 RECORD *tData = NULL;
00340 ByteArray *offlineAuthData = NULL;
00341 ByteArray *pinTryCounter = NULL;
00342 ByteArray *pin = NULL;
00343 ByteArray *ddata = NULL;
00344 ByteArray *bdata = NULL;
00345 ByteArray *atcData = NULL;
00346 ByteArray *lastAtcData = NULL;
00347 GENERATE_AC_PARAMS acParams;
00348 const TLV *cdol = NULL;
00349
00350 if(!lcdAvailable)
00351 {
00352 Led2On();
00353 _delay_ms(1000);
00354 Led2Off();
00355 return RET_ERROR;
00356 }
00357
00358 InitLCD();
00359 fprintf(stderr, "\n");
00360 fprintf(stderr, "Terminal\n");
00361 _delay_ms(1000);
00362
00363 DisableWDT();
00364 DisableTerminalResetInterrupt();
00365 DisableICCInsertInterrupt();
00366
00367
00368 fprintf(stderr, "%s\n", strInsertCard);
00369 while(IsICCInserted() == 0);
00370 fprintf(stderr, "%s\n", strCardInserted);
00371 if(logger)
00372 LogByte1(logger, LOG_ICC_INSERTED, 0);
00373
00374 EnableWDT(4000);
00375
00376
00377 error = ResetICC(0, &convention, &proto, &TC1, &TA3, &TB3, logger);
00378 if(error)
00379 {
00380 fprintf(stderr, "Error: %d\n", error);
00381 _delay_ms(1000);
00382 goto endtransaction;
00383 }
00384 if(proto != 0)
00385 {
00386 error = RET_ICC_BAD_PROTO;
00387 fprintf(stderr, "Error: %d\n", error);
00388 _delay_ms(1000);
00389 goto endtransaction;
00390 }
00391 ResetWDT();
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405 fci = SelectFromAID(convention, TC1, NULL, logger);
00406 if(fci == NULL)
00407 {
00408 error = RET_EMV_SELECT;
00409 fprintf(stderr, "Error: %d\n", error);
00410 _delay_ms(1000);
00411 goto endtransaction;
00412 }
00413 ResetWDT();
00414
00415
00416 appInfo = InitializeTransaction(convention, TC1, fci, logger);
00417 if(appInfo == NULL)
00418 {
00419 error = RET_EMV_INIT_TRANSACTION;
00420 fprintf(stderr, "Error: %d\n", error);
00421 _delay_ms(1000);
00422 goto endfci;
00423 }
00424 ResetWDT();
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 offlineAuthData = NULL;
00435 tData = GetTransactionData(convention, TC1, appInfo, offlineAuthData, logger);
00436 if(tData == NULL)
00437 {
00438 error = RET_EMV_READ_DATA;
00439 fprintf(stderr, "Error: %d\n", error);
00440 _delay_ms(1000);
00441 goto endappinfo;
00442 }
00443 ResetWDT();
00444
00445
00446 atcData = GetDataObject(convention, TC1, PDO_ATC, logger);
00447 ResetWDT();
00448
00449
00450 lastAtcData = GetDataObject(convention, TC1, PDO_LAST_ATC, logger);
00451 ResetWDT();
00452
00453 if(atcData)
00454 {
00455 fprintf(stderr, "atc: %d\n", (atcData->bytes[0] << 8) | atcData->bytes[1]);
00456 _delay_ms(1000);
00457 }
00458
00459 if(lastAtcData)
00460 {
00461 fprintf(stderr, "last onlatc: %d\n", (lastAtcData->bytes[0] << 8) | lastAtcData->bytes[1]);
00462 _delay_ms(1000);
00463 }
00464
00465
00466 if((appInfo->aip[0] & 0x20) != 0)
00467 {
00468 ddata = MakeByteArrayV(4,
00469 0x01, 0x02, 0x03, 0x04
00470 );
00471 response = SignDynamicData(convention, TC1, ddata, logger);
00472 if(response == NULL)
00473 {
00474 error = RET_EMV_DDA;
00475 fprintf(stderr, "Error: %d\n", error);
00476 goto endatcdata;
00477 }
00478 ResetWDT();
00479 }
00480
00481
00482 pinTryCounter = GetDataObject(convention, TC1, PDO_PIN_TRY_COUNTER, logger);
00483 if(pinTryCounter == NULL)
00484 {
00485 error = RET_EMV_GET_DATA;
00486 fprintf(stderr, "Error: %d\n", error);
00487 goto endatcdata;
00488 }
00489 if(pinTryCounter->bytes[0] == 0)
00490 {
00491 error = RET_EMV_PIN_TRY_EXCEEDED;
00492 fprintf(stderr, "Error: %d\n", error);
00493 goto endpintry;
00494 }
00495 ResetWDT();
00496
00497 fprintf(stderr, "pin try:%d\n", pinTryCounter->bytes[0]);
00498 _delay_ms(1000);
00499 ResetWDT();
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 acParams.tvr[0] = 0x80;
00526 acParams.terminalCountryCode[0] = 0x08;
00527 acParams.terminalCountryCode[1] = 0x26;
00528 acParams.terminalCurrencyCode[0] = 0x08;
00529 acParams.terminalCurrencyCode[1] = 0x26;
00530 acParams.transactionDate[0] = 0x01;
00531 acParams.transactionDate[1] = 0x01;
00532 acParams.transactionDate[2] = 0x01;
00533 cdol = GetTLVFromRECORD(tData, 0x8C, 0);
00534 if(cdol == NULL)
00535 {
00536 error = RET_ERROR;
00537 fprintf(stderr, "Error: %d\n", error);
00538 goto endpin;
00539 }
00540
00541 if(response != NULL) FreeRAPDU(response);
00542 response = SendGenerateAC(
00543 convention, TC1, AC_REQ_ARQC, cdol, &acParams, logger);
00544 if(response == NULL)
00545 {
00546 error = RET_EMV_GENERATE_AC;
00547 fprintf(stderr, "Error: %d\n", error);
00548 goto endpin;
00549 }
00550
00551 fprintf(stderr, "%s\n", strDone);
00552 error = 0;
00553 FreeRAPDU(response);
00554 endpin:
00555
00556 endpintry:
00557 FreeByteArray(pinTryCounter);
00558 endatcdata:
00559 FreeByteArray(lastAtcData);
00560 FreeByteArray(atcData);
00561 endtdata:
00562 FreeRECORD(tData);
00563 endappinfo:
00564 FreeAPPINFO(appInfo);
00565 if(offlineAuthData != NULL)
00566 FreeByteArray(offlineAuthData);
00567 endfci:
00568 FreeFCITemplate(fci);
00569 endtransaction:
00570 DisableWDT();
00571 DeactivateICC();
00572
00573 if(logger)
00574 {
00575 LogByte1(logger, LOG_ICC_DEACTIVATED, 0);
00576 fprintf(stderr, "%s\n", strLog);
00577 WriteLogEEPROM(logger);
00578 ResetLogger(logger);
00579 }
00580
00581 return error;
00582 }
00583
00584
00601 uint8_t FilterGenerateAC(log_struct_t *logger)
00602 {
00603 uint8_t t_inverse = 0, t_TC1 = 0;
00604 uint8_t cInverse, cProto, cTC1, cTA3, cTB3;
00605 uint8_t tmp, error;
00606 uint8_t posCDOL1 = 0;
00607 uint8_t amount[12];
00608 uint8_t gotGAC = 0;
00609 CAPDU *cmd;
00610 RAPDU *response;
00611 RECORD *record;
00612 CRP *crp;
00613
00614 if(!lcdAvailable)
00615 {
00616 Led2On();
00617 _delay_ms(1000);
00618 Led2Off();
00619 return RET_ERROR;
00620 }
00621
00622 InitLCD();
00623 fprintf(stderr, "\n");
00624 fprintf(stderr, "Filter Gen AC\n");
00625 _delay_ms(1000);
00626
00627 DisableWDT();
00628 DisableTerminalResetInterrupt();
00629 DisableICCInsertInterrupt();
00630
00631
00632 fprintf(stderr, "%s\n", strInsertCard);
00633 while(IsICCInserted() == 0);
00634 fprintf(stderr, "%s\n", strCardInserted);
00635 if(logger)
00636 LogByte1(logger, LOG_ICC_INSERTED, 0);
00637 while(GetTerminalResetLine() != 0);
00638 fprintf(stderr, "%s\n", strTerminalReset);
00639 if(logger)
00640 LogByte1(logger, LOG_TERMINAL_RST_LOW, 0);
00641
00642 EnableWDT(4000);
00643
00644 error = InitSCDTransaction(t_inverse, t_TC1, &cInverse,
00645 &cProto, &cTC1, &cTA3, &cTB3, logger);
00646 if(error)
00647 goto enderror;
00648
00649
00650 while(posCDOL1 == 0)
00651 {
00652 ResetWDT();
00653 cmd = ReceiveT0Command(t_inverse, t_TC1, logger);
00654 if(cmd == NULL)
00655 {
00656 error = RET_TERMINAL_GET_CMD;
00657 goto enderror;
00658 }
00659
00660 if((cmd->cmdHeader->cla & 0xF0) == 0 &&
00661 cmd->cmdHeader->ins == 0xB2)
00662 {
00663
00664 if(SendT0Command(cInverse, cTC1, cmd, logger))
00665 {
00666 error = RET_ICC_SEND_CMD;
00667 FreeCAPDU(cmd);
00668 goto enderror;
00669 }
00670
00671 response = ReceiveT0Response(cInverse, cmd->cmdHeader, logger);
00672 if(response == NULL)
00673 {
00674 error = RET_ICC_GET_RESPONSE;
00675 FreeCAPDU(cmd);
00676 goto enderror;
00677 }
00678
00679 if(response->repData != NULL)
00680 {
00681 record = ParseRECORD(response->repData, response->lenData);
00682 if(record == NULL)
00683 {
00684 error = RET_ERROR;
00685 FreeCAPDU(cmd);
00686 FreeRAPDU(response);
00687 goto enderror;
00688 }
00689
00690 posCDOL1 = AmountPositionInCDOLRecord(record);
00691 FreeRECORD(record);
00692 record = NULL;
00693 }
00694
00695 if(SendT0Response(t_inverse, cmd->cmdHeader, response, logger))
00696 {
00697 error = RET_TERMINAL_SEND_RESPONSE;
00698 FreeCAPDU(cmd);
00699 FreeRAPDU(response);
00700 goto enderror;
00701 }
00702 }
00703 else
00704 {
00705
00706 if(SendT0Command(cInverse, cTC1, cmd, logger))
00707 {
00708 error = RET_ICC_SEND_CMD;
00709 FreeCAPDU(cmd);
00710 goto enderror;
00711 }
00712
00713 response = ForwardResponse(t_inverse, cInverse, cmd->cmdHeader, logger);
00714 if(response == NULL)
00715 {
00716 error = RET_ERROR;
00717 FreeCAPDU(cmd);
00718 goto enderror;
00719 }
00720
00721
00722 FreeCAPDU(cmd);
00723 FreeRAPDU(response);
00724 }
00725 }
00726
00727
00728 DisableWDT();
00729
00730
00731 while(gotGAC == 0)
00732 {
00733 cmd = ReceiveT0Command(t_inverse, t_TC1, logger);
00734 if(cmd == NULL)
00735 {
00736 error = RET_TERMINAL_GET_CMD;
00737 goto enderror;
00738 }
00739
00740 if((cmd->cmdHeader->cla & 0xF0) == 0x80 &&
00741 cmd->cmdHeader->ins == 0xAE)
00742 {
00743
00744 if(cmd->cmdData == NULL)
00745 {
00746 error = RET_ERROR;
00747 FreeCAPDU(cmd);
00748 goto enderror;
00749 }
00750
00751 gotGAC = 1;
00752
00753 posCDOL1--;
00754 amount[0] = (cmd->cmdData[posCDOL1] & 0xF0) >> 4;
00755 amount[1] = cmd->cmdData[posCDOL1] & 0x0F;
00756 amount[2] = (cmd->cmdData[posCDOL1 + 1] & 0xF0) >> 4;
00757 amount[3] = cmd->cmdData[posCDOL1 + 1] & 0x0F;
00758 amount[4] = (cmd->cmdData[posCDOL1 + 2] & 0xF0) >> 4;
00759 amount[5] = cmd->cmdData[posCDOL1 + 2] & 0x0F;
00760 amount[6] = (cmd->cmdData[posCDOL1 + 3] & 0xF0) >> 4;
00761 amount[7] = cmd->cmdData[posCDOL1 + 3] & 0x0F;
00762 amount[8] = (cmd->cmdData[posCDOL1 + 4] & 0xF0) >> 4;
00763 amount[9] = cmd->cmdData[posCDOL1 + 4] & 0x0F;
00764 amount[10] = (cmd->cmdData[posCDOL1 + 5] & 0xF0) >> 4;
00765 amount[11] = cmd->cmdData[posCDOL1 + 5] & 0x0F;
00766
00767
00768
00769
00770
00771
00772
00773 while(1){
00774 fprintf(stderr, "%s\n", strScroll);
00775 do{
00776 tmp = GetButton();
00777 _delay_ms(100);
00778 if(SendByteTerminalParity(0x60, t_inverse))
00779 {
00780 error = RET_TERMINAL_SEND_RESPONSE;
00781 FreeCAPDU(cmd);
00782 goto enderror;
00783 }
00784 }while((tmp & BUTTON_C) == 0);
00785 _delay_ms(100);
00786
00787 fprintf(stderr, "Amt:%1X%1X%1X%1X%1X%1X%1X%1X%1X,%1X%1X\n",
00788 amount[1],
00789 amount[2],
00790 amount[3],
00791 amount[4],
00792 amount[5],
00793 amount[6],
00794 amount[7],
00795 amount[8],
00796 amount[9],
00797 amount[10],
00798 amount[11]);
00799
00800 do{
00801 tmp = GetButton();
00802 _delay_ms(100);
00803 if(SendByteTerminalParity(0x60, t_inverse))
00804 {
00805 error = RET_TERMINAL_SEND_RESPONSE;
00806 FreeCAPDU(cmd);
00807 goto enderror;
00808 }
00809 }while((tmp & BUTTON_C) == 0);
00810 _delay_ms(100);
00811
00812 fprintf(stderr, "%s\n", strDecide);
00813 do{
00814 tmp = GetButton();
00815 _delay_ms(100);
00816 if(SendByteTerminalParity(0x60, t_inverse))
00817 {
00818 error = RET_TERMINAL_SEND_RESPONSE;
00819 FreeCAPDU(cmd);
00820 goto enderror;
00821 }
00822 }while(((tmp & BUTTON_A) == 0) &&
00823 ((tmp & BUTTON_C) == 0) &&
00824 ((tmp & BUTTON_D) == 0));
00825 _delay_ms(100);
00826
00827 if((tmp & BUTTON_D) != 0)
00828 {
00829 return RET_ERROR;
00830 }
00831
00832 if((tmp & BUTTON_A) != 0) break;
00833 }
00834
00835 }
00836
00837 if(SendT0Command(cInverse, cTC1, cmd, logger))
00838 {
00839 error = RET_ICC_SEND_CMD;
00840 FreeCAPDU(cmd);
00841 goto enderror;
00842 }
00843
00844 response = ForwardResponse(t_inverse, cInverse, cmd->cmdHeader, logger);
00845 FreeCAPDU(cmd);
00846
00847 if(response == NULL)
00848 {
00849 error = RET_ERROR;
00850 FreeRAPDU(response);
00851 goto enderror;
00852 }
00853 FreeRAPDU(response);
00854 }
00855
00856 EnableWDT(4000);
00857
00858 while(1)
00859 {
00860 crp = ExchangeCompleteData(t_inverse, cInverse, t_TC1, cTC1, logger);
00861 if(crp == NULL)
00862 {
00863 error = RET_ERROR;
00864 goto enderror;
00865 }
00866 FreeCRP(crp);
00867 ResetWDT();
00868 }
00869
00870 error = 0;
00871
00872 enderror:
00873 DisableWDT();
00874 DeactivateICC();
00875 if(logger)
00876 {
00877 LogByte1(logger, LOG_ICC_DEACTIVATED, 0);
00878 WriteLogEEPROM(logger);
00879 fprintf(stderr, "%s\n", strLog);
00880 ResetLogger(logger);
00881 }
00882
00883 return error;
00884 }
00885
00904 uint8_t StorePIN(log_struct_t *logger)
00905 {
00906 uint8_t t_inverse = 0, t_TC1 = 0;
00907 uint8_t cInverse, cProto, cTC1, cTA3, cTB3;
00908 uint8_t tmp, len, error;
00909 CRP *crp;
00910
00911 if(lcdAvailable)
00912 {
00913 InitLCD();
00914 fprintf(stderr, "\n");
00915 fprintf(stderr, "Store PIN\n");
00916 _delay_ms(1000);
00917 }
00918
00919 DisableWDT();
00920 DisableTerminalResetInterrupt();
00921 DisableICCInsertInterrupt();
00922
00923
00924 if(lcdAvailable)
00925 fprintf(stderr, "%s\n", strInsertCard);
00926 while(IsICCInserted() == 0);
00927 if(lcdAvailable)
00928 fprintf(stderr, "%s\n", strCardInserted);
00929 if(logger)
00930 LogByte1(logger, LOG_ICC_INSERTED, 0);
00931 while(GetTerminalResetLine() != 0);
00932 if(lcdAvailable)
00933 fprintf(stderr, "%s\n", strTerminalReset);
00934 if(logger)
00935 LogByte1(logger, LOG_TERMINAL_RST_LOW, 0);
00936
00937 error = InitSCDTransaction(t_inverse, t_TC1, &cInverse,
00938 &cProto, &cTC1, &cTA3, &cTB3, logger);
00939 if(error)
00940 goto enderror;
00941
00942 while(1)
00943 {
00944 crp = ExchangeCompleteData(t_inverse, cInverse, t_TC1, cTC1, logger);
00945 if(crp == NULL)
00946 {
00947 break;
00948 }
00949
00950
00951 if(crp->cmd->cmdHeader->cla == 0x00 &&
00952 crp->cmd->cmdHeader->ins == 0x20)
00953 {
00954
00955 if(crp->cmd->cmdHeader->p2 != 0x80 ||
00956 crp->cmd->cmdData == NULL)
00957 {
00958 error = RET_TERMINAL_ENCRYPTED_PIN;
00959 if(lcdAvailable)
00960 fprintf(stderr, "Error: %d\n", error);
00961 goto enderror;
00962 }
00963
00964 tmp = crp->cmd->cmdData[0];
00965 len = crp->cmd->cmdHeader->p3;
00966 if((tmp & 0xF0) != 0x20 || len != crp->cmd->lenData)
00967 {
00968 error = RET_ERROR;
00969 if(lcdAvailable)
00970 fprintf(stderr, "Error: %d\n", error);
00971 error = RET_ERROR;
00972 goto enderror;
00973 }
00974
00975
00976 cli();
00977 eeprom_write_byte((uint8_t*)EEPROM_PIN, len);
00978 eeprom_write_block(crp->cmd->cmdData, (void*)(EEPROM_PIN + 1), len);
00979
00980
00981 if(lcdAvailable)
00982 fprintf(stderr, "PIN stored\n");
00983 }
00984
00985 FreeCRP(crp);
00986 }
00987
00988 error = 0;
00989
00990 enderror:
00991 DeactivateICC();
00992 if(logger)
00993 {
00994 LogByte1(logger, LOG_ICC_DEACTIVATED, 0);
00995 if(lcdAvailable)
00996 fprintf(stderr, "%s\n", strLog);
00997 WriteLogEEPROM(logger);
00998 ResetLogger(logger);
00999 }
01000
01001 return error;
01002 }
01003
01013 uint8_t ForwardAndChangePIN(log_struct_t *logger)
01014 {
01015 uint8_t t_inverse = 0, t_TC1 = 0, tdelay;
01016 uint8_t cInverse, cProto, cTC1, cTA3, cTB3;
01017 CAPDU *cmd, *tcmd = NULL;
01018 RAPDU *response;
01019 uint8_t sreg, len;
01020 uint8_t *pin;
01021 uint8_t error;
01022
01023 if(lcdAvailable)
01024 {
01025 InitLCD();
01026 fprintf(stderr, "\n");
01027 fprintf(stderr, "Change PIN\n");
01028 _delay_ms(1000);
01029 }
01030
01031 DisableWDT();
01032 DisableTerminalResetInterrupt();
01033 DisableICCInsertInterrupt();
01034
01035
01036 if(lcdAvailable)
01037 fprintf(stderr, "%s\n", strInsertCard);
01038 while(IsICCInserted() == 0);
01039 if(lcdAvailable)
01040 fprintf(stderr, "%s\n", strCardInserted);
01041 if(logger)
01042 LogByte1(logger, LOG_ICC_INSERTED, 0);
01043 while(GetTerminalResetLine() != 0);
01044 if(lcdAvailable)
01045 fprintf(stderr, "%s\n", strTerminalReset);
01046 if(logger)
01047 LogByte1(logger, LOG_TERMINAL_RST_LOW, 0);
01048
01049
01050 sreg = SREG;
01051 cli();
01052 len = eeprom_read_byte((uint8_t*)EEPROM_PIN);
01053 SREG = sreg;
01054 pin = (uint8_t*)malloc(len * sizeof(uint8_t));
01055 if(pin == NULL)
01056 {
01057 error = RET_ERROR;
01058 goto enderror;
01059 }
01060 eeprom_read_block(pin, (void*)(EEPROM_PIN + 1), len);
01061
01062 error = InitSCDTransaction(t_inverse, t_TC1, &cInverse,
01063 &cProto, &cTC1, &cTA3, &cTB3, logger);
01064 if(error)
01065 {
01066 if(lcdAvailable)
01067 {
01068 fprintf(stderr, "Error: %d\n", error);
01069 _delay_ms(1000);
01070 }
01071 goto enderror;
01072 }
01073
01074
01075 while(1)
01076 {
01077 cmd = ReceiveT0Command(t_inverse, t_TC1, logger);
01078 if(cmd == NULL)
01079 {
01080 error = RET_ERROR;
01081 goto enderror;
01082 }
01083
01084
01085 if(cmd->cmdHeader->cla == 0 &&
01086 cmd->cmdHeader->ins == 0x20 &&
01087 cmd->cmdHeader->p2 == 0x80 &&
01088 cmd->cmdData != NULL)
01089 {
01090
01091 tdelay = 1 + cTC1;
01092 tcmd = (CAPDU*)malloc(sizeof(CAPDU));
01093 tcmd->cmdHeader = (EMVCommandHeader*)malloc(sizeof(EMVCommandHeader));
01094 tcmd->cmdData = pin;
01095 tcmd->lenData = len;
01096 tcmd->cmdHeader->cla = cmd->cmdHeader->cla;
01097 tcmd->cmdHeader->ins = cmd->cmdHeader->ins;
01098 tcmd->cmdHeader->p1 = cmd->cmdHeader->p1;
01099 tcmd->cmdHeader->p2 = cmd->cmdHeader->p2;
01100 tcmd->cmdHeader->p3 = len;
01101
01102
01103 if(SendT0Command(cInverse, cTC1, tcmd, logger))
01104 {
01105 error = RET_ICC_SEND_CMD;
01106 FreeCAPDU(cmd);
01107 goto enderror;
01108 }
01109
01110 response = ForwardResponse(t_inverse, cInverse, tcmd->cmdHeader, logger);
01111 if(response == NULL)
01112 {
01113 error = RET_ERROR;
01114 FreeCAPDU(cmd);
01115 FreeCAPDU(tcmd);
01116 goto enderror;
01117 }
01118
01119 FreeCAPDU(cmd);
01120 FreeCAPDU(tcmd);
01121 FreeRAPDU(response);
01122 }
01123 else
01124 {
01125 if(SendT0Command(cInverse, cTC1, cmd, logger))
01126 {
01127 error = RET_ICC_SEND_CMD;
01128 FreeCAPDU(cmd);
01129 goto enderror;
01130 }
01131
01132 response = ForwardResponse(t_inverse, cInverse, cmd->cmdHeader, logger);
01133 if(response == NULL)
01134 {
01135 error = RET_ERROR;
01136 FreeCAPDU(cmd);
01137 goto enderror;
01138 }
01139
01140 FreeCAPDU(cmd);
01141 FreeRAPDU(response);
01142 }
01143
01144 }
01145
01146 error = 0;
01147
01148 enderror:
01149 DeactivateICC();
01150 if(logger)
01151 {
01152 LogByte1(logger, LOG_ICC_DEACTIVATED, 0);
01153 if(lcdAvailable)
01154 fprintf(stderr, "%s\n", strLog);
01155 WriteLogEEPROM(logger);
01156 ResetLogger(logger);
01157 }
01158
01159 return error;
01160 }
01161
01176 uint8_t ForwardData(log_struct_t *logger)
01177 {
01178 uint8_t t_inverse = 0, t_TC1 = 0, error = 0;
01179 uint8_t cInverse, cProto, cTC1, cTA3, cTB3;
01180 CRP *crp = NULL;
01181
01182 if(lcdAvailable)
01183 {
01184 InitLCD();
01185 fprintf(stderr, "\n");
01186 fprintf(stderr, "Forward Data\n");
01187 _delay_ms(1000);
01188 }
01189
01190 DisableWDT();
01191 DisableTerminalResetInterrupt();
01192 DisableICCInsertInterrupt();
01193
01194
01195 if(lcdAvailable)
01196 fprintf(stderr, "%s\n", strInsertCard);
01197 while(IsICCInserted() == 0);
01198 if(lcdAvailable)
01199 fprintf(stderr, "%s\n", strCardInserted);
01200 if(logger)
01201 LogByte1(logger, LOG_ICC_INSERTED, 0);
01202 while(GetTerminalResetLine() != 0);
01203 if(lcdAvailable)
01204 fprintf(stderr, "%s\n", strTerminalReset);
01205 if(logger)
01206 LogByte1(logger, LOG_TERMINAL_RST_LOW, 0);
01207
01208 error = InitSCDTransaction(t_inverse, t_TC1, &cInverse,
01209 &cProto, &cTC1, &cTA3, &cTB3, logger);
01210 if(error)
01211 {
01212 if(lcdAvailable)
01213 {
01214 fprintf(stderr, "Error: %d\n", error);
01215 _delay_ms(1000);
01216 }
01217 goto enderror;
01218 }
01219
01220
01221 nCounter++;
01222
01223 while(1)
01224 {
01225 crp = ExchangeCompleteData(
01226 t_inverse, cInverse, t_TC1, cTC1, logger);
01227 if(crp == NULL)
01228 break;
01229 FreeCRP(crp);
01230 }
01231
01232 error = 0;
01233
01234 enderror:
01235 DeactivateICC();
01236 if(logger)
01237 {
01238 LogByte1(logger, LOG_ICC_DEACTIVATED, 0);
01239 if(lcdAvailable)
01240 fprintf(stderr, "%s\n", strLog);
01241 WriteLogEEPROM(logger);
01242 ResetLogger(logger);
01243 }
01244
01245 return error;
01246 }
01247
01258 uint8_t ForwardDataLogAC(log_struct_t *logger)
01259 {
01260 uint8_t t_inverse = 0, t_TC1 = 0;
01261 uint8_t cInverse, cProto, cTC1, cTA3, cTB3;
01262 uint8_t gotAC = 0, error = 0;
01263 CAPDU *cmd;
01264 RAPDU *response;
01265 CRP *crp;
01266
01267 if(lcdAvailable)
01268 {
01269 InitLCD();
01270 fprintf(stderr, "\n");
01271 fprintf(stderr, "Forward Data2\n");
01272 _delay_ms(1000);
01273 }
01274
01275 DisableWDT();
01276 DisableTerminalResetInterrupt();
01277 DisableICCInsertInterrupt();
01278
01279
01280 if(lcdAvailable)
01281 fprintf(stderr, "%s\n", strInsertCard);
01282 while(IsICCInserted() == 0);
01283 if(lcdAvailable)
01284 fprintf(stderr, "%s\n", strCardInserted);
01285 if(logger)
01286 LogByte1(logger, LOG_ICC_INSERTED, 0);
01287 while(GetTerminalResetLine() != 0);
01288 if(lcdAvailable)
01289 fprintf(stderr, "%s\n", strTerminalReset);
01290 if(logger)
01291 LogByte1(logger, LOG_TERMINAL_RST_LOW, 0);
01292
01293
01294 error = InitSCDTransaction(t_inverse, t_TC1, &cInverse,
01295 &cProto, &cTC1, &cTA3, &cTB3, logger);
01296 if(error)
01297 {
01298 if(lcdAvailable)
01299 {
01300 fprintf(stderr, "Error: %d\n", error);
01301 _delay_ms(1000);
01302 }
01303 goto enderror;
01304 }
01305
01306
01307 nCounter++;
01308
01309
01310 while(gotAC == 0)
01311 {
01312 cmd = ReceiveT0Command(t_inverse, t_TC1, NULL);
01313 if(cmd == NULL)
01314 {
01315 error = RET_TERMINAL_GET_CMD;
01316 goto enderror;
01317 }
01318
01319 if((cmd->cmdHeader->cla & 0xF0) == 0x80 &&
01320 cmd->cmdHeader->ins == 0xAE)
01321 {
01322
01323 gotAC = 1;
01324 }
01325
01326 if(gotAC)
01327 error = SendT0Command(cInverse, cTC1, cmd, logger);
01328 else
01329 error = SendT0Command(cInverse, cTC1, cmd, NULL);
01330 if(error)
01331 {
01332 error = RET_ICC_SEND_CMD;
01333 FreeCAPDU(cmd);
01334 goto enderror;
01335 }
01336
01337 if(gotAC)
01338 response = ForwardResponse(t_inverse, cInverse, cmd->cmdHeader, logger);
01339 else
01340 response = ForwardResponse(t_inverse, cInverse, cmd->cmdHeader, NULL);
01341 if(response == NULL)
01342 {
01343 error = RET_ERROR;
01344 FreeCAPDU(cmd);
01345 goto enderror;
01346 }
01347
01348 FreeCAPDU(cmd);
01349 FreeRAPDU(response);
01350 }
01351
01352
01353 while(1)
01354 {
01355 crp = ExchangeCompleteData(
01356 t_inverse, cInverse, t_TC1, cTC1, logger);
01357 if(crp == NULL)
01358 break;
01359 FreeCRP(crp);
01360 }
01361
01362 error = 0;
01363
01364 enderror:
01365 DeactivateICC();
01366 if(logger)
01367 {
01368 LogByte1(logger, LOG_ICC_DEACTIVATED, 0);
01369 if(lcdAvailable)
01370 fprintf(stderr, "%s\n", strLog);
01371 WriteLogEEPROM(logger);
01372 ResetLogger(logger);
01373 }
01374
01375 return error;
01376 }
01377
01378
01388 void WriteLogEEPROM(log_struct_t *logger)
01389 {
01390 uint16_t addrStream, write_size;
01391 uint8_t addrHi, addrLo;
01392
01393 if(logger == NULL)
01394 return;
01395
01396 Led3On();
01397
01398
01399 eeprom_write_byte((uint8_t*)EEPROM_COUNTER, nCounter);
01400
01401
01402 addrHi = eeprom_read_byte((uint8_t*)EEPROM_TLOG_POINTER_HI);
01403 addrLo = eeprom_read_byte((uint8_t*)EEPROM_TLOG_POINTER_LO);
01404 addrStream = ((addrHi << 8) | addrLo);
01405
01406 if(logger->position > 0 && addrStream < EEPROM_MAX_ADDRESS)
01407 {
01408
01409 if(EEPROM_MAX_ADDRESS - addrStream < logger->position)
01410 write_size = EEPROM_MAX_ADDRESS - addrStream;
01411 else
01412 write_size = logger->position;
01413 eeprom_write_block(logger->log_buffer, (void*)addrStream, write_size);
01414 addrStream += write_size;
01415
01416
01417 addrHi = (uint8_t)((addrStream >> 8) & 0x00FF);
01418 addrLo = (uint8_t)(addrStream & 0x00FF);
01419 eeprom_write_byte((uint8_t*)EEPROM_TLOG_POINTER_HI, addrHi);
01420 eeprom_write_byte((uint8_t*)EEPROM_TLOG_POINTER_LO, addrLo);
01421 }
01422
01423 Led3Off();
01424 }
01425
01426