Guest User

Untitled

a guest
Sep 24th, 2018
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 50.87 KB | None | 0 0
  1. //=============================================================================
  2. // Hypercom Inc
  3. // (c) Copyright 2006
  4. //=============================================================================
  5. //
  6. // Module overview: PinPad.c
  7. // Pinpad functions
  8. // Info on Internal PIN-Pad of T2100:
  9. // Maskter Key is currently double-length
  10. // Triple-length key encryption/decryption is not supported
  11. //=============================================================================
  12. //=============================================================================
  13.  
  14. #include "basictyp.h"
  15. #include "sdk.h"
  16. #include "sdkos.h"
  17. #include "sdkio.h"
  18. #include "sdkmem.h"
  19. #include "sdktime.h"
  20. #include "osclib.h"
  21. #include "utllib.h"
  22. #include "app_profile.h"
  23. #include "fixdata.h"
  24. #include "app_msgid.h"
  25. #include "pindev.inc"
  26. #include "siodev.inc"
  27. #include "prtdev.inc"
  28. #include "rs232cfg.h"
  29. #include "tranutil.h"
  30. #include "GUI_Base.h"
  31. #include "pinattck.h"
  32. #include "pinpad.h"
  33. #include "cvtamt.h"
  34. #include "sha1.h"
  35.  
  36. //#include "CryptoService.h"
  37. #ifdef MAKE_VIKING
  38.  
  39. //#define __CS_TEST__
  40. #ifdef __CS_TEST__
  41. static void SecurityTest( void );
  42. #endif
  43.  
  44. typedef unsigned char* LPBYTE;
  45. typedef unsigned long DWORD;
  46. typedef unsigned int BOOL;
  47. extern void CS_Open(BOOL bVirginStart);
  48. extern DWORD CS_DecryptPIN(DWORD nKeyIndex, BYTE* pSPEK, BYTE* pPlainTextPIN, BYTE* pEncryptedPIN);
  49. extern DWORD CS_EncryptPIN(DWORD nKeyIndex, BYTE* pSPEK, BYTE* pCipher, BYTE* pPIN);
  50. extern DWORD CS_EncryptPIN_DUKPT(DWORD nKeyIndex, BYTE* pCipher, BYTE* pPIN_Block);
  51. extern DWORD CS_GenerateKey(DWORD nKeyIndex, BYTE* pKey);
  52. extern DWORD CS_GenerateKey_DUKPT(DWORD nKeyIndex);
  53. extern DWORD CS_CreateMAC(DWORD nKeyIndex, BYTE* pSMK, BYTE* pMAC, BYTE* pData, DWORD nLen, DWORD nType);
  54. extern DWORD CS_CreateMAC_DUKPT(DWORD nKeyIndex, BYTE* pMAC, BYTE* pData, DWORD nLen, DWORD nType);
  55. extern BOOL CS_StatusSSM(void);
  56. extern DWORD CS_GetSN(BYTE* pSn, DWORD nMaxLen);
  57. extern DWORD CS_StoreMK(DWORD nKeyIndex, BYTE* pKey);
  58. extern void C_DesTripleEncryptECB(LPBYTE pKey, LPBYTE pData, DWORD nDataLen, LPBYTE pResult);
  59. void C_DesTripleEncryptCBC(const BYTE* pKey, const BYTE* pIV, const BYTE* pData, DWORD nLen, BYTE* pResult);
  60. #endif // MAKE_VIKING
  61.  
  62.  
  63. //=============================================================================
  64. // External variables / declarations
  65. //=============================================================================
  66.  
  67.  
  68. //=============================================================================
  69. // Private defines and typedefs
  70. //=============================================================================
  71. #define S_AQWORKKEY 8 // PIN working key
  72.  
  73. //====================================================
  74. //=== PINSTAT bit values ===
  75. //====================================================
  76.  
  77. #define PinCard_Read 0x01 // Card read from pin.
  78. #define PinCardReadReqPend 0x02 // Card Read Request Pending Bit
  79. #define PinWaitUserAction 0x04 // Waiting for User Action
  80. #define PinWaitResetResp 0x08 // Wait for Reset Response
  81. #define PinCardReadError 0x10 // Card Read Error
  82. #define PinSmartCard_Read 0x40 /* Smart Card read from pinpad */
  83. #define PinCancelCardSwipe 0x80 // Cancel Card Swipe
  84.  
  85. //====================================================
  86. //=== PIN_TYPE values ===
  87. //====================================================
  88.  
  89. #define PIN_TYPE_INVALID 0 // INVALID PIN PAD
  90. #define PIN_TYPE_EXTERNAL 1 // EXTERNAL PIN PAD
  91. #define PIN_TYPE_ICE5000 2 // INTEGRATED ICE5000
  92.  
  93.  
  94.  
  95. //=============================================================================
  96. // Private function declarations
  97. //=============================================================================
  98. static void PreparePinCalc( void );
  99. static UBYTE GetCommand( UBYTE* cmd, UBYTE* pMsgBuf);
  100. static UBYTE GetPINDevice( void );;
  101. static UBYTE GetMode( void );
  102. static void StartRspTimer( PTCS_BLK *blk, UBYTE *flag, unsigned short timeout );
  103. //static UBYTE GetFS( void );
  104. //static UBYTE GetEncKey(UBYTE ubAqId, int nProfileKeyId, UBYTE* pMsgBuf);
  105. static UBYTE GetEncKeyId( UBYTE ubAqId );
  106. static UBYTE GetMACKeyId( UBYTE ubAqId );
  107.  
  108.  
  109. static UBYTE InternalPinpadGetPin( struct TRANDATA_REC* pTranData );
  110. static UBYTE InternalMacGenerate(UBYTE* pData, UWORD uwDataLength,
  111. UBYTE* pMacKey, UBYTE ubAqId, UBYTE* pMac);
  112. static UBYTE InternalPinBGenerate(UBYTE* pData, UBYTE* pPinKey, UBYTE ubAqId,
  113. UBYTE* pEPinBlock);
  114.  
  115. //=============================================================================
  116. // Public data definitions
  117. //=============================================================================
  118. UBYTE PIN_DEVICE; /* PIN device type */
  119. void* PIN_CONFIG; /* Pointer to PIN device configuration parameters */
  120. UBYTE PIN_TYPE;
  121. // Pinpad status byte.
  122. UBYTE PINSTAT;
  123. UBYTE PowerOnFlag;
  124.  
  125. #define S_PINBUF (270)
  126. static UBYTE PINBUF[S_PINBUF];
  127. static UBYTE OUTPIN[128];
  128.  
  129. typedef struct
  130. {
  131. UBYTE device; // Device ID
  132. PIN_CPWR power; // Power mode
  133. void* cfgptr; // Pointer to configuration parameters
  134. } CFGDATA;
  135.  
  136. static const PINPRC CFG_S8_2400 = { PIN_CAT33, PIN_TERMINAL, SIO_7EVEN1, SIO_B2400 };
  137. static const PINPRC CFG_S8_9600 = { PIN_CAT33, PIN_TERMINAL, SIO_7EVEN1, SIO_B9600 };
  138. static const PINPRC CFG_S8_19200 = { PIN_CAT33, PIN_TERMINAL, SIO_7EVEN1, SIO_B19200 };
  139. static const PINPRC CFG_HFT105_485_2400 = { PIN_POSMINI, PIN_TERMINAL, SIO_8NONE1, SIO_B2400 };
  140. static const PINPRC CFG_HFT105_485_9600 = { PIN_POSMINI, PIN_TERMINAL, SIO_8NONE1, SIO_B9600 };
  141. static const PINPRC CFG_HFT105_485_19200 = { PIN_POSMINI, PIN_TERMINAL, SIO_8NONE1, SIO_B19200 };
  142. static const prtprc CFG_HFT105_232_2400 = { PRTP_POSMINI, SIO_8NONE1, SIO_B2400 };
  143. static const prtprc CFG_HFT105_232_9600 = { PRTP_POSMINI, SIO_8NONE1, SIO_B9600 };
  144. static const prtprc CFG_HFT105_232_19200 = { PRTP_POSMINI, SIO_8NONE1, SIO_B19200 };
  145.  
  146. static const CFGDATA ProtList[] =
  147. {
  148. #ifdef MAKE_VIKING
  149. { PIN, PIN_CPWR_OFF, (void*)&CFG_HFT105_485_19200 },
  150. // { PIN, PIN_CPWR_OFF, (void*)&CFG_HFT105_485_9600 },
  151. // { PIN, PIN_CPWR_OFF, (void*)&CFG_HFT105_485_2400 },
  152. // { PIN, PIN_CPWR_OFF, (void*)&CFG_S8_19200 },
  153. // { PIN, PIN_CPWR_OFF, (void*)&CFG_S8_9600 },
  154. { PIN, PIN_CPWR_OFF, (void*)&CFG_S8_2400 },
  155. #else // MAKE_VIKING
  156. { PIN, PIN_CPWR_ON, (void*)&CFG_HFT105_485_19200 },
  157. { PRT, PIN_CPWR_OFF, (void*)&CFG_HFT105_232_19200 },
  158. // { PRT, PIN_CPWR_OFF, (void*)&CFG_HFT105_232_9600 },
  159. // { PIN, PIN_CPWR_ON, (void*)&CFG_HFT105_485_9600 },
  160. { PIN, PIN_CPWR_ON, (void*)&CFG_HFT105_485_2400 },
  161. { PRT, PIN_CPWR_OFF, (void*)&CFG_HFT105_232_2400 },
  162. // { PIN, PIN_CPWR_OFF, (void*)&CFG_S8_19200 },
  163. { PIN, PIN_CPWR_OFF, (void*)&CFG_S8_9600 },
  164. { PIN, PIN_CPWR_OFF, (void*)&CFG_S8_2400 },
  165. #endif // MAKE_VIKING
  166. { 0, PIN_CPWR_OFF, NULL }
  167. };
  168.  
  169.  
  170. //=============================================================================
  171. // Private data definitions
  172. //=============================================================================
  173.  
  174.  
  175. //=============================================================================
  176. // Public function definitions
  177. //=============================================================================
  178.  
  179. //-----------------------------------------------------------------------------
  180. // PinInit Initialize the pin pad.
  181. //
  182. // Parameters: None
  183. // Global Inputs:
  184. // Returns: None
  185. // Notes: Calls PinReset() which will set PinRetval
  186. // to True if OK, False otherwise
  187. //-----------------------------------------------------------------------------
  188. extern void PinInit( void )
  189. {
  190. Bool DetectFlag;
  191. int PinMsgNumber;
  192.  
  193. /* Get PIN Pad Detect Flag */
  194. DetectFlag = ( 0xFF == TERM.TERMInit ) &&
  195. (GetProfileFlag(OPT_TR_PINDETECT, 0) || GetProfileFlag(OPT_TR_SMCARD_ENABLE, 0));
  196.  
  197. // Force pin type to invalid.
  198. PIN_TYPE = PIN_TYPE_INVALID;
  199. // Clear all bits in PINSTAT
  200. PINSTAT = 0;
  201. // Reset PIN device
  202. PIN_DEVICE = 0;
  203.  
  204. // Reset the Pin Pad.
  205. PinReset( );
  206.  
  207. /* Check detect flag */
  208. if ( DetectFlag )
  209. {
  210. if (GetProfileFlag(OPT_TR_SMCARD_ENABLE, 0))
  211. { // Send a "Ready" message
  212. PinMsgNumber = MSG_ID_PPAD_PinReady;
  213. } else
  214. { // Clear PIN Pad display
  215. PinMsgNumber = MSG_ID_PPAD_ClrScrn;
  216. }
  217.  
  218. // Send message to pinpad to display
  219. PinMessage( PinMsgNumber );
  220.  
  221. if ( GetProfileFlag(OPT_TR_SMCARD_ENABLE, 0) &&
  222. (PIN_CAT33 != *((UBYTE*)PIN_CONFIG)) &&
  223. (PIN_TYPE == PIN_TYPE_EXTERNAL) )
  224. { // Set the flag Smart Card Read from Pinpad
  225. PINSTAT |= PinSmartCard_Read;
  226. }
  227. }
  228. Rewind_Pin( );
  229. #ifdef __CS_TEST__
  230. SecurityTest();
  231. #endif
  232. }
  233.  
  234. //-----------------------------------------------------------------------------
  235. // PinPadTest PIN-Pad Test - for display test message on Pin-Pad
  236. //
  237. // Parameters: None
  238. //
  239. // Global Inputs:
  240. //
  241. // Returns: None
  242. //
  243. // Notes:
  244. //
  245. //-----------------------------------------------------------------------------
  246. extern void PinPadTest()
  247. {
  248. UBYTE retval;
  249. int nResultMsgId;
  250.  
  251. // Reset PINPAD variables
  252. // Force pin type to invalid.
  253. PIN_TYPE = PIN_TYPE_INVALID;
  254. // Clear all bits in PINSTAT
  255. PINSTAT = 0;
  256. // Reset PIN device
  257. PIN_DEVICE = 0;
  258.  
  259. // Select * PINPAD TEST * message to display on pinpad
  260. retval = PinMessage( MSG_ID_PPAD_PinTest );
  261.  
  262. // Display results of test.
  263. if ( retval )
  264. {
  265. nResultMsgId = MSG_ID_PASSED;
  266. SDK_BeepIt( 2 );
  267. } else
  268. {
  269. nResultMsgId = MSG_ID_ERR_FAILED;
  270. SystemBeep(BEEP_ERROR);
  271. }
  272. // prompt user of Pin-Pad testing
  273. SCR_DisplayEntryById( MSG_ID_PINPAD_TEST, 0 , nResultMsgId, 0,
  274. 5, SCR_N_PROMPT_STYLE);
  275. }
  276.  
  277. //-----------------------------------------------------------------------------
  278. // PinReset Reset the pin pad.
  279. //
  280. // Parameters: None
  281. // Global Inputs:
  282. // Returns: None
  283. // Notes: PinRetval set to True if OK, False otherwise
  284. //
  285. //-----------------------------------------------------------------------------
  286. extern void PinReset( void )
  287. {
  288. Rewind_Pin( );
  289.  
  290. // Reset Bits of PINSTAT
  291. PINSTAT &= ~PinCardReadReqPend;
  292. PINSTAT &= ~PinWaitUserAction;
  293. }
  294.  
  295. /*------------------------------------------------------------------
  296. * Name: Rewind_Pin
  297. * Description: Rewinds PIN device
  298. *
  299. * Parameters: None
  300. * Return Value: None
  301. * Notes:
  302. *-----------------------------------------------------------------*/
  303. extern void Rewind_Pin( void )
  304. {
  305. OS_DeviceRewind( PIN_DEVICE );
  306. OS_DeviceClose( PIN_DEVICE );
  307.  
  308. /* Clear 'Device Open' flag */
  309. PINFLG.deviceOpen = 0;
  310. }
  311.  
  312. //-----------------------------------------------------------------------------
  313. // PinMessage Build message and send it to the Pin Pad.
  314. //
  315. // Parameters: None
  316. // Global Inputs:
  317. // Returns: None
  318. // Notes: PinRetval set to True if OK, False otherwise
  319. // Message to display in PinMsgNumber.
  320. //-----------------------------------------------------------------------------
  321. extern UBYTE PinMessage( int PinMsgNumber )
  322. {
  323. UBYTE aTmp[20];
  324. UBYTE PinRetval;
  325. UBYTE length, ubLen, ubSize;
  326. int nSize;
  327.  
  328. // May need to add a Get PIN Semaphore in the future
  329.  
  330. PinRetval = False;
  331.  
  332. // Open and configure Pin Pad Port
  333. if ( OK == Open_Config( ) )
  334. {
  335. if ( PIN_TYPE_EXTERNAL == PIN_TYPE )
  336. {
  337. // Load the Message Type - Display Text Request
  338. PreparePinCalc();
  339. ubLen = 0;
  340. ubSize = GetCommand( "3C", OUTPIN+ubLen);
  341. ubLen += ubSize;
  342. // Load text message into buffer after message type ( 16 Bytes)
  343. memset(aTmp, 0x00, sizeof(aTmp));
  344. nSize = 16;
  345. MSG_GetMsgString(PinMsgNumber, aTmp, &nSize );
  346. length = StrLn( aTmp, 16 );
  347. memcpy( OUTPIN+ubLen, aTmp, (UWORD) length );
  348. if ( 16 < length )
  349. { // Pad the field with space
  350. memset(OUTPIN+ubLen+length, ' ', ( UWORD ) ( 16 - length ) );
  351. }
  352. ubLen += 16;
  353. // Write message to Pin Pad
  354. if ( OK == Write_Pin( ubLen ) )
  355. {
  356. PinRetval = True;
  357. // Display for a short time
  358. if (PowerOnFlag != 0xAA)
  359. {
  360. OS_Wait( ONESECOND*2 );
  361. }
  362. }
  363. // Close Pin Pad Port
  364. if ( OK != Close_Pin( ) )
  365. {
  366. PinRetval = False;
  367. }
  368. } else
  369. { // Internal T5000 pinpad.
  370. // Spoof it for now just like SPOS.
  371. PinRetval = True;
  372. }
  373. }
  374.  
  375. // May need to add a Release PIN Semaphore
  376.  
  377. return PinRetval;
  378. }
  379.  
  380. //-----------------------------------------------------------------------------
  381. // PinGetPin Get the PIN from the pin pad.
  382. //
  383. // Parameters: None
  384. // Global Inputs:
  385. // Returns: None
  386. // Notes: PinRetval set to True if OK, False otherwise
  387. // Notes: The S7 will retransmit both packets upon
  388. // CLEAR Key, S8 does not retransmit.
  389. //
  390. //-----------------------------------------------------------------------------
  391. extern UBYTE PinGetPin( struct TRANDATA_REC* pTranData )
  392. {
  393. UBYTE PinRetval;
  394.  
  395. // May need to add a Get PIN Semaphore in the future
  396.  
  397. PinRetval = False;
  398.  
  399. // Open and configure Pin Pad Port
  400. if ( OK == Open_Config( ) )
  401. {
  402. if ( PIN_TYPE_EXTERNAL == PIN_TYPE )
  403. {
  404. ////////////////////////////////////////////////////////////////////////////////
  405. // @@dump v01A, KF 033006, EXTERNAL PIN-PAD IS NOT SUPPORTED
  406. ////////////////////////////////////////////////////////////////////////////////
  407. } else
  408. { // Internal T5000 pinpad.
  409. PinRetval = InternalPinpadGetPin(pTranData);
  410. }
  411. }
  412.  
  413. // May need to add a Release PIN Semaphore
  414. return PinRetval;
  415. }
  416.  
  417. //-----------------------------------------------------------------------------
  418. // PinGenMac For generating MAC code on input data
  419. //
  420. // Parameters: ubMacOpt Mac option
  421. // '1' - Hypercom ECB MAC
  422. // '2' - X9.9 MAC
  423. // '3' - SHA1-RMAC
  424. // pMacKey Mac key encrypted under corresponding Master Key for Mac Key
  425. // (packed Hex string)
  426. // pData Data for MAC generation
  427. // uwDataLength Length of Data for MAC generation
  428. // pMac Return storage for the generated MAC (binary format, 8 bytes)
  429. //
  430. // Global Inputs:
  431. //
  432. // Returns: 0 successful MAC generated
  433. // non-zero for MAC generation failed
  434. // 1 invalid input data
  435. // 2 processing error (external PIN-PAD not supported)
  436. //
  437. // Notes:
  438. //
  439. //-----------------------------------------------------------------------------
  440.  
  441. extern UBYTE PinGenMac(UBYTE ubMacOpt, UBYTE* pMacKey, UBYTE ubAqId,
  442. UBYTE* pData, UWORD uwDataLength, UBYTE* pMac )
  443. {
  444. UWORD data_remaining, i;
  445. SHA1Context sha; /* SHA-1 context */
  446. UBYTE bCont;
  447. UBYTE WorkData[24];
  448. UBYTE MacBlock[8];
  449. unsigned char dummy[50];
  450.  
  451. if (uwDataLength == 0 || pData == NULL)
  452. { // invalid data, inform caller
  453. return 1;
  454. }
  455. switch(ubMacOpt)
  456. {
  457. case '1': // ECB MAC
  458. case '2': // X9.9 MAC
  459. case '3': // SHA1-RMAC
  460. vdLA_Print(0,"ECB / X9.9 / SHA1",0,0);
  461. break;
  462. default:
  463. // invalid MAC option
  464. return 1;
  465. }
  466. bCont = 0;
  467. while(!bCont)
  468. {
  469. // some pre-processing for
  470. switch(ubMacOpt)
  471. {
  472. case '1': // ECB MAC
  473. // generate the 8 bytes data for ECB MAC generation
  474. vdLA_Print(0,"case 1 ECB MAC",0,0);
  475. memset( MacBlock, 0, 8 );
  476. memset( WorkData, 0, 8 );
  477. data_remaining = uwDataLength;
  478. do
  479. {
  480. memset( WorkData, 0, 8 );
  481. if ( data_remaining > 8 )
  482. memcpy ( WorkData, pData, 8 );
  483. else
  484. memcpy ( WorkData, pData, data_remaining );
  485. for (i =0; i<8; i++)
  486. MacBlock[i] = WorkData[i] ^ MacBlock[i];
  487. if (data_remaining > 8)
  488. {
  489. data_remaining -= 8;
  490. pData += 8;
  491. } else
  492. {
  493. data_remaining = 0;
  494. }
  495. } while ( 0 != data_remaining );
  496. memset(dummy,0,sizeof(dummy));
  497. sprintf(dummy, "%02x %02x %02x %02x %02x %02x %02x %02x ",
  498. MacBlock[0], MacBlock[1], MacBlock[2], MacBlock[3],
  499. MacBlock[4], MacBlock[5], MacBlock[6], MacBlock[7] );
  500. vdLA_Print(0,dummy,0,0);
  501. memcpy ( WorkData, MacBlock, 8 );
  502. uwDataLength = 8;
  503. pData = WorkData;
  504. break;
  505. case '3': // SHA1-RMAC
  506. /*
  507. * Reset the SHA-1 context and process input
  508. */
  509. vdLA_Print(0,"case 3 SHA1",0,0);
  510. SHA1Reset(&sha);
  511. SHA1Input(&sha, pData, uwDataLength);
  512. memset(WorkData, 0x00, sizeof(WorkData));
  513. if (!SHA1Result(&sha))
  514. { // SHA1 error
  515. } else
  516. { // SHA1 is a 20 bytes digest, append 4 bytes 0x80, 0x00, 0x00, 0x00
  517. // to generate 24 bytes data for SHA1-RMAC DES/DES3 processing
  518. memcpy(WorkData, &sha.Message_Digest[0], 4);
  519. memcpy(WorkData+4, &sha.Message_Digest[1], 4);
  520. memcpy(WorkData+8, &sha.Message_Digest[2], 4);
  521. memcpy(WorkData+16, &sha.Message_Digest[3], 4);
  522. }
  523. WorkData[16] = 0x80;
  524. WorkData[17] = 0x00;
  525. WorkData[18] = 0x00;
  526. WorkData[19] = 0x00;
  527. uwDataLength = 24;
  528. pData = WorkData;
  529. break;
  530. }
  531. // continue for DES/3DES processing here
  532. if ( OK == Open_Config( ) )
  533. {
  534. if ( PIN_TYPE_EXTERNAL == PIN_TYPE )
  535. { // use external PIN PAD processing here
  536. bCont = 2;
  537. // + taha 01-09-2018 show bCont variable on rock +
  538. memset(dummy,0,sizeof(dummy));
  539. sprintf(dummy,"1 - bCont: %d / %02x", bCont, bCont);
  540. vdLA_Print(0,dummy,0,0);
  541. // - taha 01-09-2018 show bCont variable on rock -
  542. break;
  543. } else
  544. { // Internal T5000 pinpad.
  545. vdLA_Print(0,"before InternalMacGenerate",0,0);
  546. bCont = InternalMacGenerate(pData, uwDataLength,
  547. pMacKey, ubAqId, pMac);
  548. // + taha 01-09-2018 show bCont variable on rock +
  549. memset(dummy,0,sizeof(dummy));
  550. sprintf(dummy,"e - bCont: %d / %02x", bCont, bCont);
  551. vdLA_Print(0,dummy,0,0);
  552. // - taha 01-09-2018 show bCont variable on rock -
  553. }
  554. }
  555. break;
  556. }
  557. return bCont;
  558. }
  559.  
  560. //=============================================================================
  561. // Private function definitions
  562. //=============================================================================
  563. //-----------------------------------------------------------------------------
  564. // InternalPinpadGetPin For Using T2100 internal Pin-pad to enter Pin
  565. //
  566. // Parameters: pTranData Pointer to Transaction Data record
  567. //
  568. // Global Inputs:
  569. //
  570. // Returns: True successful enter Pin
  571. // False Pin entry failed or aborted
  572. //
  573. // Notes:
  574. // - Will update the following fields in the Transaction data record:
  575. // [TRPINBL] - with encrypted PIN block
  576. // [TRSTATUS[1]] - enabling bit TS2_PINBLOCK when PIN block entered
  577. //-----------------------------------------------------------------------------
  578.  
  579. static UBYTE InternalPinpadGetPin( struct TRANDATA_REC* pTranData )
  580. {
  581. int nSize;
  582. UWORD uwSize;
  583. UBYTE WorkData[8];
  584. UBYTE pinblock[13];
  585. UBYTE aTmp[40];
  586. UBYTE aPinKey[24];
  587. UBYTE status;
  588. UBYTE PinRetval;
  589.  
  590. PinRetval = False;
  591. // Display TOTAL and amount on line 1.
  592. memset(aTmp, 0x00, sizeof(aTmp));
  593. if ( pTranData->TRKEY != TRX_BALINQ )
  594. {
  595. CustomAmount(MSG_ID_AmountTotals, pTranData->TRTOTAM, aTmp,
  596. IsTRNOption(pTranData->nTRNOPT, TRNOPT_CREDIT));
  597. }
  598. MSG_SetUserMsg(1, aTmp, 21);
  599. memset( pinblock, 0, sizeof( pinblock ) );
  600. // Read pin from the keyboard, 4-12 digits
  601. nSize = 12;
  602. status = SCR_DataEntryById(MSG_ID_Pinpad, 0,
  603. MSG_ID_SPECIAL_MSG1, 0,
  604. pinblock, &nSize, 4, SCR_ENTRY_DATA_N|SCR_ENTRY_PASSWORD,
  605. SCR_STYLE_TITLE_CENTER);
  606. // Check if pin number has been entered
  607. if ( status )
  608. { // user aborted, inform caller
  609. return False;
  610. }
  611. uwSize = strlen( ( char * ) pinblock );
  612. // Combine pin length, pin and PAN and save at WorkData.
  613. FormatPin(uwSize, pinblock, pTranData->TRPAN, WorkData );
  614.  
  615. memset(aPinKey, 0x00, sizeof(aPinKey));
  616. uwSize = sizeof(aPinKey);
  617. GetProfileData(BD_AQ_PIN_KEY, pTranData->TRAQID, aPinKey, &uwSize);
  618. memset(pinblock, 0x00, sizeof(pinblock));
  619. if (InternalPinBGenerate(WorkData, aPinKey, pTranData->TRAQID,
  620. pinblock) == 0)
  621. { // PIN-block OK
  622. status = 1;
  623. } else
  624. { // error
  625. status = 0;
  626. }
  627. if ( !status )
  628. {
  629. ShowErrMsg( MSG_ID_EncryptError );
  630. } else
  631. {
  632. memcpy( pTranData->TRPINBL, pinblock, LEN_PIN_BLK );
  633.  
  634. /* Set PIN Block ready flag */
  635. pTranData->TRSTATUS[1] |= TS2_PINBLOCK;
  636.  
  637. #ifdef MAKE_PINATTACKDELAY
  638. // Setup the pin attack delay
  639. PinAttackDelay( pTranData->TRPAN, pTranData->TRPINBL, 0 );
  640. #endif //MAKE_PINATTACKDELAY
  641.  
  642. PinRetval = True;
  643. }
  644.  
  645. // Clean clear PIN block
  646. memset( WorkData, 0, sizeof(WorkData) );
  647. // Clear the entered pin.
  648. memset( pinblock, 0, sizeof( pinblock ) );
  649. return PinRetval;
  650. }
  651.  
  652. //-----------------------------------------------------------------------------
  653. // InternalPinBGenerate For Using T2100 internal SSM to generate Encrypted Pin-Block
  654. //
  655. // Parameters: pData Plain text Pin-block Data for encryption (8 binary bytes)
  656. // pPinKey Pin key encrypted under corresponding Master Key for Pin Key
  657. // (packed Hex string)
  658. // ubAqId Acquirer Id
  659. // pEPinBlock Return storage for the encrypted Pin-block (binary format, 8 bytes)
  660. //
  661. // Global Inputs:
  662. //
  663. // Returns: 0 successful Encrypted Pin-block and returned in [pEPinBlock]
  664. // non-zero for Encryption failed
  665. // 2 processing error (external PIN-PAD not supported)
  666. //
  667. // Notes:
  668. //
  669. //-----------------------------------------------------------------------------
  670.  
  671. static UBYTE InternalPinBGenerate(UBYTE* pData, UBYTE* pPinKey, UBYTE ubAqId,
  672. UBYTE* pEPinBlock)
  673. {
  674. UWORD uwKeyLen;
  675. UBYTE mkid;
  676. UBYTE tmpaqbuffer[S_AQWORKKEY + S_AQWORKKEY];
  677.  
  678. // @@dump, v01A, KF 042506
  679. // CURRENTLY, DUKPT IS NOT SUPPORTED HERE, WILL NEED ADDITION EFFORT TO IMPLEMENT DUKPT
  680.  
  681. // Set working key - binary value
  682. mkid = Binary(GetEncKeyId(ubAqId) );
  683.  
  684. // Implementation of Internal Master Session for PIN Key
  685. memset(tmpaqbuffer, 0x00, sizeof(tmpaqbuffer));
  686. switch(GetProfileByte(BD_AQ_KEY_LENGTH, ubAqId))
  687. {
  688. case 2: // double length key
  689. case 3: // triple length key, PS:the crypto API currently not supporting triple length key, use double length instead
  690. uwKeyLen = S_AQWORKKEY*2;
  691. break;
  692. case 1: // single length key
  693. default:
  694. uwKeyLen = S_AQWORKKEY;
  695. break;
  696. }
  697. memcpy( tmpaqbuffer, pPinKey, uwKeyLen );
  698. if (uwKeyLen == S_AQWORKKEY)
  699. { // duplicate the first part key to second part key
  700. memcpy(&tmpaqbuffer[S_AQWORKKEY], pPinKey, S_AQWORKKEY );
  701. }
  702. // generate encrypted PIN-Block
  703. CS_Open(False);
  704. if ( 1 == CS_EncryptPIN( mkid, tmpaqbuffer, pEPinBlock, pData ) )
  705. { // PIN-block encryption OK
  706. return 0;
  707. } else
  708. { // encryption failure
  709. return 2;
  710. }
  711. }
  712.  
  713. //-----------------------------------------------------------------------------
  714. // InternalMacGenerate For Using T2100 internal SSM to generate MAC
  715. //
  716. // Parameters: pData Data for MAC generation
  717. // uwDataLength Length of Data for MAC generation
  718. // pMacKey Mac key encrypted under corresponding Master Key for Mac Key
  719. // (packed Hex string)
  720. // ubAqId Acquirer Id
  721. // pMac Return storage for the generated MAC (binary format, 8 bytes)
  722. //
  723. // Global Inputs:
  724. //
  725. // Returns: 0 successful MAC generated 8 bytes MAC returned in [pMAC]
  726. // non-zero for MAC generation failed
  727. // 2 processing error (external PIN-PAD not supported)
  728. //
  729. // Notes:
  730. //
  731. //-----------------------------------------------------------------------------
  732.  
  733. static UBYTE InternalMacGenerate(UBYTE* pData, UWORD uwDataLength,
  734. UBYTE* pMacKey, UBYTE ubAqId, UBYTE* pMac)
  735. {
  736. UWORD uwKeyLen;
  737. UWORD data_remaining;
  738. UBYTE ubTmp, mkid, PinRetval;
  739. UBYTE WorkData[8];
  740. UBYTE MacBlock[8], aTmp[8];
  741. UBYTE tmpaqbuffer[S_AQWORKKEY + S_AQWORKKEY];
  742.  
  743. unsigned char dummy[50], szDummy[5];
  744. int i=0;
  745. // @@dump, v01A, KF 042506
  746. // CURRENTLY, DUKPT IS NOT SUPPORTED HERE, WILL NEED ADDITION EFFORT TO IMPLEMENT DUKPT
  747.  
  748. // Set working key - binary value
  749. mkid = Binary(GetMACKeyId(ubAqId) );
  750.  
  751. // Implementation of Internal Master Session for MAC Key
  752. memset(tmpaqbuffer, 0x00, sizeof(tmpaqbuffer));
  753. data_remaining = uwDataLength;
  754. switch(GetProfileByte(BD_AQ_KEY_LENGTH, ubAqId))
  755. {
  756. case 2: // double length key
  757. case 3: // triple length key, PS:the crypto API currently not supporting triple length key, use double length instead
  758. uwKeyLen = S_AQWORKKEY*2;
  759. break;
  760. case 1: // single length key
  761. default:
  762. uwKeyLen = S_AQWORKKEY;
  763. break;
  764. }
  765.  
  766.  
  767. //+ taha 05-09-2018 hard code mac key, and data +
  768. memset( pData, (UBYTE)'\x01', uwDataLength );
  769. memset( pMacKey, (UBYTE)'\x02', uwKeyLen);
  770. sprintf(dummy,"mkid: %02x",mkid);
  771. vdLA_Print(0,dummy,0,0);
  772. //- taha 05-09-2018 hard code mac key, and data -
  773.  
  774. // + taha 06-09-2018 show modified MAC data on rock +
  775. vdLA_Print(0,"MAC data modified:" ,0,0);
  776. memset(dummy,0,sizeof(dummy));
  777. for (i=0 ; i < uwDataLength ; i++)
  778. {
  779. memset(szDummy,0x00,sizeof(szDummy));
  780. sprintf(szDummy,"%02X ", *(pData+i) );
  781. strcat(dummy,szDummy);
  782.  
  783. if (strlen(dummy) >= 42)
  784. {
  785. vdLA_Print(0,dummy,0,0);
  786. memset(dummy,0x00,sizeof(dummy));
  787. }
  788. }
  789. if (strlen(dummy) > 0)
  790. {
  791. vdLA_Print(0,dummy,0,0);
  792. }
  793. // - taha 06-09-2018 show modified MAC data on rock -
  794.  
  795. // + taha 01-09-2018 show modified mac key on rock +
  796.  
  797. vdLA_Print(0,"mac key modified:",0,0);
  798. memset(dummy,0,sizeof(dummy));
  799. for (i=0 ; i < uwKeyLen ; i++ )
  800. {
  801. memset(szDummy,0x00,sizeof(szDummy));
  802. sprintf(szDummy,"%02X ", pMacKey[i] );
  803. strcat(dummy,szDummy);
  804.  
  805. if (strlen(dummy) >= 42)
  806. {
  807. vdLA_Print(0,dummy,0,0);
  808. memset(dummy,0x00,sizeof(dummy));
  809. }
  810. }
  811. if (strlen(dummy) > 0)
  812. {
  813. vdLA_Print(0,dummy,0,0);
  814. }
  815. // - taha 06-09-2018 show modified mac key on rock -
  816.  
  817. memcpy ( tmpaqbuffer, pMacKey, uwKeyLen );
  818. if (uwKeyLen == S_AQWORKKEY)
  819. { // duplicate the first part key to second part key
  820. memcpy(&tmpaqbuffer[S_AQWORKKEY], pMacKey, S_AQWORKKEY );
  821. }
  822. // testing
  823. // calculate MAC using DES/3DES in CBC mode
  824. PinRetval = 1;
  825. memset( MacBlock, 0, 8 );
  826. memset( aTmp, 0x00, sizeof(aTmp));
  827. data_remaining = uwDataLength;
  828. CS_Open(False);
  829. do
  830. {
  831. // for data block not multiply of 8, trailing fill with binary zero
  832. memset( WorkData, 0, 8 );
  833. if ( data_remaining > 8 )
  834. memcpy ( WorkData, pData, 8 );
  835. else
  836. memcpy ( WorkData, pData, data_remaining );
  837. for (ubTmp =0; ubTmp < 8; ubTmp++)
  838. WorkData[ubTmp] ^= MacBlock[ubTmp];
  839. // Loop here pulling 8 bytes at a time from callers page.
  840.  
  841. PinRetval &= CS_CreateMAC ( mkid, tmpaqbuffer, MacBlock, WorkData, 8, 1 );
  842. if (data_remaining > 8)
  843. {
  844. data_remaining -= 8;
  845. pData += 8;
  846. } else
  847. {
  848. data_remaining = 0;
  849. }
  850. } while ( 0 != data_remaining );
  851.  
  852. memset(dummy,0,sizeof(dummy));
  853. sprintf(dummy, "%02x %02x %02x %02x %02x %02x %02x %02x ",
  854. MacBlock[0], MacBlock[1], MacBlock[2], MacBlock[3],
  855. MacBlock[4], MacBlock[5], MacBlock[6], MacBlock[7] );
  856. vdLA_Print(0,dummy,0,0);
  857.  
  858.  
  859. if ( PinRetval == 1 )
  860. { // MAC generation OK
  861. vdLA_Print(0,"MAC generation OK",0,0);
  862. memcpy ( pMac, MacBlock, 8 );
  863. return 0;
  864. }
  865. // MAC generation failure
  866. return 2;
  867. }
  868.  
  869. //-----------------------------------------------------------------------------
  870. // PreparePinCalc Clear PINBUF, OUTPIN and initialize pointer into OUTPIN
  871. //
  872. // Parameters: None
  873. // Global Inputs:
  874. // Returns: None
  875. // Notes:
  876. //
  877. //-----------------------------------------------------------------------------
  878. static void PreparePinCalc( void )
  879. {
  880. // Clear PINBUF, OUTPIN and initialize pointer into OUTPIN.
  881. memset( ( UBYTE * ) PINBUF, 0, S_PINBUF );
  882. memset( ( UBYTE * ) OUTPIN, 0, sizeof( OUTPIN ) );
  883. }
  884.  
  885. //-----------------------------------------------------------------------------
  886. // GetCommand Get message separator
  887. //
  888. // Parameters: char* - Command string
  889. //
  890. // Global Inputs:
  891. //
  892. // Returns: Number of byte added in the PIN buffer for the command
  893. //
  894. // Notes: Set proper message separator in the buffer
  895. // '.' - for CAT33 protocol
  896. // '/' - for POSMINI protocol
  897. //-----------------------------------------------------------------------------
  898. static UBYTE GetCommand( UBYTE* cmd, UBYTE* pMsgBuf)
  899. {
  900. UBYTE ubLen;
  901.  
  902. ubLen = 0;
  903. memcpy( pMsgBuf+ubLen, cmd, 2 );
  904. ubLen += 2;
  905.  
  906. if ( PIN_CAT33 == *((UBYTE*)PIN_CONFIG) || ( OUTPIN[0] == 'A' ) )
  907. pMsgBuf[ubLen] = '.';
  908. else
  909. pMsgBuf[ubLen] = '/';
  910. ubLen++;
  911. return ubLen;
  912. }
  913.  
  914. #if 0
  915. static UBYTE GetFS( void )
  916. {
  917. return '\x1C';
  918. }
  919. #endif
  920.  
  921. //-----------------------------------------------------------------------------
  922. // GetEncKeyId Get Encryption working Key ID
  923. //
  924. // Parameters: None
  925. // Global Inputs:
  926. // Returns: UBYTE - key ID
  927. // Notes:
  928. //
  929. //-----------------------------------------------------------------------------
  930. static UBYTE GetEncKeyId( UBYTE ubAqId )
  931. {
  932. UBYTE AqMKID;
  933.  
  934. AqMKID = GetProfileByte(BD_AQ_PIN_MASTER_KID, ubAqId);
  935. // convert numeric 0-12 to ASCII '0' - 'B'
  936. if (AqMKID <= 9)
  937. {
  938. AqMKID = '0' + AqMKID;
  939. } else if (AqMKID <= 12)
  940. {
  941. AqMKID = 'A' + (AqMKID-10);
  942. }
  943. #ifdef MAKE_VIKING
  944. if ( ((AqMKID < '0') || (AqMKID > '9')) && (AqMKID != 'A') && (AqMKID != 'B') )
  945. {
  946. return ('0');
  947. }
  948. #else // MAKE_VIKING
  949. if ( ((AqMKID < '0') || (AqMKID > '9')) && ((AqMKID < 'A') || (AqMKID > 'C')) )
  950. {
  951. return ('0');
  952. }
  953. #endif // MAKE_VIKING
  954.  
  955. return (AqMKID);
  956. }
  957.  
  958. //-----------------------------------------------------------------------------
  959. // GetEncKeyId Get Encryption MAC Master Key ID
  960. //
  961. // Parameters: None
  962. // Global Inputs:
  963. // Returns: UBYTE - Acquirer ID
  964. // Notes:
  965. //
  966. //-----------------------------------------------------------------------------
  967. static UBYTE GetMACKeyId( UBYTE ubAqId )
  968. {
  969. UBYTE AqMKID;
  970.  
  971. AqMKID = GetProfileByte(BD_AQ_MAC_MASTER_KID, ubAqId);
  972. // convert numeric 0-12 to ASCII '0' - 'B'
  973. if (AqMKID <= 9)
  974. {
  975. AqMKID = '0' + AqMKID;
  976. } else if (AqMKID <= 12)
  977. {
  978. AqMKID = 'A' + (AqMKID-10);
  979. }
  980. #ifdef MAKE_VIKING
  981. if ( ((AqMKID < '0') || (AqMKID > '9')) && (AqMKID != 'A') && (AqMKID != 'B') )
  982. {
  983. return ('0');
  984. }
  985. #else // MAKE_VIKING
  986. if ( ((AqMKID < '0') || (AqMKID > '9')) && ((AqMKID < 'A') || (AqMKID > 'C')) )
  987. {
  988. return ('0');
  989. }
  990. #endif // MAKE_VIKING
  991.  
  992. return (AqMKID);
  993. }
  994.  
  995. //-----------------------------------------------------------------------------
  996. // GetEncKey Get Encryption working Key
  997. //
  998. // Parameters: UBYTE* - pointer to encrypted key
  999. // short - key length
  1000. // Bool - double length key flag
  1001. // Global Inputs:
  1002. // Returns: None
  1003. // Notes: Put the Key into output buffer
  1004. //
  1005. //-----------------------------------------------------------------------------
  1006. //static UBYTE GetEncKey( UBYTE* keyptr, UWORD len, Bool dblflag, UBYTE* pMsgBuf )
  1007. #if 0
  1008. static UBYTE GetEncKey(UBYTE ubAqId, int nProfileKeyId, UBYTE* pMsgBuf)
  1009. {
  1010. UBYTE ubLen, ubKeyLen;
  1011. Bool empty;
  1012. UBYTE tmpaqbuffer[S_AQWORKKEY*3];
  1013. UWORD uwSize;
  1014.  
  1015. memset(tmpaqbuffer, 0x00, sizeof(tmpaqbuffer));
  1016. // check the key length
  1017. ubKeyLen = GetProfileByte(BD_AQ_KEY_LENGTH, ubAqId);
  1018. if (ubKeyLen == 3)
  1019. { // single key length
  1020. ubKeyLen = S_AQWORKKEY*3;
  1021. } else if (ubKeyLen == 2)
  1022. { // single key length
  1023. ubKeyLen = S_AQWORKKEY*2;
  1024. } else
  1025. { // default to single key length
  1026. ubKeyLen = S_AQWORKKEY;
  1027. }
  1028.  
  1029. /* Copy key from aquirer table */
  1030. uwSize = ubKeyLen;
  1031. GetProfileData(nProfileKeyId, ubAqId, tmpaqbuffer, &uwSize);
  1032.  
  1033. // Init. empty flag
  1034. empty = True;
  1035.  
  1036. // Check conditions
  1037. if ( !NullComp( ( char * ) tmpaqbuffer, ubKeyLen ) )
  1038. {
  1039. empty = False;
  1040. }
  1041. ubLen = 0;
  1042. // If key is all zeros then send all spaces.
  1043. if ( empty )
  1044. {
  1045. if ( PIN_CAT33 == *((UBYTE*)PIN_CONFIG) )
  1046. {
  1047. memset( pMsgBuf+ubLen, ' ', ( ubKeyLen << 1 ) );
  1048. ubLen += ( ubKeyLen << 1 );
  1049. } else
  1050. {
  1051. memset( pMsgBuf+ubLen, 0, ubKeyLen );
  1052. ubLen += ubKeyLen;
  1053. }
  1054. } else
  1055. {
  1056. if ( PIN_CAT33 == *((UBYTE*)PIN_CONFIG) )
  1057. {
  1058. BfAscii( ( char * ) pMsgBuf+ubLen, tmpaqbuffer, ubKeyLen );
  1059. ubLen += ( ubKeyLen << 1 );
  1060. } else
  1061. {
  1062. memcpy( pMsgBuf+ubLen, tmpaqbuffer, ubKeyLen );
  1063. ubLen += ubKeyLen;
  1064. }
  1065. }
  1066. return ubLen;
  1067. }
  1068. #endif
  1069.  
  1070. //-----------------------------------------------------------------------------
  1071. // GetPINDevice Return device configuration mode
  1072. //
  1073. // Parameters: None
  1074. // Global Inputs:
  1075. // Returns: True - success, False - error
  1076. // Notes: Set PIN_DEVICE & PIN_CONFIG variables
  1077. //-----------------------------------------------------------------------------
  1078. static UBYTE GetPINDevice( void )
  1079. {
  1080. UBYTE aTmp[20];
  1081. IOCS_DDDA_DATA ddda;
  1082. OSRETURNCODES status;
  1083. UBYTE i, ubLen, ubSize;
  1084.  
  1085. /* Check for terminal restart or initialization */
  1086. if ( !PIN_DEVICE )
  1087. {
  1088. /* Prepare progress buffer */
  1089. memset(aTmp, 0x00, sizeof(aTmp));
  1090. ubLen = 0;
  1091. aTmp[ubLen++] = '<';
  1092. memset( aTmp+ubLen, ' ', sizeof(ProtList)/sizeof(CFGDATA) - 1 );
  1093. aTmp[sizeof(ProtList)/sizeof(CFGDATA)] = '>';
  1094. aTmp[sizeof(ProtList)/sizeof(CFGDATA) + 1] = 0;
  1095. MSG_SetUserMsg(2, aTmp, 0);
  1096.  
  1097. // Display PIN AUTO DETECTING message.
  1098. ShowInfoMsgNoWait(MSG_ID_PinPadAutoDetect, MSG_ID_SPECIAL_MSG2);
  1099.  
  1100. for ( i = 0; ProtList[i].device != 0; i++ )
  1101. { /* Set device */
  1102. PIN_DEVICE = ProtList[i].device;
  1103.  
  1104. /* Check communication */
  1105. if ( !(RS232_GetRSOPT( ) & RSOPT_RSACTIVE) || !(PIN_DEVICE == PRT) )
  1106. {
  1107. /* Close the device */
  1108. if ( OK == OS_DeviceClose( PIN_DEVICE )) PINFLG.deviceOpen = 0;
  1109.  
  1110. /* Try to open device */
  1111. status = OS_DeviceOpen( PIN_DEVICE );
  1112. if ( OK == status ) PINFLG.deviceOpen = 1; /* Device opened successfully */
  1113.  
  1114. /* Set config parameters pointer */
  1115. PIN_CONFIG = ProtList[i].cfgptr;
  1116.  
  1117. /* Configure device */
  1118. ddda.pubyte = PIN_CONFIG;
  1119. status = OS_DeviceConfig ( PIN_DEVICE, GetMode(), &ddda );
  1120.  
  1121. /* PINPAD just powered up */
  1122. if ( ProtList[i].power == PIN_CPWR_ON ) OS_Wait( ONESECOND*3 );
  1123.  
  1124. /* Check config status */
  1125. if ( OK == status )
  1126. { /* Clear output buffer */
  1127. memset( ( UBYTE * ) OUTPIN, 0, sizeof( OUTPIN ) );
  1128. ubLen = 0;;
  1129. ubSize = GetCommand( "90", OUTPIN+ubLen );
  1130. ubLen += ubSize;
  1131. // Write message to Pin Pad
  1132. if ( OK == Write_Pin( (UWORD)ubLen ) )
  1133. {
  1134. /* Read PINPAD answer */
  1135. if ( OK == Read_Pin( ONESECOND ) )
  1136. {
  1137. // Check for PIN BLOCK response code.
  1138. if ( !memcmp( PINBUF, ( UBYTE * ) "91", 2 ) )
  1139. {
  1140. // Set external PINPAD type
  1141. PIN_TYPE = PIN_TYPE_EXTERNAL;
  1142. // Set power mode
  1143. if ( PowerOnFlag != 0xAA )
  1144. {
  1145. OS_Wait( MS100*2 );
  1146. ddda.data = ProtList[i].power;
  1147. OS_DeviceConfig ( PIN_DEVICE, PIN_CONST_PWR, &ddda );
  1148. OS_Wait( MS100*2 );
  1149. PowerOnFlag = 0xAA ;
  1150. }
  1151. /* Close the device */
  1152. if ( OK == OS_DeviceClose( PIN_DEVICE )) PINFLG.deviceOpen = 0;
  1153.  
  1154. /* Change detect progress */
  1155. memset( &aTmp[1], '-', sizeof(ProtList)/sizeof(CFGDATA) - 1 );
  1156. aTmp[i + 1] = '*';
  1157. MSG_SetUserMsg(2, aTmp, 0);
  1158. //ShowInfoMsg( CustomMsg2, N_Pinpad );
  1159. ShowInfoMsgNoWait(MSG_ID_Pinpad, MSG_ID_SPECIAL_MSG2);
  1160. OS_Wait( ONESECOND*2 );
  1161.  
  1162. // Receive correct response code, exit
  1163. return True;
  1164. }
  1165. }
  1166. }
  1167. }
  1168.  
  1169. /* Close the device */
  1170. if ( OK == OS_DeviceClose( PIN_DEVICE )) PINFLG.deviceOpen = 0;
  1171. }
  1172.  
  1173. // Clear PIN device
  1174. PIN_DEVICE = 0;
  1175.  
  1176. /* Change detect progress */
  1177. aTmp[i + 1] = '-';
  1178. MSG_SetUserMsg(2, aTmp, 0);
  1179. ShowInfoMsgNoWait(MSG_ID_PinPadAutoDetect, MSG_ID_SPECIAL_MSG2);
  1180. }
  1181.  
  1182. #ifdef MAKE_VIKING
  1183. // Open CryptoService
  1184. CS_Open( False );
  1185. #else // MAKE_VIKING
  1186. /* Try to find internal PINPAD */
  1187. // Read the revision number from the Z8 and display it.
  1188. // Clear PINBUF, OUTPIN and initialize pointer to OUTPIN.
  1189. // Build message that goes direct to the Z8 in PINOUT.
  1190. // Receive the message directly from the Z8 into PINBUF.
  1191. memset( ( UBYTE * ) OUTPIN, 0, sizeof( OUTPIN ) );
  1192.  
  1193. // The command string to the Z8 to request the version
  1194. // number is command value of 0x00. Already set by clear.
  1195.  
  1196. // Use exact length of command that Z8 expects. It is not
  1197. // necessary to fill in unused fields, leave them nulls.
  1198. OutLen = Z8LEN_ReturnVersionNumber;
  1199. #endif // MAKE_VIKING
  1200.  
  1201. #ifdef MAKE_VIKING
  1202. // Test the internal PIN PAD
  1203. if ( CS_StatusSSM() )
  1204. #else // MAKE_VIKING
  1205. // Send the command to the Z8 and verify the Z8 responds.
  1206. if ( FunctionZ8() )
  1207. #endif // MAKE_VIKING
  1208. {
  1209. /* Set PIN device */
  1210. PIN_DEVICE = PIN;
  1211.  
  1212. // Internal pinpad exists.
  1213. PIN_TYPE = PIN_TYPE_ICE5000;
  1214. }
  1215. else
  1216. {
  1217. // Force pin type to invalid.
  1218. PIN_TYPE = PIN_TYPE_INVALID;
  1219.  
  1220. // No external and no internal Z8 detected.
  1221. ShowErrMsg( MSG_ID_PinpadNotFound );
  1222.  
  1223. /* Exit */
  1224. return False;
  1225. }
  1226. }
  1227. return True;
  1228. }
  1229.  
  1230.  
  1231. /*------------------------------------------------------------------
  1232. * Name: StartRspTimer
  1233. * Description: Starts a timer to detect a response timeout. Flags bit 0
  1234. * of 'flag' upon expiration.
  1235. *
  1236. * Parameters: PTCS_BLK , flag, timeout
  1237. *
  1238. * Return Value: none.
  1239. *
  1240. *-----------------------------------------------------------------*/
  1241. static void StartRspTimer( PTCS_BLK *blk, UBYTE *flag, unsigned short timeout )
  1242. {
  1243.  
  1244. blk->ptcs_cmnd = TIMER; // Request a PTCS timer service
  1245. blk->ptcs_scmd = PROCEED + FLAG; // Select Proceed+Flag option
  1246. blk->ptcs_time = timeout; // Set timer timeout value
  1247. #ifdef MAKE_VHDT
  1248. blk->ptcs_ifad.pubyte = flag; // Pointer to the flag to be used
  1249. #else
  1250. blk->ptcs_ifad = flag; // Pointer to the flag to be used
  1251. #endif
  1252. blk->ptcs_fbit = 0; // Flag to bit 0
  1253.  
  1254. OS_Function ( RQPTCS, blk ); // Call the OS service handler
  1255.  
  1256. } // end of StartRspTimer
  1257.  
  1258.  
  1259. //-----------------------------------------------------------------------------
  1260. // GetMode Return device configuration mode
  1261. //
  1262. // Parameters: None
  1263. // Global Inputs:
  1264. // Returns: UBYTE: PIN_CFG_PROT for PIN device
  1265. // PRT_CFG_PROT for PRT device
  1266. // Notes:
  1267. //-----------------------------------------------------------------------------
  1268. static UBYTE GetMode( void )
  1269. {
  1270. /* Set device mode */
  1271. if ( PIN == PIN_DEVICE )
  1272. return PIN_CFG_PROT;
  1273. else
  1274. return PRT_CFG_PROT;
  1275. }
  1276.  
  1277. //-----------------------------------------------------------------------------
  1278. // Open_Config Opens and configures the Pin Pad port.
  1279. //
  1280. // Parameters: None
  1281. // Global Inputs:
  1282. // Returns: Bool True if successful, False if error
  1283. // Notes:
  1284. //-----------------------------------------------------------------------------
  1285. extern Bool Open_Config( void )
  1286. {
  1287. IOCS_DDDA_DATA ddda;
  1288. OSRETURNCODES status;
  1289.  
  1290. /* Already open, return */
  1291. if ( PINFLG.deviceOpen ) return( OK );
  1292.  
  1293. /* Check PIN device type */
  1294. if ( PIN_TYPE == PIN_TYPE_ICE5000 ) return ( OK );
  1295.  
  1296. /* Check PIN device setting */
  1297. if ( !GetPINDevice() ) return ( !OK );
  1298.  
  1299. /* Check PIN device type again */
  1300. if ( PIN_TYPE == PIN_TYPE_ICE5000 ) return ( OK );
  1301.  
  1302. /* Try to open the PIN device */
  1303. status = OS_DeviceOpen( PIN_DEVICE );
  1304. if (status == ERRBSY) // BUSY
  1305. {
  1306. Rewind_Pin( ); // close, rewind and reopen
  1307. status = OS_DeviceOpen( PIN_DEVICE );
  1308. }
  1309.  
  1310. /* Configure PINPAD device */
  1311. if ( OK == status )
  1312. {
  1313. ddda.pubyte = PIN_CONFIG;
  1314. status = OS_DeviceConfig ( PIN_DEVICE, GetMode(), &ddda );
  1315. }
  1316.  
  1317. if ( OK == status )
  1318. PINFLG.deviceOpen = 1; /* Device opened successfully */
  1319. else
  1320. Rewind_Pin( ); /* Error opening & configuring device */
  1321.  
  1322. return ( status );
  1323. }
  1324.  
  1325. //-----------------------------------------------------------------------------
  1326. // Write_Pin Writes contents of OUTPIN to Pin Pad.
  1327. //
  1328. // Parameters: UWORD Length of data that must be in OUTPIN
  1329. // Global Inputs:
  1330. // Returns: Bool True if successful, False if error
  1331. // Notes:
  1332. //-----------------------------------------------------------------------------
  1333. extern Bool Write_Pin( UWORD length )
  1334. {
  1335. Bool Retval = !OK ;
  1336.  
  1337. if ( PIN_TYPE_ICE5000 == PIN_TYPE )
  1338. { /* Internal pinpad */
  1339. Retval = OK;
  1340. } else
  1341. {
  1342. if ( OK == OS_DeviceWrite( PIN_DEVICE, OUTPIN, length ) )
  1343. {
  1344. Retval = OK ;
  1345. } else
  1346. {
  1347. Rewind_Pin( );
  1348. }
  1349. }
  1350. return(Retval);
  1351. }
  1352.  
  1353. //-----------------------------------------------------------------------------
  1354. // Close_Pin Closes Pin Pad.
  1355. //
  1356. // Parameters: None
  1357. //
  1358. // Global Inputs:
  1359. //
  1360. // Returns: Bool True if successful, False if error
  1361. //
  1362. // Notes:
  1363. //
  1364. //-----------------------------------------------------------------------------
  1365.  
  1366. extern Bool Close_Pin( void )
  1367. {
  1368. Bool retval;
  1369.  
  1370. if (!PINFLG.deviceOpen)
  1371. { /* Device already closed */
  1372. return( OK );
  1373. }
  1374. retval = !OK ;
  1375. if ( PIN_TYPE_EXTERNAL == PIN_TYPE )
  1376. {
  1377. if ( OK == OS_DeviceClose( PIN_DEVICE ) )
  1378. {
  1379. PINFLG.deviceOpen = 0;
  1380. retval = OK;
  1381. }
  1382. } else
  1383. {
  1384. // Internal T5000 pinpad.
  1385. retval = OK ;
  1386. }
  1387. return ( retval );
  1388. }
  1389.  
  1390. //-----------------------------------------------------------------------------
  1391. // Read_Pin Reads message from Pin Pad.
  1392. //
  1393. // Parameters: OS_TIMES timout Time out value
  1394. // Global Inputs:
  1395. // Returns: Bool True if successful, False if error
  1396. // Notes: Data is returned in global buffer OUTPIN
  1397. //-----------------------------------------------------------------------------
  1398. extern Bool Read_Pin( OS_TIMES timeout )
  1399. {
  1400. Bool Retval;
  1401. UBYTE readflag;
  1402. UWORD pinlen;
  1403. UBYTE ubKey;
  1404.  
  1405. Retval = !OK ;
  1406. pinlen = 0;
  1407.  
  1408. if ( PIN_TYPE_ICE5000 == PIN_TYPE )
  1409. { // Internal T5000 pinpad
  1410. } else
  1411. { /* Post a read to the pin device */
  1412. if ( OK != DeviceRead (PIN_DEVICE, &PINBLKR, PROCEED+FLAG, PINBUF, sizeof(PINBUF), &readflag, 7 ) )
  1413. {
  1414. } else
  1415. { /* Start response timer */
  1416. StartRspTimer( &TIM_01, &readflag, timeout );
  1417.  
  1418. /* Wait for timeout (bit 0) or read complete (bit 7) */
  1419. while( ! ( readflag & 0x01 ) )
  1420. {
  1421. ubKey = GetOneKey(STAY_OPEN1|DEV_KBD|STAY_OPEN0, 0);
  1422. if (ubKey == CANCEL_KY || ubKey == CLEAR_KY)
  1423. break; // user cancelled
  1424. if ( ( readflag & 0x80 ) && ( OK == PINBLKR.iocs_stati ) )
  1425. {
  1426. pinlen = PINBLKR.iocs_var.iocs_xfer.iocs_tlenx;
  1427. Retval = OK ;
  1428. break;
  1429. }
  1430. // Give up some cycles while waiting...
  1431. SDK_RelinqCPU( );
  1432. } // while()
  1433.  
  1434. // Force a close of still open pad and kbd devices.
  1435. GetOneKey(STAY_OPEN1|DEV_KBD, 0);
  1436.  
  1437. /* Cancel response timeout timer */
  1438. OS_CancelTimer ( &TIM_01 );
  1439. }
  1440.  
  1441. if ( OK != Retval )
  1442. {
  1443. Rewind_Pin();
  1444. }
  1445. }
  1446. return ( Retval );
  1447. }
  1448.  
  1449. //-----------------------------------------------------------------------------
  1450. // FormatPin Formats the pin and pan for use in pin encryption.
  1451. //
  1452. // Parameters: ubPinLen - Length of PIN entered
  1453. // pPlainPin - PIN (ASCII, numeric digit only)
  1454. // pPAN_N2 - PAN (packed BCD format)
  1455. // pWorkData - PIN-BLOCK data buffer (8 bytes required)
  1456. //
  1457. // Global Inputs:
  1458. // Returns: None
  1459. // Notes: Result of pin/pan format is stored in WorkData.
  1460. //-----------------------------------------------------------------------------
  1461. extern void FormatPin( UBYTE ubPinLen, UBYTE* pPlainPin, UBYTE* pPAN_N2, UBYTE* pWorkData )
  1462. {
  1463. UBYTE aTmp[40];
  1464. UBYTE WorkData[8];
  1465. UBYTE FormatPanBuf[10];
  1466. UBYTE i, j, ubPINDigit;
  1467. UBYTE *pASCII_PAN;
  1468.  
  1469. // Start by filling the pin work buffer with hex FF's.
  1470. memset( WorkData, 0xFF, sizeof( WorkData ) );
  1471.  
  1472. // Move the length of the pin to start of pin work buffer.
  1473. WorkData[0] = ubPinLen;
  1474.  
  1475. // Convert pin digits to hex and store in pin work buffer. The
  1476. // result should be one byte length, pin in hex padded with F's.
  1477. // For example, pin length of 5 and pin of "12345" results in
  1478. // 05 12 34 5F FF FF FF FF
  1479. for ( i = 0, j = 1; i < ubPinLen; i++, j++ )
  1480. {
  1481. // the lower nibble is the numeric pin digit
  1482. ubPINDigit = pPlainPin[i] & 0x0f;
  1483. WorkData[j] = ubPINDigit<<4 | 0x0F; // padd unused nibble with F
  1484.  
  1485. // Quit here if an odd number of bytes in PIN.
  1486. if ( i == ubPinLen - 1 )
  1487. break;
  1488.  
  1489. // Move to next ASCII input byte.
  1490. i++;
  1491.  
  1492. // Move second nibble to format buffer.
  1493. WorkData[j] &= 0xf0;
  1494. WorkData[j] |= ( pPlainPin[i] & 0x0f );
  1495. }
  1496.  
  1497. // Shift the PAN 5 nibbles to the right.
  1498. // Original PAN of '44 27 80 26 41 00 47 97 FF FF' should be
  1499. // '00 00 00 00 78 02 64 10 04 79' after shifts.
  1500.  
  1501. // Clear the working buffer for formatting the PAN.
  1502. memset( FormatPanBuf, 0, sizeof( FormatPanBuf ) );
  1503.  
  1504. // Convert the PAN (N2) to an ASCII string.
  1505. memset(aTmp, 0x00, sizeof(aTmp));
  1506. BfAscii( ( char * ) aTmp, pPAN_N2, sizeof( FormatPanBuf ) );
  1507.  
  1508. // Set pASCII_PAN to the end of the PAN data (look for 'F').
  1509. pASCII_PAN = aTmp;
  1510. while ( *pASCII_PAN != 'F' )
  1511. pASCII_PAN++;
  1512.  
  1513. // Now back up two - skip the 'F' we just found, and the check digit.
  1514. pASCII_PAN -= 2;
  1515.  
  1516. // Now walk backwards through the ASCII PAN data, storing 12 nibbles.
  1517. // Stop when we've got 12 nibbles or when we're out of PAN data.
  1518.  
  1519. i = 7;
  1520. while ( ( i > 1 ) && ( pASCII_PAN >= ( UBYTE * ) aTmp) )
  1521. {
  1522. FormatPanBuf[i] = A2hex( *pASCII_PAN ); // Low nibble.
  1523. pASCII_PAN--;
  1524.  
  1525. if ( pASCII_PAN >= ( UBYTE * ) aTmp )
  1526. {
  1527. FormatPanBuf[i] |= ( A2hex( *pASCII_PAN ) << 4 ); // High nibble.
  1528. pASCII_PAN--;
  1529. }
  1530.  
  1531. i--;
  1532. }
  1533.  
  1534. // XOR FormatPanBuf with WorkData.
  1535. for ( i = 0; i < sizeof( WorkData ); i++ )
  1536. {
  1537. WorkData[i] = WorkData[i] ^ FormatPanBuf[i];
  1538. }
  1539. // return PIN-BLOCK Data to caller
  1540. memcpy(pWorkData, WorkData, sizeof(WorkData));
  1541. }
  1542.  
  1543. #ifdef __CS_TEST__
  1544. static void SecurityTest( void )
  1545. {
  1546. unsigned char IK0[] = {0xB0,0x15,0x0A,0xF5,0xBB,0x82,0x96,0x63};
  1547. unsigned char IK1[] = {0x0E,0xAB,0x43,0xC3,0xF7,0xE4,0x78,0xB8,0x7E,0x57,0x3B,0x96,0x3E,0x6D,0xAA,0x59};
  1548. unsigned char IK2[] = {0xCC,0xA7,0xF1,0xDF,0xB9,0xBB,0x62,0x83};
  1549. unsigned char IKSN0[] = {0xFF,0xFF,0x00,0x00,0x01,0x11,0x11,0x00,0x00,0x00};
  1550. unsigned char IKSN1[] = {0xFF,0xFF,0x00,0x00,0x02,0x22,0x22,0x00,0x00,0x00};
  1551. unsigned char IKSN2[] = {0xFF,0xFF,0x00,0x00,0x03,0x33,0x33,0x00,0x00,0x00};
  1552. #if 0
  1553. unsigned char MK0[] = {0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31};
  1554. #endif
  1555. unsigned char MK0[] = {0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31};
  1556. unsigned char MK1[] = {0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32};
  1557. unsigned char eMK1[] = {0x99,0x0F,0xEE,0x15,0x96,0x7F,0xE8,0x04,0x1A,0x79,0x3D,0xBC,0x13,0xE3,0x30,0x3D};
  1558. unsigned char WK[] = {0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34};
  1559. #if 0
  1560. unsigned char eWK0[] = {0xC5,0x48,0xB2,0xB8,0xCA,0xF9,0xB4,0x01,0xF1,0xC1,0x18,0x68,0xFE,0x25,0xCD,0xE0};
  1561. // C548B2B8CAF9B401-F1C11868FE25CDE0
  1562. #endif
  1563. // kf, TESTING KEY OF 3131313131313131-3131313131313131 ENCRYPTED UNDER tmk 3131313131313131-3131313131313131
  1564. unsigned char eWK0[] = {0x65,0x5E,0xA6,0x28,0xCF,0x62,0x58,0x5F,0x65,0x5E,0xA6,0x28,0xCF,0x62,0x58,0x5F};
  1565. unsigned char eWK1[] = {0x8C,0xAB,0xEF,0xF1,0x1F,0x97,0xDC,0xA2,0x8E,0xDF,0x89,0x62,0xBC,0xA9,0x10,0x4C};
  1566.  
  1567. unsigned char DT[] =
  1568. {
  1569. 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11
  1570. };
  1571.  
  1572. unsigned char MAC[] =
  1573. {
  1574. 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
  1575. 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD
  1576. };
  1577.  
  1578. unsigned char work[16 + 16];
  1579. unsigned char data[8 + 10];
  1580.  
  1581. int status;
  1582. unsigned long result;
  1583. char SN[16 + 1];
  1584.  
  1585. // Open CryptoService
  1586. CS_Open( True );
  1587.  
  1588. // Get the Serial Number
  1589. memset( SN, 0, sizeof(SN) );
  1590. status = CS_GetSN( SN, sizeof(SN) );
  1591.  
  1592. // Open CryptoService
  1593. CS_Open( False );
  1594.  
  1595. // Get SSM status
  1596. if ( CS_StatusSSM() )
  1597. {
  1598. // Prepare MK with PIN TAG
  1599. memcpy( work, MK0, sizeof(MK0) );
  1600. work[16] = 1;
  1601.  
  1602. // Store plain MK0
  1603. result = CS_StoreMK( 1, work );
  1604.  
  1605. // Prepare MK with MAC TAG
  1606. memcpy( work, MK0, sizeof(MK0) );
  1607. work[16] = 8;
  1608.  
  1609. // Store plain MK0
  1610. result = CS_StoreMK( 2, work );
  1611.  
  1612. // Calculate PIN
  1613. result = CS_EncryptPIN(1, eWK0, data, DT);
  1614. #if 0
  1615. // KF, v01A, KF 042706, standard test using key 31...31
  1616. {
  1617. UBYTE aTestPIN[8];
  1618. UBYTE aData2[8], aData3[8];
  1619.  
  1620. memset(aTestPIN, 0x00, sizeof(aTestPIN));
  1621. asc2bcd(aTestPIN, "06127765cddddeee", 16);
  1622. memset(aData2, 0x00, sizeof(aData2));
  1623. memset(aData3, 0x00, sizeof(aData3));
  1624. result = CS_EncryptPIN(1, eWK0, aData2, aTestPIN);
  1625. result = CS_CreateMAC ( 2, eWK0, aData3, aTestPIN, 8, 1 );
  1626.  
  1627. asc2bcd(aTestPIN, "596656744C9371C0", 16);
  1628. memset(aData2, 0x00, sizeof(aData2));
  1629. memset(aData3, 0x00, sizeof(aData3));
  1630. result = CS_EncryptPIN(1, eWK0, aData2, aTestPIN);
  1631. result = CS_CreateMAC ( 2, eWK0, aData3, aTestPIN, 8, 1 );
  1632. result = CS_CreateMAC ( 2, eWK0, aData2, aTestPIN, 8, 0 );
  1633. }
  1634. #endif
  1635. // Calculate MAC
  1636. result = CS_CreateMAC(2, eWK0, data, MAC, sizeof(MAC), 0);
  1637. result = CS_CreateMAC(2, eWK0, data, MAC, sizeof(MAC), 1);
  1638.  
  1639. // Generate Key
  1640. result = CS_GenerateKey(1, work);
  1641.  
  1642. // Decrypt PIN
  1643. result = CS_DecryptPIN(1, work, data, DT);
  1644. return;
  1645. //==================================================================
  1646. //
  1647. // // Prepare MK with PIN TAG
  1648. memcpy( work, eMK1, sizeof(eMK1) );
  1649. work[16] = 1;
  1650.  
  1651. // Store encrypted MK
  1652. result = CS_StoreEncryptedMK( 1, work );
  1653.  
  1654. // Prepare MK with MAC TAG
  1655. memcpy( work, eMK1, sizeof(eMK1) );
  1656. work[16] = 8;
  1657.  
  1658. // Store encrypted MK
  1659. result = CS_StoreEncryptedMK( 2, work );
  1660.  
  1661. // Calculate PIN
  1662. result = CS_EncryptPIN(1, eWK1, data, DT);
  1663.  
  1664. // Calculate MAC
  1665. result = CS_CreateMAC(2, eWK1, data, MAC, sizeof(MAC), 0);
  1666. result = CS_CreateMAC(2, eWK1, data, MAC, sizeof(MAC), 1);
  1667.  
  1668. // Generate Key
  1669. result = CS_GenerateKey(1, work);
  1670.  
  1671. // Decrypt PIN
  1672. result = CS_DecryptPIN(1, work, data, DT);
  1673. }
  1674.  
  1675. if ( CS_StatusSSM() )
  1676. {
  1677. // Load DUKPT keys
  1678. result = CS_InitDUKPT(0, IK0, IKSN0, 1); // Single
  1679. result = CS_InitDUKPT(1, IK1, IKSN1, 0); // Double
  1680. result = CS_InitDUKPT(2, IK2, IKSN2, 1); // Single
  1681.  
  1682. // Generate Keys
  1683. result = CS_GenerateKey_DUKPT(0);
  1684. result = CS_GenerateKey_DUKPT(1);
  1685. result = CS_GenerateKey_DUKPT(2);
  1686.  
  1687. // PIN Calculation
  1688. result = CS_EncryptPIN_DUKPT(0, data, DT);
  1689. result = CS_EncryptPIN_DUKPT(1, data, DT);
  1690. result = CS_EncryptPIN_DUKPT(2, data, DT);
  1691.  
  1692. // MAC Calculation
  1693. result = CS_CreateMAC_DUKPT(0, data, MAC, sizeof(MAC), 0);
  1694. result = CS_CreateMAC_DUKPT(1, data, MAC, sizeof(MAC), 0);
  1695. result = CS_CreateMAC_DUKPT(2, data, MAC, sizeof(MAC), 0);
  1696.  
  1697. // Generate Keys
  1698. result = CS_GenerateKey_DUKPT(0);
  1699. result = CS_GenerateKey_DUKPT(1);
  1700. result = CS_GenerateKey_DUKPT(2);
  1701.  
  1702. // PIN Calculation
  1703. result = CS_EncryptPIN_DUKPT(0, data, DT);
  1704. result = CS_EncryptPIN_DUKPT(1, data, DT);
  1705. result = CS_EncryptPIN_DUKPT(2, data, DT);
  1706.  
  1707. // MAC Calculation
  1708. result = CS_CreateMAC_DUKPT(0, data, MAC, sizeof(MAC), 1);
  1709. result = CS_CreateMAC_DUKPT(1, data, MAC, sizeof(MAC), 1);
  1710. result = CS_CreateMAC_DUKPT(2, data, MAC, sizeof(MAC), 1);
  1711.  
  1712. // Check for error
  1713. result = CS_EncryptPIN_DUKPT(0, data, DT);
  1714. result = CS_CreateMAC_DUKPT(1, data, MAC, sizeof(MAC), 1);
  1715. }
  1716.  
  1717. //==================================================================
  1718. // Open CryptoService
  1719. CS_Open( False );
  1720.  
  1721. // Get SSM status
  1722. if ( CS_StatusSSM() )
  1723. {
  1724. // Test MK
  1725. result = CS_TestMK(1, eWK1, data);
  1726. result = CS_TestMK(2, eWK1, data);
  1727. }
  1728. }
  1729. #endif
Add Comment
Please, Sign In to add comment