def command_FG(cmdObj): """ Generate a random PIN key and return it to the Host encrypted under a ZMK for transmission to another party and under the LMK for storage on the Host database.""" """ Command Pattern: request: Message header + 'FG' + ZMK + Atalla Variant + Delimiter + Key Scheme ZMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer response: Message header + 'FH' + Error code + first PVK under ZMK + second PVK under LMK + Check Value + End Message delimiter + Message Trailer """ (schemeZMK, schemeLMK, kcvLength) = extractKeySchemeAndKcvLength(cmdObj) clearPVK1 = genRandomKey(Configure.CFG_KEY_LENGTH / 2) clearPVK2 = genRandomKey(Configure.CFG_KEY_LENGTH / 2) ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value), cmdObj.ZMK.scheme) cipherPVKUnderLMK = encryptKeyUnderLMK('PVK', clearPVK2, schemeLMK) zmkScheme = KeyScheme(ZMK, schemeZMK) cipherPVKUnderZMK = zmkScheme.encrypt(clearPVK1) pvk1 = KeyScheme(clearPVK1) kcv = hexlify(pvk1.encrypt("\0\0\0\0\0\0\0\0")).upper() pvk2 = KeyScheme(clearPVK2) kcv = hexlify(pvk2.encrypt("\0\0\0\0\0\0\0\0")).upper() respObj = CommandObj() respObj.ResponseCode = DataVariable('00') respObj.PVKUnderZMK = KeyVariable( hexlify(cipherPVKUnderZMK).upper(), schemeZMK) respObj.PVKUnderLMK = KeyVariable( hexlify(cipherPVKUnderLMK).upper(), schemeLMK) if (kcvLength == Configure.CFG_KCV_LENGTH): respObj.CheckValue = DataVariable(kcv1 + kcv2) else: respObj.CheckValue = DataVariable(kcv1[:kcvLength]) return respObj
def command_FI(cmdObj): """ Generate a ZEK or ZAK. """ """ Command Pattern: request: Message header + 'FI' + Flag + ZMK + Atalla Variant + Delimiter + Key Scheme ZMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer response: Message header + 'FI' + Error code + ZEK/ZAK under ZMK + ZEK/ZAK under LMK + Check Value + End Message delimiter + Message Trailer """ if cmdObj.Flag == '0': keyType = 'ZEK' elif cmdObj.Flag == '1': keyType = 'ZAK' else: raise ValueError('ZEK/ZAK Flag error') (schemeZMK, schemeLMK, kcvLength) = extractKeySchemeAndKcvLength(cmdObj) clearZEK_ZAK = genRandomKey(Configure.CFG_KEY_LENGTH / 2) ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value), cmdObj.ZMK.scheme) cipherKeyUnderLMK = encryptKeyUnderLMK(keyType, clearZEK_ZAK, schemeLMK) zmkScheme = KeyScheme(ZMK, schemeZMK) cipherKeyUnderZMK = zmkScheme.encrypt(clearZEK_ZAK) zek_zak = KeyScheme(clearZEK_ZAK) kcv = hexlify(zek_zak.encrypt("\0\0\0\0\0\0\0\0")).upper() respObj = CommandObj() respObj.ResponseCode = DataVariable('00') respObj.ZEKZAKUnderZMK = KeyVariable( hexlify(cipherKeyUnderZMK).upper(), schemeZMK) respObj.ZEKZAKUnderLMK = KeyVariable( hexlify(cipherKeyUnderLMK).upper(), schemeLMK) respObj.CheckValue = DataVariable(kcv[:kcvLength]) return respObj
def command_HA(cmdObj): """ Generate a random key, and encrypt it under a TMK (TPK or PVK) and under LMK pair 16-17. """ """ Command Pattern: request: Message header + 'HA' + TMK + Atalla Variant + Delimiter + Key Scheme TMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer response: Message header + 'HB' + Error code + ZPK under ZMK + ZPK under LMK + Check Value + End Message delimiter + Message Trailer """ (schemeTMK, schemeLMK, kcvLength) = extractTMKSchemeAndKcvLength(cmdObj) clearZPK = genRandomKey(Configure.CFG_KEY_LENGTH / 2) TMK = decryptKeyUnderLMK('TMK', unhexlify(cmdObj.TMK.value), cmdObj.TMK.scheme) cipherTAKUnderLMK = encryptKeyUnderLMK('TAK', clearTAK, schemeLMK) tmkScheme = KeyScheme(TMK, schemeTMK) cipherTAKUnderTMK = tmkScheme.encrypt(clearTAK) tak = KeyScheme(clearTAK) kcv = hexlify(tak.encrypt("\0\0\0\0\0\0\0\0")).upper() respObj = CommandObj() respObj.ResponseCode = DataVariable('00') respObj.TAKUnderTMK = KeyVariable( hexlify(cipherTAKUnderTMK).upper(), schemeTMK) respObj.TAKUnderLMK = KeyVariable( hexlify(cipherTAKUnderLMK).upper(), schemeLMK) respObj.CheckValue = DataVariable(kcv[:kcvLength]) return respObj
def command_IA(cmdObj): """ Generate a random PIN key and return it to the Host encrypted under a ZMK for transmission to another party and under the LMK for storage on the Host database.""" """ Command Pattern: request: Message header + 'IA' + ZMK + Atalla Variant + Delimiter + Key Scheme ZMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer response: Message header + 'IB' + Error code + ZPK under ZMK + ZPK under LMK + Check Value + End Message delimiter + Message Trailer """ (schemeZMK, schemeLMK, kcvLength) = extractKeySchemeAndKcvLength(cmdObj) clearZPK = genRandomKey(Configure.CFG_KEY_LENGTH / 2) ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value), cmdObj.ZMK.scheme) cipherZPKUnderLMK = encryptKeyUnderLMK('ZPK', clearZPK, schemeLMK) zmkScheme = KeyScheme(ZMK, schemeZMK) cipherZPKUnderZMK = zmkScheme.encrypt(clearZPK) zpk = KeyScheme(clearZPK) kcv = hexlify(zpk.encrypt("\0\0\0\0\0\0\0\0")).upper() respObj = CommandObj() respObj.ResponseCode = DataVariable('00') respObj.ZPKUnderZMK = KeyVariable( hexlify(cipherZPKUnderZMK).upper(), schemeZMK) respObj.ZPKUnderLMK = KeyVariable( hexlify(cipherZPKUnderLMK).upper(), schemeLMK) respObj.CheckValue = DataVariable(kcv[:kcvLength]) return respObj
def command_A0(cmdObj): """ To generate a key and optionally encrypt key under ZMK for transmission.""" """ Command Pattern: request: Message header + 'A0' + Mode + Key Type + Key Scheme LMK + ZMK + Key Scheme ZMK + Atalla Variant + End message delimiter + Message Trailer response: Message header + 'A1' + Error code + Key under LMK + Key under ZMK + Check Value + End Message delimiter + Message Trailer """ clearKey = genRandomKey(Configure.CFG_KEY_LENGTH / 2) keyType = Configure.KeyTypeTable[cmdObj.KeyType.value] cipherKeyUnderLMK = encryptKeyUnderLMK(keyType, clearKey, cmdObj.KeySchemeLMK.value) if cmdObj.Mode.value == '1': ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value), cmdObj.ZMK.scheme) zmkScheme = KeyScheme(ZMK, cmdObj.KeySchemeZMK.value) cipherKeyUnderZMK = zmkScheme.encrypt(clearKey) key = KeyScheme(clearKey) kcv = hexlify(key.encrypt("\0\0\0\0\0\0\0\0")).upper() respObj = CommandObj() respObj.ResponseCode = DataVariable('00') respObj.KeyUnderLMK = KeyVariable( hexlify(cipherKeyUnderLMK).upper(), cmdObj.KeySchemeLMK.value) if cmdObj.Mode.value == '1': respObj.KeyUnderZMK = KeyVariable( hexlify(cipherKeyUnderZMK).upper(), cmdObj.KeySchemeZMK.value) else: respObj.KeyUnderZMK = DataVariable('') respObj.CheckValue = DataVariable(kcv[:6]) return respObj
def GenCardInfo(mp, cardno, expiry, offset): keyConfig = GetKeyConfig(cardno) AccountNumber = cardno[-13:-1] # generate pin command = mp.command_hash['EE'] obj = Command.CommandObj() obj.MessageHeader = ' ' obj.Code = DataVariable('EE') obj.PVK = KeyVariable(keyConfig.PVK) obj.Offset = DataVariable(offset[:6] + 'FFFFFF') obj.CheckLength = DataVariable('06') obj.AccountNumber = DataVariable(AccountNumber) obj.DecimalizationTable = DataVariable('1234567890123456') obj.PINValidationData = DataVariable(AccountNumber[:-1] + 'N') message = command.pack(obj) # print message resp = mp.ProcessMessage(message) # print resp command = mp.command_hash['EF'] pinResp = command.unpack(resp) # print pinResp.PIN command = mp.command_hash['NG'] obj = Command.CommandObj() obj.MessageHeader = ' ' obj.Code = DataVariable('NG') obj.PIN = pinResp.PIN obj.AccountNumber = DataVariable(AccountNumber) message = command.pack(obj) # print message resp = mp.ProcessMessage(message) command = mp.command_hash['NH'] # print resp pinResp = command.unpack(resp) # generate cvv command = mp.command_hash['CW'] obj = Command.CommandObj() obj.MessageHeader = ' ' obj.Code = DataVariable('CW') obj.CVK_AB = KeyVariable(keyConfig.CVK_A + keyConfig.CVK_B) obj.PrimaryAccountNumber = DataVariable(cardno + ';') obj.ExpirationDate = DataVariable(expiry) obj.ServiceCode = DataVariable('106') message = command.pack(obj) # print message resp = mp.ProcessMessage(message) # print resp command = mp.command_hash['CX'] cvvResp = command.unpack(resp) # print cvvResp.CVV return (pinResp.PIN, cvvResp.CVV)
def command_FE(cmdObj): """ Translate a TMK, TPK or PVK from encryption under the LMK to encryption under a ZMK. """ """ Command Pattern: request: Message header + 'FE' + ZMK + TMK_TPK_PVK + Atalla Variant + Delimiter + Key Scheme ZMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer response: Message header + 'FF' + Error code + TMK_TPK_PVK + Check Value + End Message delimiter + Message Trailer """ (schemeZMK, schemeLMK, kcvLength) = extractKeySchemeAndKcvLength(cmdObj) ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value), cmdObj.ZMK.scheme) clearTMK_TPK_PVK = decryptKeyUnderLMK('PVK', unhexlify(cmdObj.TMK_TPK_PVK.value), cmdObj.TMK_TPK_PVK.scheme) zmkScheme = KeyScheme(ZMK, schemeZMK) cipherTMK_TPK_PVK = zmkScheme.encrypt(clearTMK_TPK_PVK) tmk_tpk_pvk = KeyScheme(clearTMK_TPK_PVK) kcv = hexlify(tmk_tpk_pvk.encrypt("\0\0\0\0\0\0\0\0")).upper() respObj = CommandObj() respObj.ResponseCode = DataVariable('00') respObj.TMK_TPK_PVK = KeyVariable( hexlify(cipherTMK_TPK_PVK).upper(), schemeZMK) respObj.CheckValue = DataVariable(kcv[:kcvLength]) return respObj
def command_MI(cmdObj): """ Translate a TAK from encryption under a ZMK to encryption under the LMK. Used to receive a key from another party. """ """ Command Pattern: request: Message header + 'MI' + ZMK + TAK + Atalla Variant + Delimiter + Key Scheme ZMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer response: Message header + 'MJ' + Error code + TAK + Check Value + End Message delimiter + Message Trailer """ (schemeZMK, schemeLMK, kcvLength) = extractKeySchemeAndKcvLength(cmdObj) ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value), cmdObj.ZMK.scheme) takScheme = KeyScheme(ZMK, cmdObj.TAK.scheme) clearTAK = takScheme.decrypt(unhexlify(cmdObj.TAK.value)) cipherTAK = encryptKeyUnderLMK('TAK', clearTAK, schemeLMK) tak = KeyScheme(clearTAK) kcv = hexlify(tak.encrypt("\0\0\0\0\0\0\0\0")).upper() respObj = CommandObj() respObj.ResponseCode = DataVariable('00') respObj.TAK = KeyVariable(hexlify(cipherTAK).upper(), schemeLMK) respObj.CheckValue = DataVariable(kcv[:kcvLength]) return respObj
def command_GC(cmdObj): """ Translate a ZPK from encryption under the LMK to encryption under a ZMK. Used to transmit a ZPK to another party. """ """ Command Pattern: request: Message header + 'GC' + ZMK + ZPK + Atalla Variant + Delimiter + Key Scheme ZMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer response: Message header + 'GD' + Error code + ZPK + Check Value + End Message delimiter + Message Trailer """ (schemeZMK, schemeLMK, kcvLength) = extractKeySchemeAndKcvLength(cmdObj) ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value), cmdObj.ZMK.scheme) clearZPK = decryptKeyUnderLMK('ZPK', unhexlify(cmdObj.ZPK.value), cmdObj.ZPK.scheme) zmkScheme = KeyScheme(ZMK, schemeZMK) cipherZPK = zmkScheme.encrypt(clearZPK) zpk = KeyScheme(clearZPK) kcv = hexlify(zpk.encrypt("\0\0\0\0\0\0\0\0")).upper() respObj = CommandObj() respObj.ResponseCode = DataVariable('00') respObj.ZPK = KeyVariable(hexlify(cipherZPK).upper(), schemeZMK) respObj.CheckValue = DataVariable(kcv[:kcvLength]) return respObj
def command_A6(cmdObj): """ To import a key encrypted under a ZMK. """ """ Command Pattern: request: Message header + 'A6' + Key Type + ZMK + Key + Key Scheme LMK + Atalla Variant + End message delimiter + Message Trailer response: Message header + 'A7' + Error code + Key + Check Value + End Message delimiter + Message Trailer """ ZMK = decryptKeyUnderLMK('ZMK', unhexlify(cmdObj.ZMK.value), cmdObj.ZMK.scheme) keyScheme = KeyScheme(ZMK, cmdObj.Key.scheme) clearKey = keyScheme.decrypt(unhexlify(cmdObj.Key.value)) keyType = Configure.KeyTypeTable[cmdObj.KeyType.value] cipherKey = encryptKeyUnderLMK(keyType, clearKey, cmdObj.KeySchemeLMK.value) key = KeyScheme(clearKey) kcv = hexlify(key.encrypt("\0\0\0\0\0\0\0\0")).upper() respObj = CommandObj() respObj.ResponseCode = DataVariable('00') respObj.Key = KeyVariable( hexlify(cipherKey).upper(), cmdObj.KeySchemeLMK.value) respObj.CheckValue = DataVariable(kcv[:6]) return respObj
def command_AG(cmdObj): """ Translate a TAK from encryption under the LMK to encryption under a TMK. Used to send a key to a terminal. """ """ Command Pattern: request: Message header + 'AG' + TMK + TAK + Atalla Variant + Delimiter + Key Scheme TMK + Key Scheme LMK + Key Check Value Type + End message delimiter + Message Trailer response: Message header + 'AH' + Error code + TAK + Check Value + End Message delimiter + Message Trailer """ (schemeTMK, schemeLMK, kcvLength) = extractTMKSchemeAndKcvLength(cmdObj) TMK = decryptKeyUnderLMK('TMK', unhexlify(cmdObj.TMK.value), cmdObj.TMK.scheme) clearTAK = decryptKeyUnderLMK('TAK', unhexlify(cmdObj.TAK.value), cmdObj.TAK.scheme) tmkScheme = KeyScheme(TMK, schemeTMK) cipherTAK = tmkScheme.encrypt(clearTAK) tak = KeyScheme(clearTAK) kcv = hexlify(tak.encrypt("\0\0\0\0\0\0\0\0")).upper() respObj = CommandObj() respObj.ResponseCode = DataVariable('00') respObj.TAK = KeyVariable(hexlify(cipherTAK).upper(), schemeTMK) respObj.CheckValue = DataVariable(kcv[:kcvLength]) return respObj