Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //=============================================================================
- // Hypercom Inc
- // (c) Copyright 2006
- //=============================================================================
- //
- // Module overview: PinPad.c
- // Pinpad functions
- // Info on Internal PIN-Pad of T2100:
- // Maskter Key is currently double-length
- // Triple-length key encryption/decryption is not supported
- //=============================================================================
- //=============================================================================
- #include "basictyp.h"
- #include "sdk.h"
- #include "sdkos.h"
- #include "sdkio.h"
- #include "sdkmem.h"
- #include "sdktime.h"
- #include "osclib.h"
- #include "utllib.h"
- #include "app_profile.h"
- #include "fixdata.h"
- #include "app_msgid.h"
- #include "pindev.inc"
- #include "siodev.inc"
- #include "prtdev.inc"
- #include "rs232cfg.h"
- #include "tranutil.h"
- #include "GUI_Base.h"
- #include "pinattck.h"
- #include "pinpad.h"
- #include "cvtamt.h"
- #include "sha1.h"
- //#include "CryptoService.h"
- #ifdef MAKE_VIKING
- //#define __CS_TEST__
- #ifdef __CS_TEST__
- static void SecurityTest( void );
- #endif
- typedef unsigned char* LPBYTE;
- typedef unsigned long DWORD;
- typedef unsigned int BOOL;
- extern void CS_Open(BOOL bVirginStart);
- extern DWORD CS_DecryptPIN(DWORD nKeyIndex, BYTE* pSPEK, BYTE* pPlainTextPIN, BYTE* pEncryptedPIN);
- extern DWORD CS_EncryptPIN(DWORD nKeyIndex, BYTE* pSPEK, BYTE* pCipher, BYTE* pPIN);
- extern DWORD CS_EncryptPIN_DUKPT(DWORD nKeyIndex, BYTE* pCipher, BYTE* pPIN_Block);
- extern DWORD CS_GenerateKey(DWORD nKeyIndex, BYTE* pKey);
- extern DWORD CS_GenerateKey_DUKPT(DWORD nKeyIndex);
- extern DWORD CS_CreateMAC(DWORD nKeyIndex, BYTE* pSMK, BYTE* pMAC, BYTE* pData, DWORD nLen, DWORD nType);
- extern DWORD CS_CreateMAC_DUKPT(DWORD nKeyIndex, BYTE* pMAC, BYTE* pData, DWORD nLen, DWORD nType);
- extern BOOL CS_StatusSSM(void);
- extern DWORD CS_GetSN(BYTE* pSn, DWORD nMaxLen);
- extern DWORD CS_StoreMK(DWORD nKeyIndex, BYTE* pKey);
- extern void C_DesTripleEncryptECB(LPBYTE pKey, LPBYTE pData, DWORD nDataLen, LPBYTE pResult);
- void C_DesTripleEncryptCBC(const BYTE* pKey, const BYTE* pIV, const BYTE* pData, DWORD nLen, BYTE* pResult);
- #endif // MAKE_VIKING
- //=============================================================================
- // External variables / declarations
- //=============================================================================
- //=============================================================================
- // Private defines and typedefs
- //=============================================================================
- #define S_AQWORKKEY 8 // PIN working key
- //====================================================
- //=== PINSTAT bit values ===
- //====================================================
- #define PinCard_Read 0x01 // Card read from pin.
- #define PinCardReadReqPend 0x02 // Card Read Request Pending Bit
- #define PinWaitUserAction 0x04 // Waiting for User Action
- #define PinWaitResetResp 0x08 // Wait for Reset Response
- #define PinCardReadError 0x10 // Card Read Error
- #define PinSmartCard_Read 0x40 /* Smart Card read from pinpad */
- #define PinCancelCardSwipe 0x80 // Cancel Card Swipe
- //====================================================
- //=== PIN_TYPE values ===
- //====================================================
- #define PIN_TYPE_INVALID 0 // INVALID PIN PAD
- #define PIN_TYPE_EXTERNAL 1 // EXTERNAL PIN PAD
- #define PIN_TYPE_ICE5000 2 // INTEGRATED ICE5000
- //=============================================================================
- // Private function declarations
- //=============================================================================
- static void PreparePinCalc( void );
- static UBYTE GetCommand( UBYTE* cmd, UBYTE* pMsgBuf);
- static UBYTE GetPINDevice( void );;
- static UBYTE GetMode( void );
- static void StartRspTimer( PTCS_BLK *blk, UBYTE *flag, unsigned short timeout );
- //static UBYTE GetFS( void );
- //static UBYTE GetEncKey(UBYTE ubAqId, int nProfileKeyId, UBYTE* pMsgBuf);
- static UBYTE GetEncKeyId( UBYTE ubAqId );
- static UBYTE GetMACKeyId( UBYTE ubAqId );
- static UBYTE InternalPinpadGetPin( struct TRANDATA_REC* pTranData );
- static UBYTE InternalMacGenerate(UBYTE* pData, UWORD uwDataLength,
- UBYTE* pMacKey, UBYTE ubAqId, UBYTE* pMac);
- static UBYTE InternalPinBGenerate(UBYTE* pData, UBYTE* pPinKey, UBYTE ubAqId,
- UBYTE* pEPinBlock);
- //=============================================================================
- // Public data definitions
- //=============================================================================
- UBYTE PIN_DEVICE; /* PIN device type */
- void* PIN_CONFIG; /* Pointer to PIN device configuration parameters */
- UBYTE PIN_TYPE;
- // Pinpad status byte.
- UBYTE PINSTAT;
- UBYTE PowerOnFlag;
- #define S_PINBUF (270)
- static UBYTE PINBUF[S_PINBUF];
- static UBYTE OUTPIN[128];
- typedef struct
- {
- UBYTE device; // Device ID
- PIN_CPWR power; // Power mode
- void* cfgptr; // Pointer to configuration parameters
- } CFGDATA;
- static const PINPRC CFG_S8_2400 = { PIN_CAT33, PIN_TERMINAL, SIO_7EVEN1, SIO_B2400 };
- static const PINPRC CFG_S8_9600 = { PIN_CAT33, PIN_TERMINAL, SIO_7EVEN1, SIO_B9600 };
- static const PINPRC CFG_S8_19200 = { PIN_CAT33, PIN_TERMINAL, SIO_7EVEN1, SIO_B19200 };
- static const PINPRC CFG_HFT105_485_2400 = { PIN_POSMINI, PIN_TERMINAL, SIO_8NONE1, SIO_B2400 };
- static const PINPRC CFG_HFT105_485_9600 = { PIN_POSMINI, PIN_TERMINAL, SIO_8NONE1, SIO_B9600 };
- static const PINPRC CFG_HFT105_485_19200 = { PIN_POSMINI, PIN_TERMINAL, SIO_8NONE1, SIO_B19200 };
- static const prtprc CFG_HFT105_232_2400 = { PRTP_POSMINI, SIO_8NONE1, SIO_B2400 };
- static const prtprc CFG_HFT105_232_9600 = { PRTP_POSMINI, SIO_8NONE1, SIO_B9600 };
- static const prtprc CFG_HFT105_232_19200 = { PRTP_POSMINI, SIO_8NONE1, SIO_B19200 };
- static const CFGDATA ProtList[] =
- {
- #ifdef MAKE_VIKING
- { PIN, PIN_CPWR_OFF, (void*)&CFG_HFT105_485_19200 },
- // { PIN, PIN_CPWR_OFF, (void*)&CFG_HFT105_485_9600 },
- // { PIN, PIN_CPWR_OFF, (void*)&CFG_HFT105_485_2400 },
- // { PIN, PIN_CPWR_OFF, (void*)&CFG_S8_19200 },
- // { PIN, PIN_CPWR_OFF, (void*)&CFG_S8_9600 },
- { PIN, PIN_CPWR_OFF, (void*)&CFG_S8_2400 },
- #else // MAKE_VIKING
- { PIN, PIN_CPWR_ON, (void*)&CFG_HFT105_485_19200 },
- { PRT, PIN_CPWR_OFF, (void*)&CFG_HFT105_232_19200 },
- // { PRT, PIN_CPWR_OFF, (void*)&CFG_HFT105_232_9600 },
- // { PIN, PIN_CPWR_ON, (void*)&CFG_HFT105_485_9600 },
- { PIN, PIN_CPWR_ON, (void*)&CFG_HFT105_485_2400 },
- { PRT, PIN_CPWR_OFF, (void*)&CFG_HFT105_232_2400 },
- // { PIN, PIN_CPWR_OFF, (void*)&CFG_S8_19200 },
- { PIN, PIN_CPWR_OFF, (void*)&CFG_S8_9600 },
- { PIN, PIN_CPWR_OFF, (void*)&CFG_S8_2400 },
- #endif // MAKE_VIKING
- { 0, PIN_CPWR_OFF, NULL }
- };
- //=============================================================================
- // Private data definitions
- //=============================================================================
- //=============================================================================
- // Public function definitions
- //=============================================================================
- //-----------------------------------------------------------------------------
- // PinInit Initialize the pin pad.
- //
- // Parameters: None
- // Global Inputs:
- // Returns: None
- // Notes: Calls PinReset() which will set PinRetval
- // to True if OK, False otherwise
- //-----------------------------------------------------------------------------
- extern void PinInit( void )
- {
- Bool DetectFlag;
- int PinMsgNumber;
- /* Get PIN Pad Detect Flag */
- DetectFlag = ( 0xFF == TERM.TERMInit ) &&
- (GetProfileFlag(OPT_TR_PINDETECT, 0) || GetProfileFlag(OPT_TR_SMCARD_ENABLE, 0));
- // Force pin type to invalid.
- PIN_TYPE = PIN_TYPE_INVALID;
- // Clear all bits in PINSTAT
- PINSTAT = 0;
- // Reset PIN device
- PIN_DEVICE = 0;
- // Reset the Pin Pad.
- PinReset( );
- /* Check detect flag */
- if ( DetectFlag )
- {
- if (GetProfileFlag(OPT_TR_SMCARD_ENABLE, 0))
- { // Send a "Ready" message
- PinMsgNumber = MSG_ID_PPAD_PinReady;
- } else
- { // Clear PIN Pad display
- PinMsgNumber = MSG_ID_PPAD_ClrScrn;
- }
- // Send message to pinpad to display
- PinMessage( PinMsgNumber );
- if ( GetProfileFlag(OPT_TR_SMCARD_ENABLE, 0) &&
- (PIN_CAT33 != *((UBYTE*)PIN_CONFIG)) &&
- (PIN_TYPE == PIN_TYPE_EXTERNAL) )
- { // Set the flag Smart Card Read from Pinpad
- PINSTAT |= PinSmartCard_Read;
- }
- }
- Rewind_Pin( );
- #ifdef __CS_TEST__
- SecurityTest();
- #endif
- }
- //-----------------------------------------------------------------------------
- // PinPadTest PIN-Pad Test - for display test message on Pin-Pad
- //
- // Parameters: None
- //
- // Global Inputs:
- //
- // Returns: None
- //
- // Notes:
- //
- //-----------------------------------------------------------------------------
- extern void PinPadTest()
- {
- UBYTE retval;
- int nResultMsgId;
- // Reset PINPAD variables
- // Force pin type to invalid.
- PIN_TYPE = PIN_TYPE_INVALID;
- // Clear all bits in PINSTAT
- PINSTAT = 0;
- // Reset PIN device
- PIN_DEVICE = 0;
- // Select * PINPAD TEST * message to display on pinpad
- retval = PinMessage( MSG_ID_PPAD_PinTest );
- // Display results of test.
- if ( retval )
- {
- nResultMsgId = MSG_ID_PASSED;
- SDK_BeepIt( 2 );
- } else
- {
- nResultMsgId = MSG_ID_ERR_FAILED;
- SystemBeep(BEEP_ERROR);
- }
- // prompt user of Pin-Pad testing
- SCR_DisplayEntryById( MSG_ID_PINPAD_TEST, 0 , nResultMsgId, 0,
- 5, SCR_N_PROMPT_STYLE);
- }
- //-----------------------------------------------------------------------------
- // PinReset Reset the pin pad.
- //
- // Parameters: None
- // Global Inputs:
- // Returns: None
- // Notes: PinRetval set to True if OK, False otherwise
- //
- //-----------------------------------------------------------------------------
- extern void PinReset( void )
- {
- Rewind_Pin( );
- // Reset Bits of PINSTAT
- PINSTAT &= ~PinCardReadReqPend;
- PINSTAT &= ~PinWaitUserAction;
- }
- /*------------------------------------------------------------------
- * Name: Rewind_Pin
- * Description: Rewinds PIN device
- *
- * Parameters: None
- * Return Value: None
- * Notes:
- *-----------------------------------------------------------------*/
- extern void Rewind_Pin( void )
- {
- OS_DeviceRewind( PIN_DEVICE );
- OS_DeviceClose( PIN_DEVICE );
- /* Clear 'Device Open' flag */
- PINFLG.deviceOpen = 0;
- }
- //-----------------------------------------------------------------------------
- // PinMessage Build message and send it to the Pin Pad.
- //
- // Parameters: None
- // Global Inputs:
- // Returns: None
- // Notes: PinRetval set to True if OK, False otherwise
- // Message to display in PinMsgNumber.
- //-----------------------------------------------------------------------------
- extern UBYTE PinMessage( int PinMsgNumber )
- {
- UBYTE aTmp[20];
- UBYTE PinRetval;
- UBYTE length, ubLen, ubSize;
- int nSize;
- // May need to add a Get PIN Semaphore in the future
- PinRetval = False;
- // Open and configure Pin Pad Port
- if ( OK == Open_Config( ) )
- {
- if ( PIN_TYPE_EXTERNAL == PIN_TYPE )
- {
- // Load the Message Type - Display Text Request
- PreparePinCalc();
- ubLen = 0;
- ubSize = GetCommand( "3C", OUTPIN+ubLen);
- ubLen += ubSize;
- // Load text message into buffer after message type ( 16 Bytes)
- memset(aTmp, 0x00, sizeof(aTmp));
- nSize = 16;
- MSG_GetMsgString(PinMsgNumber, aTmp, &nSize );
- length = StrLn( aTmp, 16 );
- memcpy( OUTPIN+ubLen, aTmp, (UWORD) length );
- if ( 16 < length )
- { // Pad the field with space
- memset(OUTPIN+ubLen+length, ' ', ( UWORD ) ( 16 - length ) );
- }
- ubLen += 16;
- // Write message to Pin Pad
- if ( OK == Write_Pin( ubLen ) )
- {
- PinRetval = True;
- // Display for a short time
- if (PowerOnFlag != 0xAA)
- {
- OS_Wait( ONESECOND*2 );
- }
- }
- // Close Pin Pad Port
- if ( OK != Close_Pin( ) )
- {
- PinRetval = False;
- }
- } else
- { // Internal T5000 pinpad.
- // Spoof it for now just like SPOS.
- PinRetval = True;
- }
- }
- // May need to add a Release PIN Semaphore
- return PinRetval;
- }
- //-----------------------------------------------------------------------------
- // PinGetPin Get the PIN from the pin pad.
- //
- // Parameters: None
- // Global Inputs:
- // Returns: None
- // Notes: PinRetval set to True if OK, False otherwise
- // Notes: The S7 will retransmit both packets upon
- // CLEAR Key, S8 does not retransmit.
- //
- //-----------------------------------------------------------------------------
- extern UBYTE PinGetPin( struct TRANDATA_REC* pTranData )
- {
- UBYTE PinRetval;
- // May need to add a Get PIN Semaphore in the future
- PinRetval = False;
- // Open and configure Pin Pad Port
- if ( OK == Open_Config( ) )
- {
- if ( PIN_TYPE_EXTERNAL == PIN_TYPE )
- {
- ////////////////////////////////////////////////////////////////////////////////
- // @@dump v01A, KF 033006, EXTERNAL PIN-PAD IS NOT SUPPORTED
- ////////////////////////////////////////////////////////////////////////////////
- } else
- { // Internal T5000 pinpad.
- PinRetval = InternalPinpadGetPin(pTranData);
- }
- }
- // May need to add a Release PIN Semaphore
- return PinRetval;
- }
- //-----------------------------------------------------------------------------
- // PinGenMac For generating MAC code on input data
- //
- // Parameters: ubMacOpt Mac option
- // '1' - Hypercom ECB MAC
- // '2' - X9.9 MAC
- // '3' - SHA1-RMAC
- // pMacKey Mac key encrypted under corresponding Master Key for Mac Key
- // (packed Hex string)
- // pData Data for MAC generation
- // uwDataLength Length of Data for MAC generation
- // pMac Return storage for the generated MAC (binary format, 8 bytes)
- //
- // Global Inputs:
- //
- // Returns: 0 successful MAC generated
- // non-zero for MAC generation failed
- // 1 invalid input data
- // 2 processing error (external PIN-PAD not supported)
- //
- // Notes:
- //
- //-----------------------------------------------------------------------------
- extern UBYTE PinGenMac(UBYTE ubMacOpt, UBYTE* pMacKey, UBYTE ubAqId,
- UBYTE* pData, UWORD uwDataLength, UBYTE* pMac )
- {
- UWORD data_remaining, i;
- SHA1Context sha; /* SHA-1 context */
- UBYTE bCont;
- UBYTE WorkData[24];
- UBYTE MacBlock[8];
- unsigned char dummy[50];
- if (uwDataLength == 0 || pData == NULL)
- { // invalid data, inform caller
- return 1;
- }
- switch(ubMacOpt)
- {
- case '1': // ECB MAC
- case '2': // X9.9 MAC
- case '3': // SHA1-RMAC
- vdLA_Print(0,"ECB / X9.9 / SHA1",0,0);
- break;
- default:
- // invalid MAC option
- return 1;
- }
- bCont = 0;
- while(!bCont)
- {
- // some pre-processing for
- switch(ubMacOpt)
- {
- case '1': // ECB MAC
- // generate the 8 bytes data for ECB MAC generation
- vdLA_Print(0,"case 1 ECB MAC",0,0);
- memset( MacBlock, 0, 8 );
- memset( WorkData, 0, 8 );
- data_remaining = uwDataLength;
- do
- {
- memset( WorkData, 0, 8 );
- if ( data_remaining > 8 )
- memcpy ( WorkData, pData, 8 );
- else
- memcpy ( WorkData, pData, data_remaining );
- for (i =0; i<8; i++)
- MacBlock[i] = WorkData[i] ^ MacBlock[i];
- if (data_remaining > 8)
- {
- data_remaining -= 8;
- pData += 8;
- } else
- {
- data_remaining = 0;
- }
- } while ( 0 != data_remaining );
- memset(dummy,0,sizeof(dummy));
- sprintf(dummy, "%02x %02x %02x %02x %02x %02x %02x %02x ",
- MacBlock[0], MacBlock[1], MacBlock[2], MacBlock[3],
- MacBlock[4], MacBlock[5], MacBlock[6], MacBlock[7] );
- vdLA_Print(0,dummy,0,0);
- memcpy ( WorkData, MacBlock, 8 );
- uwDataLength = 8;
- pData = WorkData;
- break;
- case '3': // SHA1-RMAC
- /*
- * Reset the SHA-1 context and process input
- */
- vdLA_Print(0,"case 3 SHA1",0,0);
- SHA1Reset(&sha);
- SHA1Input(&sha, pData, uwDataLength);
- memset(WorkData, 0x00, sizeof(WorkData));
- if (!SHA1Result(&sha))
- { // SHA1 error
- } else
- { // SHA1 is a 20 bytes digest, append 4 bytes 0x80, 0x00, 0x00, 0x00
- // to generate 24 bytes data for SHA1-RMAC DES/DES3 processing
- memcpy(WorkData, &sha.Message_Digest[0], 4);
- memcpy(WorkData+4, &sha.Message_Digest[1], 4);
- memcpy(WorkData+8, &sha.Message_Digest[2], 4);
- memcpy(WorkData+16, &sha.Message_Digest[3], 4);
- }
- WorkData[16] = 0x80;
- WorkData[17] = 0x00;
- WorkData[18] = 0x00;
- WorkData[19] = 0x00;
- uwDataLength = 24;
- pData = WorkData;
- break;
- }
- // continue for DES/3DES processing here
- if ( OK == Open_Config( ) )
- {
- if ( PIN_TYPE_EXTERNAL == PIN_TYPE )
- { // use external PIN PAD processing here
- bCont = 2;
- // + taha 01-09-2018 show bCont variable on rock +
- memset(dummy,0,sizeof(dummy));
- sprintf(dummy,"1 - bCont: %d / %02x", bCont, bCont);
- vdLA_Print(0,dummy,0,0);
- // - taha 01-09-2018 show bCont variable on rock -
- break;
- } else
- { // Internal T5000 pinpad.
- vdLA_Print(0,"before InternalMacGenerate",0,0);
- bCont = InternalMacGenerate(pData, uwDataLength,
- pMacKey, ubAqId, pMac);
- // + taha 01-09-2018 show bCont variable on rock +
- memset(dummy,0,sizeof(dummy));
- sprintf(dummy,"e - bCont: %d / %02x", bCont, bCont);
- vdLA_Print(0,dummy,0,0);
- // - taha 01-09-2018 show bCont variable on rock -
- }
- }
- break;
- }
- return bCont;
- }
- //=============================================================================
- // Private function definitions
- //=============================================================================
- //-----------------------------------------------------------------------------
- // InternalPinpadGetPin For Using T2100 internal Pin-pad to enter Pin
- //
- // Parameters: pTranData Pointer to Transaction Data record
- //
- // Global Inputs:
- //
- // Returns: True successful enter Pin
- // False Pin entry failed or aborted
- //
- // Notes:
- // - Will update the following fields in the Transaction data record:
- // [TRPINBL] - with encrypted PIN block
- // [TRSTATUS[1]] - enabling bit TS2_PINBLOCK when PIN block entered
- //-----------------------------------------------------------------------------
- static UBYTE InternalPinpadGetPin( struct TRANDATA_REC* pTranData )
- {
- int nSize;
- UWORD uwSize;
- UBYTE WorkData[8];
- UBYTE pinblock[13];
- UBYTE aTmp[40];
- UBYTE aPinKey[24];
- UBYTE status;
- UBYTE PinRetval;
- PinRetval = False;
- // Display TOTAL and amount on line 1.
- memset(aTmp, 0x00, sizeof(aTmp));
- if ( pTranData->TRKEY != TRX_BALINQ )
- {
- CustomAmount(MSG_ID_AmountTotals, pTranData->TRTOTAM, aTmp,
- IsTRNOption(pTranData->nTRNOPT, TRNOPT_CREDIT));
- }
- MSG_SetUserMsg(1, aTmp, 21);
- memset( pinblock, 0, sizeof( pinblock ) );
- // Read pin from the keyboard, 4-12 digits
- nSize = 12;
- status = SCR_DataEntryById(MSG_ID_Pinpad, 0,
- MSG_ID_SPECIAL_MSG1, 0,
- pinblock, &nSize, 4, SCR_ENTRY_DATA_N|SCR_ENTRY_PASSWORD,
- SCR_STYLE_TITLE_CENTER);
- // Check if pin number has been entered
- if ( status )
- { // user aborted, inform caller
- return False;
- }
- uwSize = strlen( ( char * ) pinblock );
- // Combine pin length, pin and PAN and save at WorkData.
- FormatPin(uwSize, pinblock, pTranData->TRPAN, WorkData );
- memset(aPinKey, 0x00, sizeof(aPinKey));
- uwSize = sizeof(aPinKey);
- GetProfileData(BD_AQ_PIN_KEY, pTranData->TRAQID, aPinKey, &uwSize);
- memset(pinblock, 0x00, sizeof(pinblock));
- if (InternalPinBGenerate(WorkData, aPinKey, pTranData->TRAQID,
- pinblock) == 0)
- { // PIN-block OK
- status = 1;
- } else
- { // error
- status = 0;
- }
- if ( !status )
- {
- ShowErrMsg( MSG_ID_EncryptError );
- } else
- {
- memcpy( pTranData->TRPINBL, pinblock, LEN_PIN_BLK );
- /* Set PIN Block ready flag */
- pTranData->TRSTATUS[1] |= TS2_PINBLOCK;
- #ifdef MAKE_PINATTACKDELAY
- // Setup the pin attack delay
- PinAttackDelay( pTranData->TRPAN, pTranData->TRPINBL, 0 );
- #endif //MAKE_PINATTACKDELAY
- PinRetval = True;
- }
- // Clean clear PIN block
- memset( WorkData, 0, sizeof(WorkData) );
- // Clear the entered pin.
- memset( pinblock, 0, sizeof( pinblock ) );
- return PinRetval;
- }
- //-----------------------------------------------------------------------------
- // InternalPinBGenerate For Using T2100 internal SSM to generate Encrypted Pin-Block
- //
- // Parameters: pData Plain text Pin-block Data for encryption (8 binary bytes)
- // pPinKey Pin key encrypted under corresponding Master Key for Pin Key
- // (packed Hex string)
- // ubAqId Acquirer Id
- // pEPinBlock Return storage for the encrypted Pin-block (binary format, 8 bytes)
- //
- // Global Inputs:
- //
- // Returns: 0 successful Encrypted Pin-block and returned in [pEPinBlock]
- // non-zero for Encryption failed
- // 2 processing error (external PIN-PAD not supported)
- //
- // Notes:
- //
- //-----------------------------------------------------------------------------
- static UBYTE InternalPinBGenerate(UBYTE* pData, UBYTE* pPinKey, UBYTE ubAqId,
- UBYTE* pEPinBlock)
- {
- UWORD uwKeyLen;
- UBYTE mkid;
- UBYTE tmpaqbuffer[S_AQWORKKEY + S_AQWORKKEY];
- // @@dump, v01A, KF 042506
- // CURRENTLY, DUKPT IS NOT SUPPORTED HERE, WILL NEED ADDITION EFFORT TO IMPLEMENT DUKPT
- // Set working key - binary value
- mkid = Binary(GetEncKeyId(ubAqId) );
- // Implementation of Internal Master Session for PIN Key
- memset(tmpaqbuffer, 0x00, sizeof(tmpaqbuffer));
- switch(GetProfileByte(BD_AQ_KEY_LENGTH, ubAqId))
- {
- case 2: // double length key
- case 3: // triple length key, PS:the crypto API currently not supporting triple length key, use double length instead
- uwKeyLen = S_AQWORKKEY*2;
- break;
- case 1: // single length key
- default:
- uwKeyLen = S_AQWORKKEY;
- break;
- }
- memcpy( tmpaqbuffer, pPinKey, uwKeyLen );
- if (uwKeyLen == S_AQWORKKEY)
- { // duplicate the first part key to second part key
- memcpy(&tmpaqbuffer[S_AQWORKKEY], pPinKey, S_AQWORKKEY );
- }
- // generate encrypted PIN-Block
- CS_Open(False);
- if ( 1 == CS_EncryptPIN( mkid, tmpaqbuffer, pEPinBlock, pData ) )
- { // PIN-block encryption OK
- return 0;
- } else
- { // encryption failure
- return 2;
- }
- }
- //-----------------------------------------------------------------------------
- // InternalMacGenerate For Using T2100 internal SSM to generate MAC
- //
- // Parameters: pData Data for MAC generation
- // uwDataLength Length of Data for MAC generation
- // pMacKey Mac key encrypted under corresponding Master Key for Mac Key
- // (packed Hex string)
- // ubAqId Acquirer Id
- // pMac Return storage for the generated MAC (binary format, 8 bytes)
- //
- // Global Inputs:
- //
- // Returns: 0 successful MAC generated 8 bytes MAC returned in [pMAC]
- // non-zero for MAC generation failed
- // 2 processing error (external PIN-PAD not supported)
- //
- // Notes:
- //
- //-----------------------------------------------------------------------------
- static UBYTE InternalMacGenerate(UBYTE* pData, UWORD uwDataLength,
- UBYTE* pMacKey, UBYTE ubAqId, UBYTE* pMac)
- {
- UWORD uwKeyLen;
- UWORD data_remaining;
- UBYTE ubTmp, mkid, PinRetval;
- UBYTE WorkData[8];
- UBYTE MacBlock[8], aTmp[8];
- UBYTE tmpaqbuffer[S_AQWORKKEY + S_AQWORKKEY];
- unsigned char dummy[50], szDummy[5];
- int i=0;
- // @@dump, v01A, KF 042506
- // CURRENTLY, DUKPT IS NOT SUPPORTED HERE, WILL NEED ADDITION EFFORT TO IMPLEMENT DUKPT
- // Set working key - binary value
- mkid = Binary(GetMACKeyId(ubAqId) );
- // Implementation of Internal Master Session for MAC Key
- memset(tmpaqbuffer, 0x00, sizeof(tmpaqbuffer));
- data_remaining = uwDataLength;
- switch(GetProfileByte(BD_AQ_KEY_LENGTH, ubAqId))
- {
- case 2: // double length key
- case 3: // triple length key, PS:the crypto API currently not supporting triple length key, use double length instead
- uwKeyLen = S_AQWORKKEY*2;
- break;
- case 1: // single length key
- default:
- uwKeyLen = S_AQWORKKEY;
- break;
- }
- //+ taha 05-09-2018 hard code mac key, and data +
- memset( pData, (UBYTE)'\x01', uwDataLength );
- memset( pMacKey, (UBYTE)'\x02', uwKeyLen);
- sprintf(dummy,"mkid: %02x",mkid);
- vdLA_Print(0,dummy,0,0);
- //- taha 05-09-2018 hard code mac key, and data -
- // + taha 06-09-2018 show modified MAC data on rock +
- vdLA_Print(0,"MAC data modified:" ,0,0);
- memset(dummy,0,sizeof(dummy));
- for (i=0 ; i < uwDataLength ; i++)
- {
- memset(szDummy,0x00,sizeof(szDummy));
- sprintf(szDummy,"%02X ", *(pData+i) );
- strcat(dummy,szDummy);
- if (strlen(dummy) >= 42)
- {
- vdLA_Print(0,dummy,0,0);
- memset(dummy,0x00,sizeof(dummy));
- }
- }
- if (strlen(dummy) > 0)
- {
- vdLA_Print(0,dummy,0,0);
- }
- // - taha 06-09-2018 show modified MAC data on rock -
- // + taha 01-09-2018 show modified mac key on rock +
- vdLA_Print(0,"mac key modified:",0,0);
- memset(dummy,0,sizeof(dummy));
- for (i=0 ; i < uwKeyLen ; i++ )
- {
- memset(szDummy,0x00,sizeof(szDummy));
- sprintf(szDummy,"%02X ", pMacKey[i] );
- strcat(dummy,szDummy);
- if (strlen(dummy) >= 42)
- {
- vdLA_Print(0,dummy,0,0);
- memset(dummy,0x00,sizeof(dummy));
- }
- }
- if (strlen(dummy) > 0)
- {
- vdLA_Print(0,dummy,0,0);
- }
- // - taha 06-09-2018 show modified mac key on rock -
- memcpy ( tmpaqbuffer, pMacKey, uwKeyLen );
- if (uwKeyLen == S_AQWORKKEY)
- { // duplicate the first part key to second part key
- memcpy(&tmpaqbuffer[S_AQWORKKEY], pMacKey, S_AQWORKKEY );
- }
- // testing
- // calculate MAC using DES/3DES in CBC mode
- PinRetval = 1;
- memset( MacBlock, 0, 8 );
- memset( aTmp, 0x00, sizeof(aTmp));
- data_remaining = uwDataLength;
- CS_Open(False);
- do
- {
- // for data block not multiply of 8, trailing fill with binary zero
- memset( WorkData, 0, 8 );
- if ( data_remaining > 8 )
- memcpy ( WorkData, pData, 8 );
- else
- memcpy ( WorkData, pData, data_remaining );
- for (ubTmp =0; ubTmp < 8; ubTmp++)
- WorkData[ubTmp] ^= MacBlock[ubTmp];
- // Loop here pulling 8 bytes at a time from callers page.
- PinRetval &= CS_CreateMAC ( mkid, tmpaqbuffer, MacBlock, WorkData, 8, 1 );
- if (data_remaining > 8)
- {
- data_remaining -= 8;
- pData += 8;
- } else
- {
- data_remaining = 0;
- }
- } while ( 0 != data_remaining );
- memset(dummy,0,sizeof(dummy));
- sprintf(dummy, "%02x %02x %02x %02x %02x %02x %02x %02x ",
- MacBlock[0], MacBlock[1], MacBlock[2], MacBlock[3],
- MacBlock[4], MacBlock[5], MacBlock[6], MacBlock[7] );
- vdLA_Print(0,dummy,0,0);
- if ( PinRetval == 1 )
- { // MAC generation OK
- vdLA_Print(0,"MAC generation OK",0,0);
- memcpy ( pMac, MacBlock, 8 );
- return 0;
- }
- // MAC generation failure
- return 2;
- }
- //-----------------------------------------------------------------------------
- // PreparePinCalc Clear PINBUF, OUTPIN and initialize pointer into OUTPIN
- //
- // Parameters: None
- // Global Inputs:
- // Returns: None
- // Notes:
- //
- //-----------------------------------------------------------------------------
- static void PreparePinCalc( void )
- {
- // Clear PINBUF, OUTPIN and initialize pointer into OUTPIN.
- memset( ( UBYTE * ) PINBUF, 0, S_PINBUF );
- memset( ( UBYTE * ) OUTPIN, 0, sizeof( OUTPIN ) );
- }
- //-----------------------------------------------------------------------------
- // GetCommand Get message separator
- //
- // Parameters: char* - Command string
- //
- // Global Inputs:
- //
- // Returns: Number of byte added in the PIN buffer for the command
- //
- // Notes: Set proper message separator in the buffer
- // '.' - for CAT33 protocol
- // '/' - for POSMINI protocol
- //-----------------------------------------------------------------------------
- static UBYTE GetCommand( UBYTE* cmd, UBYTE* pMsgBuf)
- {
- UBYTE ubLen;
- ubLen = 0;
- memcpy( pMsgBuf+ubLen, cmd, 2 );
- ubLen += 2;
- if ( PIN_CAT33 == *((UBYTE*)PIN_CONFIG) || ( OUTPIN[0] == 'A' ) )
- pMsgBuf[ubLen] = '.';
- else
- pMsgBuf[ubLen] = '/';
- ubLen++;
- return ubLen;
- }
- #if 0
- static UBYTE GetFS( void )
- {
- return '\x1C';
- }
- #endif
- //-----------------------------------------------------------------------------
- // GetEncKeyId Get Encryption working Key ID
- //
- // Parameters: None
- // Global Inputs:
- // Returns: UBYTE - key ID
- // Notes:
- //
- //-----------------------------------------------------------------------------
- static UBYTE GetEncKeyId( UBYTE ubAqId )
- {
- UBYTE AqMKID;
- AqMKID = GetProfileByte(BD_AQ_PIN_MASTER_KID, ubAqId);
- // convert numeric 0-12 to ASCII '0' - 'B'
- if (AqMKID <= 9)
- {
- AqMKID = '0' + AqMKID;
- } else if (AqMKID <= 12)
- {
- AqMKID = 'A' + (AqMKID-10);
- }
- #ifdef MAKE_VIKING
- if ( ((AqMKID < '0') || (AqMKID > '9')) && (AqMKID != 'A') && (AqMKID != 'B') )
- {
- return ('0');
- }
- #else // MAKE_VIKING
- if ( ((AqMKID < '0') || (AqMKID > '9')) && ((AqMKID < 'A') || (AqMKID > 'C')) )
- {
- return ('0');
- }
- #endif // MAKE_VIKING
- return (AqMKID);
- }
- //-----------------------------------------------------------------------------
- // GetEncKeyId Get Encryption MAC Master Key ID
- //
- // Parameters: None
- // Global Inputs:
- // Returns: UBYTE - Acquirer ID
- // Notes:
- //
- //-----------------------------------------------------------------------------
- static UBYTE GetMACKeyId( UBYTE ubAqId )
- {
- UBYTE AqMKID;
- AqMKID = GetProfileByte(BD_AQ_MAC_MASTER_KID, ubAqId);
- // convert numeric 0-12 to ASCII '0' - 'B'
- if (AqMKID <= 9)
- {
- AqMKID = '0' + AqMKID;
- } else if (AqMKID <= 12)
- {
- AqMKID = 'A' + (AqMKID-10);
- }
- #ifdef MAKE_VIKING
- if ( ((AqMKID < '0') || (AqMKID > '9')) && (AqMKID != 'A') && (AqMKID != 'B') )
- {
- return ('0');
- }
- #else // MAKE_VIKING
- if ( ((AqMKID < '0') || (AqMKID > '9')) && ((AqMKID < 'A') || (AqMKID > 'C')) )
- {
- return ('0');
- }
- #endif // MAKE_VIKING
- return (AqMKID);
- }
- //-----------------------------------------------------------------------------
- // GetEncKey Get Encryption working Key
- //
- // Parameters: UBYTE* - pointer to encrypted key
- // short - key length
- // Bool - double length key flag
- // Global Inputs:
- // Returns: None
- // Notes: Put the Key into output buffer
- //
- //-----------------------------------------------------------------------------
- //static UBYTE GetEncKey( UBYTE* keyptr, UWORD len, Bool dblflag, UBYTE* pMsgBuf )
- #if 0
- static UBYTE GetEncKey(UBYTE ubAqId, int nProfileKeyId, UBYTE* pMsgBuf)
- {
- UBYTE ubLen, ubKeyLen;
- Bool empty;
- UBYTE tmpaqbuffer[S_AQWORKKEY*3];
- UWORD uwSize;
- memset(tmpaqbuffer, 0x00, sizeof(tmpaqbuffer));
- // check the key length
- ubKeyLen = GetProfileByte(BD_AQ_KEY_LENGTH, ubAqId);
- if (ubKeyLen == 3)
- { // single key length
- ubKeyLen = S_AQWORKKEY*3;
- } else if (ubKeyLen == 2)
- { // single key length
- ubKeyLen = S_AQWORKKEY*2;
- } else
- { // default to single key length
- ubKeyLen = S_AQWORKKEY;
- }
- /* Copy key from aquirer table */
- uwSize = ubKeyLen;
- GetProfileData(nProfileKeyId, ubAqId, tmpaqbuffer, &uwSize);
- // Init. empty flag
- empty = True;
- // Check conditions
- if ( !NullComp( ( char * ) tmpaqbuffer, ubKeyLen ) )
- {
- empty = False;
- }
- ubLen = 0;
- // If key is all zeros then send all spaces.
- if ( empty )
- {
- if ( PIN_CAT33 == *((UBYTE*)PIN_CONFIG) )
- {
- memset( pMsgBuf+ubLen, ' ', ( ubKeyLen << 1 ) );
- ubLen += ( ubKeyLen << 1 );
- } else
- {
- memset( pMsgBuf+ubLen, 0, ubKeyLen );
- ubLen += ubKeyLen;
- }
- } else
- {
- if ( PIN_CAT33 == *((UBYTE*)PIN_CONFIG) )
- {
- BfAscii( ( char * ) pMsgBuf+ubLen, tmpaqbuffer, ubKeyLen );
- ubLen += ( ubKeyLen << 1 );
- } else
- {
- memcpy( pMsgBuf+ubLen, tmpaqbuffer, ubKeyLen );
- ubLen += ubKeyLen;
- }
- }
- return ubLen;
- }
- #endif
- //-----------------------------------------------------------------------------
- // GetPINDevice Return device configuration mode
- //
- // Parameters: None
- // Global Inputs:
- // Returns: True - success, False - error
- // Notes: Set PIN_DEVICE & PIN_CONFIG variables
- //-----------------------------------------------------------------------------
- static UBYTE GetPINDevice( void )
- {
- UBYTE aTmp[20];
- IOCS_DDDA_DATA ddda;
- OSRETURNCODES status;
- UBYTE i, ubLen, ubSize;
- /* Check for terminal restart or initialization */
- if ( !PIN_DEVICE )
- {
- /* Prepare progress buffer */
- memset(aTmp, 0x00, sizeof(aTmp));
- ubLen = 0;
- aTmp[ubLen++] = '<';
- memset( aTmp+ubLen, ' ', sizeof(ProtList)/sizeof(CFGDATA) - 1 );
- aTmp[sizeof(ProtList)/sizeof(CFGDATA)] = '>';
- aTmp[sizeof(ProtList)/sizeof(CFGDATA) + 1] = 0;
- MSG_SetUserMsg(2, aTmp, 0);
- // Display PIN AUTO DETECTING message.
- ShowInfoMsgNoWait(MSG_ID_PinPadAutoDetect, MSG_ID_SPECIAL_MSG2);
- for ( i = 0; ProtList[i].device != 0; i++ )
- { /* Set device */
- PIN_DEVICE = ProtList[i].device;
- /* Check communication */
- if ( !(RS232_GetRSOPT( ) & RSOPT_RSACTIVE) || !(PIN_DEVICE == PRT) )
- {
- /* Close the device */
- if ( OK == OS_DeviceClose( PIN_DEVICE )) PINFLG.deviceOpen = 0;
- /* Try to open device */
- status = OS_DeviceOpen( PIN_DEVICE );
- if ( OK == status ) PINFLG.deviceOpen = 1; /* Device opened successfully */
- /* Set config parameters pointer */
- PIN_CONFIG = ProtList[i].cfgptr;
- /* Configure device */
- ddda.pubyte = PIN_CONFIG;
- status = OS_DeviceConfig ( PIN_DEVICE, GetMode(), &ddda );
- /* PINPAD just powered up */
- if ( ProtList[i].power == PIN_CPWR_ON ) OS_Wait( ONESECOND*3 );
- /* Check config status */
- if ( OK == status )
- { /* Clear output buffer */
- memset( ( UBYTE * ) OUTPIN, 0, sizeof( OUTPIN ) );
- ubLen = 0;;
- ubSize = GetCommand( "90", OUTPIN+ubLen );
- ubLen += ubSize;
- // Write message to Pin Pad
- if ( OK == Write_Pin( (UWORD)ubLen ) )
- {
- /* Read PINPAD answer */
- if ( OK == Read_Pin( ONESECOND ) )
- {
- // Check for PIN BLOCK response code.
- if ( !memcmp( PINBUF, ( UBYTE * ) "91", 2 ) )
- {
- // Set external PINPAD type
- PIN_TYPE = PIN_TYPE_EXTERNAL;
- // Set power mode
- if ( PowerOnFlag != 0xAA )
- {
- OS_Wait( MS100*2 );
- ddda.data = ProtList[i].power;
- OS_DeviceConfig ( PIN_DEVICE, PIN_CONST_PWR, &ddda );
- OS_Wait( MS100*2 );
- PowerOnFlag = 0xAA ;
- }
- /* Close the device */
- if ( OK == OS_DeviceClose( PIN_DEVICE )) PINFLG.deviceOpen = 0;
- /* Change detect progress */
- memset( &aTmp[1], '-', sizeof(ProtList)/sizeof(CFGDATA) - 1 );
- aTmp[i + 1] = '*';
- MSG_SetUserMsg(2, aTmp, 0);
- //ShowInfoMsg( CustomMsg2, N_Pinpad );
- ShowInfoMsgNoWait(MSG_ID_Pinpad, MSG_ID_SPECIAL_MSG2);
- OS_Wait( ONESECOND*2 );
- // Receive correct response code, exit
- return True;
- }
- }
- }
- }
- /* Close the device */
- if ( OK == OS_DeviceClose( PIN_DEVICE )) PINFLG.deviceOpen = 0;
- }
- // Clear PIN device
- PIN_DEVICE = 0;
- /* Change detect progress */
- aTmp[i + 1] = '-';
- MSG_SetUserMsg(2, aTmp, 0);
- ShowInfoMsgNoWait(MSG_ID_PinPadAutoDetect, MSG_ID_SPECIAL_MSG2);
- }
- #ifdef MAKE_VIKING
- // Open CryptoService
- CS_Open( False );
- #else // MAKE_VIKING
- /* Try to find internal PINPAD */
- // Read the revision number from the Z8 and display it.
- // Clear PINBUF, OUTPIN and initialize pointer to OUTPIN.
- // Build message that goes direct to the Z8 in PINOUT.
- // Receive the message directly from the Z8 into PINBUF.
- memset( ( UBYTE * ) OUTPIN, 0, sizeof( OUTPIN ) );
- // The command string to the Z8 to request the version
- // number is command value of 0x00. Already set by clear.
- // Use exact length of command that Z8 expects. It is not
- // necessary to fill in unused fields, leave them nulls.
- OutLen = Z8LEN_ReturnVersionNumber;
- #endif // MAKE_VIKING
- #ifdef MAKE_VIKING
- // Test the internal PIN PAD
- if ( CS_StatusSSM() )
- #else // MAKE_VIKING
- // Send the command to the Z8 and verify the Z8 responds.
- if ( FunctionZ8() )
- #endif // MAKE_VIKING
- {
- /* Set PIN device */
- PIN_DEVICE = PIN;
- // Internal pinpad exists.
- PIN_TYPE = PIN_TYPE_ICE5000;
- }
- else
- {
- // Force pin type to invalid.
- PIN_TYPE = PIN_TYPE_INVALID;
- // No external and no internal Z8 detected.
- ShowErrMsg( MSG_ID_PinpadNotFound );
- /* Exit */
- return False;
- }
- }
- return True;
- }
- /*------------------------------------------------------------------
- * Name: StartRspTimer
- * Description: Starts a timer to detect a response timeout. Flags bit 0
- * of 'flag' upon expiration.
- *
- * Parameters: PTCS_BLK , flag, timeout
- *
- * Return Value: none.
- *
- *-----------------------------------------------------------------*/
- static void StartRspTimer( PTCS_BLK *blk, UBYTE *flag, unsigned short timeout )
- {
- blk->ptcs_cmnd = TIMER; // Request a PTCS timer service
- blk->ptcs_scmd = PROCEED + FLAG; // Select Proceed+Flag option
- blk->ptcs_time = timeout; // Set timer timeout value
- #ifdef MAKE_VHDT
- blk->ptcs_ifad.pubyte = flag; // Pointer to the flag to be used
- #else
- blk->ptcs_ifad = flag; // Pointer to the flag to be used
- #endif
- blk->ptcs_fbit = 0; // Flag to bit 0
- OS_Function ( RQPTCS, blk ); // Call the OS service handler
- } // end of StartRspTimer
- //-----------------------------------------------------------------------------
- // GetMode Return device configuration mode
- //
- // Parameters: None
- // Global Inputs:
- // Returns: UBYTE: PIN_CFG_PROT for PIN device
- // PRT_CFG_PROT for PRT device
- // Notes:
- //-----------------------------------------------------------------------------
- static UBYTE GetMode( void )
- {
- /* Set device mode */
- if ( PIN == PIN_DEVICE )
- return PIN_CFG_PROT;
- else
- return PRT_CFG_PROT;
- }
- //-----------------------------------------------------------------------------
- // Open_Config Opens and configures the Pin Pad port.
- //
- // Parameters: None
- // Global Inputs:
- // Returns: Bool True if successful, False if error
- // Notes:
- //-----------------------------------------------------------------------------
- extern Bool Open_Config( void )
- {
- IOCS_DDDA_DATA ddda;
- OSRETURNCODES status;
- /* Already open, return */
- if ( PINFLG.deviceOpen ) return( OK );
- /* Check PIN device type */
- if ( PIN_TYPE == PIN_TYPE_ICE5000 ) return ( OK );
- /* Check PIN device setting */
- if ( !GetPINDevice() ) return ( !OK );
- /* Check PIN device type again */
- if ( PIN_TYPE == PIN_TYPE_ICE5000 ) return ( OK );
- /* Try to open the PIN device */
- status = OS_DeviceOpen( PIN_DEVICE );
- if (status == ERRBSY) // BUSY
- {
- Rewind_Pin( ); // close, rewind and reopen
- status = OS_DeviceOpen( PIN_DEVICE );
- }
- /* Configure PINPAD device */
- if ( OK == status )
- {
- ddda.pubyte = PIN_CONFIG;
- status = OS_DeviceConfig ( PIN_DEVICE, GetMode(), &ddda );
- }
- if ( OK == status )
- PINFLG.deviceOpen = 1; /* Device opened successfully */
- else
- Rewind_Pin( ); /* Error opening & configuring device */
- return ( status );
- }
- //-----------------------------------------------------------------------------
- // Write_Pin Writes contents of OUTPIN to Pin Pad.
- //
- // Parameters: UWORD Length of data that must be in OUTPIN
- // Global Inputs:
- // Returns: Bool True if successful, False if error
- // Notes:
- //-----------------------------------------------------------------------------
- extern Bool Write_Pin( UWORD length )
- {
- Bool Retval = !OK ;
- if ( PIN_TYPE_ICE5000 == PIN_TYPE )
- { /* Internal pinpad */
- Retval = OK;
- } else
- {
- if ( OK == OS_DeviceWrite( PIN_DEVICE, OUTPIN, length ) )
- {
- Retval = OK ;
- } else
- {
- Rewind_Pin( );
- }
- }
- return(Retval);
- }
- //-----------------------------------------------------------------------------
- // Close_Pin Closes Pin Pad.
- //
- // Parameters: None
- //
- // Global Inputs:
- //
- // Returns: Bool True if successful, False if error
- //
- // Notes:
- //
- //-----------------------------------------------------------------------------
- extern Bool Close_Pin( void )
- {
- Bool retval;
- if (!PINFLG.deviceOpen)
- { /* Device already closed */
- return( OK );
- }
- retval = !OK ;
- if ( PIN_TYPE_EXTERNAL == PIN_TYPE )
- {
- if ( OK == OS_DeviceClose( PIN_DEVICE ) )
- {
- PINFLG.deviceOpen = 0;
- retval = OK;
- }
- } else
- {
- // Internal T5000 pinpad.
- retval = OK ;
- }
- return ( retval );
- }
- //-----------------------------------------------------------------------------
- // Read_Pin Reads message from Pin Pad.
- //
- // Parameters: OS_TIMES timout Time out value
- // Global Inputs:
- // Returns: Bool True if successful, False if error
- // Notes: Data is returned in global buffer OUTPIN
- //-----------------------------------------------------------------------------
- extern Bool Read_Pin( OS_TIMES timeout )
- {
- Bool Retval;
- UBYTE readflag;
- UWORD pinlen;
- UBYTE ubKey;
- Retval = !OK ;
- pinlen = 0;
- if ( PIN_TYPE_ICE5000 == PIN_TYPE )
- { // Internal T5000 pinpad
- } else
- { /* Post a read to the pin device */
- if ( OK != DeviceRead (PIN_DEVICE, &PINBLKR, PROCEED+FLAG, PINBUF, sizeof(PINBUF), &readflag, 7 ) )
- {
- } else
- { /* Start response timer */
- StartRspTimer( &TIM_01, &readflag, timeout );
- /* Wait for timeout (bit 0) or read complete (bit 7) */
- while( ! ( readflag & 0x01 ) )
- {
- ubKey = GetOneKey(STAY_OPEN1|DEV_KBD|STAY_OPEN0, 0);
- if (ubKey == CANCEL_KY || ubKey == CLEAR_KY)
- break; // user cancelled
- if ( ( readflag & 0x80 ) && ( OK == PINBLKR.iocs_stati ) )
- {
- pinlen = PINBLKR.iocs_var.iocs_xfer.iocs_tlenx;
- Retval = OK ;
- break;
- }
- // Give up some cycles while waiting...
- SDK_RelinqCPU( );
- } // while()
- // Force a close of still open pad and kbd devices.
- GetOneKey(STAY_OPEN1|DEV_KBD, 0);
- /* Cancel response timeout timer */
- OS_CancelTimer ( &TIM_01 );
- }
- if ( OK != Retval )
- {
- Rewind_Pin();
- }
- }
- return ( Retval );
- }
- //-----------------------------------------------------------------------------
- // FormatPin Formats the pin and pan for use in pin encryption.
- //
- // Parameters: ubPinLen - Length of PIN entered
- // pPlainPin - PIN (ASCII, numeric digit only)
- // pPAN_N2 - PAN (packed BCD format)
- // pWorkData - PIN-BLOCK data buffer (8 bytes required)
- //
- // Global Inputs:
- // Returns: None
- // Notes: Result of pin/pan format is stored in WorkData.
- //-----------------------------------------------------------------------------
- extern void FormatPin( UBYTE ubPinLen, UBYTE* pPlainPin, UBYTE* pPAN_N2, UBYTE* pWorkData )
- {
- UBYTE aTmp[40];
- UBYTE WorkData[8];
- UBYTE FormatPanBuf[10];
- UBYTE i, j, ubPINDigit;
- UBYTE *pASCII_PAN;
- // Start by filling the pin work buffer with hex FF's.
- memset( WorkData, 0xFF, sizeof( WorkData ) );
- // Move the length of the pin to start of pin work buffer.
- WorkData[0] = ubPinLen;
- // Convert pin digits to hex and store in pin work buffer. The
- // result should be one byte length, pin in hex padded with F's.
- // For example, pin length of 5 and pin of "12345" results in
- // 05 12 34 5F FF FF FF FF
- for ( i = 0, j = 1; i < ubPinLen; i++, j++ )
- {
- // the lower nibble is the numeric pin digit
- ubPINDigit = pPlainPin[i] & 0x0f;
- WorkData[j] = ubPINDigit<<4 | 0x0F; // padd unused nibble with F
- // Quit here if an odd number of bytes in PIN.
- if ( i == ubPinLen - 1 )
- break;
- // Move to next ASCII input byte.
- i++;
- // Move second nibble to format buffer.
- WorkData[j] &= 0xf0;
- WorkData[j] |= ( pPlainPin[i] & 0x0f );
- }
- // Shift the PAN 5 nibbles to the right.
- // Original PAN of '44 27 80 26 41 00 47 97 FF FF' should be
- // '00 00 00 00 78 02 64 10 04 79' after shifts.
- // Clear the working buffer for formatting the PAN.
- memset( FormatPanBuf, 0, sizeof( FormatPanBuf ) );
- // Convert the PAN (N2) to an ASCII string.
- memset(aTmp, 0x00, sizeof(aTmp));
- BfAscii( ( char * ) aTmp, pPAN_N2, sizeof( FormatPanBuf ) );
- // Set pASCII_PAN to the end of the PAN data (look for 'F').
- pASCII_PAN = aTmp;
- while ( *pASCII_PAN != 'F' )
- pASCII_PAN++;
- // Now back up two - skip the 'F' we just found, and the check digit.
- pASCII_PAN -= 2;
- // Now walk backwards through the ASCII PAN data, storing 12 nibbles.
- // Stop when we've got 12 nibbles or when we're out of PAN data.
- i = 7;
- while ( ( i > 1 ) && ( pASCII_PAN >= ( UBYTE * ) aTmp) )
- {
- FormatPanBuf[i] = A2hex( *pASCII_PAN ); // Low nibble.
- pASCII_PAN--;
- if ( pASCII_PAN >= ( UBYTE * ) aTmp )
- {
- FormatPanBuf[i] |= ( A2hex( *pASCII_PAN ) << 4 ); // High nibble.
- pASCII_PAN--;
- }
- i--;
- }
- // XOR FormatPanBuf with WorkData.
- for ( i = 0; i < sizeof( WorkData ); i++ )
- {
- WorkData[i] = WorkData[i] ^ FormatPanBuf[i];
- }
- // return PIN-BLOCK Data to caller
- memcpy(pWorkData, WorkData, sizeof(WorkData));
- }
- #ifdef __CS_TEST__
- static void SecurityTest( void )
- {
- unsigned char IK0[] = {0xB0,0x15,0x0A,0xF5,0xBB,0x82,0x96,0x63};
- unsigned char IK1[] = {0x0E,0xAB,0x43,0xC3,0xF7,0xE4,0x78,0xB8,0x7E,0x57,0x3B,0x96,0x3E,0x6D,0xAA,0x59};
- unsigned char IK2[] = {0xCC,0xA7,0xF1,0xDF,0xB9,0xBB,0x62,0x83};
- unsigned char IKSN0[] = {0xFF,0xFF,0x00,0x00,0x01,0x11,0x11,0x00,0x00,0x00};
- unsigned char IKSN1[] = {0xFF,0xFF,0x00,0x00,0x02,0x22,0x22,0x00,0x00,0x00};
- unsigned char IKSN2[] = {0xFF,0xFF,0x00,0x00,0x03,0x33,0x33,0x00,0x00,0x00};
- #if 0
- unsigned char MK0[] = {0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31};
- #endif
- unsigned char MK0[] = {0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31};
- unsigned char MK1[] = {0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32};
- unsigned char eMK1[] = {0x99,0x0F,0xEE,0x15,0x96,0x7F,0xE8,0x04,0x1A,0x79,0x3D,0xBC,0x13,0xE3,0x30,0x3D};
- unsigned char WK[] = {0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34};
- #if 0
- unsigned char eWK0[] = {0xC5,0x48,0xB2,0xB8,0xCA,0xF9,0xB4,0x01,0xF1,0xC1,0x18,0x68,0xFE,0x25,0xCD,0xE0};
- // C548B2B8CAF9B401-F1C11868FE25CDE0
- #endif
- // kf, TESTING KEY OF 3131313131313131-3131313131313131 ENCRYPTED UNDER tmk 3131313131313131-3131313131313131
- unsigned char eWK0[] = {0x65,0x5E,0xA6,0x28,0xCF,0x62,0x58,0x5F,0x65,0x5E,0xA6,0x28,0xCF,0x62,0x58,0x5F};
- unsigned char eWK1[] = {0x8C,0xAB,0xEF,0xF1,0x1F,0x97,0xDC,0xA2,0x8E,0xDF,0x89,0x62,0xBC,0xA9,0x10,0x4C};
- unsigned char DT[] =
- {
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11
- };
- unsigned char MAC[] =
- {
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD
- };
- unsigned char work[16 + 16];
- unsigned char data[8 + 10];
- int status;
- unsigned long result;
- char SN[16 + 1];
- // Open CryptoService
- CS_Open( True );
- // Get the Serial Number
- memset( SN, 0, sizeof(SN) );
- status = CS_GetSN( SN, sizeof(SN) );
- // Open CryptoService
- CS_Open( False );
- // Get SSM status
- if ( CS_StatusSSM() )
- {
- // Prepare MK with PIN TAG
- memcpy( work, MK0, sizeof(MK0) );
- work[16] = 1;
- // Store plain MK0
- result = CS_StoreMK( 1, work );
- // Prepare MK with MAC TAG
- memcpy( work, MK0, sizeof(MK0) );
- work[16] = 8;
- // Store plain MK0
- result = CS_StoreMK( 2, work );
- // Calculate PIN
- result = CS_EncryptPIN(1, eWK0, data, DT);
- #if 0
- // KF, v01A, KF 042706, standard test using key 31...31
- {
- UBYTE aTestPIN[8];
- UBYTE aData2[8], aData3[8];
- memset(aTestPIN, 0x00, sizeof(aTestPIN));
- asc2bcd(aTestPIN, "06127765cddddeee", 16);
- memset(aData2, 0x00, sizeof(aData2));
- memset(aData3, 0x00, sizeof(aData3));
- result = CS_EncryptPIN(1, eWK0, aData2, aTestPIN);
- result = CS_CreateMAC ( 2, eWK0, aData3, aTestPIN, 8, 1 );
- asc2bcd(aTestPIN, "596656744C9371C0", 16);
- memset(aData2, 0x00, sizeof(aData2));
- memset(aData3, 0x00, sizeof(aData3));
- result = CS_EncryptPIN(1, eWK0, aData2, aTestPIN);
- result = CS_CreateMAC ( 2, eWK0, aData3, aTestPIN, 8, 1 );
- result = CS_CreateMAC ( 2, eWK0, aData2, aTestPIN, 8, 0 );
- }
- #endif
- // Calculate MAC
- result = CS_CreateMAC(2, eWK0, data, MAC, sizeof(MAC), 0);
- result = CS_CreateMAC(2, eWK0, data, MAC, sizeof(MAC), 1);
- // Generate Key
- result = CS_GenerateKey(1, work);
- // Decrypt PIN
- result = CS_DecryptPIN(1, work, data, DT);
- return;
- //==================================================================
- //
- // // Prepare MK with PIN TAG
- memcpy( work, eMK1, sizeof(eMK1) );
- work[16] = 1;
- // Store encrypted MK
- result = CS_StoreEncryptedMK( 1, work );
- // Prepare MK with MAC TAG
- memcpy( work, eMK1, sizeof(eMK1) );
- work[16] = 8;
- // Store encrypted MK
- result = CS_StoreEncryptedMK( 2, work );
- // Calculate PIN
- result = CS_EncryptPIN(1, eWK1, data, DT);
- // Calculate MAC
- result = CS_CreateMAC(2, eWK1, data, MAC, sizeof(MAC), 0);
- result = CS_CreateMAC(2, eWK1, data, MAC, sizeof(MAC), 1);
- // Generate Key
- result = CS_GenerateKey(1, work);
- // Decrypt PIN
- result = CS_DecryptPIN(1, work, data, DT);
- }
- if ( CS_StatusSSM() )
- {
- // Load DUKPT keys
- result = CS_InitDUKPT(0, IK0, IKSN0, 1); // Single
- result = CS_InitDUKPT(1, IK1, IKSN1, 0); // Double
- result = CS_InitDUKPT(2, IK2, IKSN2, 1); // Single
- // Generate Keys
- result = CS_GenerateKey_DUKPT(0);
- result = CS_GenerateKey_DUKPT(1);
- result = CS_GenerateKey_DUKPT(2);
- // PIN Calculation
- result = CS_EncryptPIN_DUKPT(0, data, DT);
- result = CS_EncryptPIN_DUKPT(1, data, DT);
- result = CS_EncryptPIN_DUKPT(2, data, DT);
- // MAC Calculation
- result = CS_CreateMAC_DUKPT(0, data, MAC, sizeof(MAC), 0);
- result = CS_CreateMAC_DUKPT(1, data, MAC, sizeof(MAC), 0);
- result = CS_CreateMAC_DUKPT(2, data, MAC, sizeof(MAC), 0);
- // Generate Keys
- result = CS_GenerateKey_DUKPT(0);
- result = CS_GenerateKey_DUKPT(1);
- result = CS_GenerateKey_DUKPT(2);
- // PIN Calculation
- result = CS_EncryptPIN_DUKPT(0, data, DT);
- result = CS_EncryptPIN_DUKPT(1, data, DT);
- result = CS_EncryptPIN_DUKPT(2, data, DT);
- // MAC Calculation
- result = CS_CreateMAC_DUKPT(0, data, MAC, sizeof(MAC), 1);
- result = CS_CreateMAC_DUKPT(1, data, MAC, sizeof(MAC), 1);
- result = CS_CreateMAC_DUKPT(2, data, MAC, sizeof(MAC), 1);
- // Check for error
- result = CS_EncryptPIN_DUKPT(0, data, DT);
- result = CS_CreateMAC_DUKPT(1, data, MAC, sizeof(MAC), 1);
- }
- //==================================================================
- // Open CryptoService
- CS_Open( False );
- // Get SSM status
- if ( CS_StatusSSM() )
- {
- // Test MK
- result = CS_TestMK(1, eWK1, data);
- result = CS_TestMK(2, eWK1, data);
- }
- }
- #endif
Add Comment
Please, Sign In to add comment