Example #1
0
 def _padAndEncryptData(self, apdu):
     """ Pad the data, encrypt data with KSenc and build DO'87"""
     tdes = DES3.new(self._ksenc, DES.MODE_CBC, b'\0' * 8)
     paddedData = pad(hexRepToBin(apdu.getData()))
     enc = tdes.encrypt(paddedData)
     self.log("Pad data")
     self.log("\tData: " + binToHexRep(paddedData))
     self.log("Encrypt data with KSenc")
     self.log("\tEncryptedData: " + binToHexRep(enc))
     return enc
 def _padAndEncryptData(self, apdu):
     """ Pad the data, encrypt data with KSenc and build DO'87"""
     tdes= DES3.new(self._ksenc,DES.MODE_CBC, b'\x00\x00\x00\x00\x00\x00\x00\x00')
     paddedData = pad( hexRepToBin(apdu.getData()))
     enc = tdes.encrypt( paddedData )
     self.log("Pad data")
     self.log("\tData: " + binToHexRep(paddedData))
     self.log("Encrypt data with KSenc")
     self.log("\tEncryptedData: " + binToHexRep(enc))
     return enc
Example #3
0
    def createMAC(self):
        try:
            m = iso9797.mac(hexRepToBin(self.field2Form.get()), iso9797.pad(hexRepToBin(self.field1Form.get())))

            self.writeToLog("MAC:\n  message: {0}\n  Key: {1}\n  MAC: {2}".format(self.field1Form.get(),
                                                                          self.field2Form.get(),
                                                                          binToHexRep(m)))

            self.field1Form.delete(0, END)
            self.field2Form.delete(0, END)
            self.field1Form.insert(0, binToHexRep(m))
        except Exception, msg:
            tkMessageBox.showerror("Error: BAC", str(msg))
    def protect(self, apdu):
        """
        Protect the apdu following the doc9303 specification
        """

        cmdHeader = self._maskClassAndPad(apdu)
        do87 = ""
        do97 = ""

        tmp = "Concatenate CmdHeader"
        if(apdu.getData()):
            tmp += " and DO87"
            do87 = self._buildD087(apdu)
        if(apdu.getLe()):
            tmp += " and DO97"
            do97 = self._buildD097(apdu)

        M = cmdHeader + do87 + do97
        self.log(tmp)
        self.log("\tM: " + binToHexRep(M))

        self._ssc = self._incSSC()
        self.log("Compute MAC of M")
        self.log("\tIncrement SSC with 1")
        self.log("\t\tSSC: " + binToHexRep(self._ssc))


        N = pad(self._ssc + M)
        self.log("\tConcateate SSC and M and add padding")
        self.log("\t\tN: " + binToHexRep(N))


        CC = mac(self._ksmac, N)
        self.log("\tCompute MAC over N with KSmac")
        self.log("\t\tCC: " + binToHexRep(CC))

        do8e = self._buildD08E(CC)
        size = str(len(do87) + len(do97) + len(do8e))
        protectedAPDU = cmdHeader[:4] + intToBin(size) + do87 + do97 + do8e + hexToBin(0x00)

        self.log("Construct and send protected APDU")
        self.log("\tProtectedAPDU: " + binToHexRep(protectedAPDU))

        return CommandAPDU(binToHexRep(protectedAPDU[0]),
                    binToHexRep(protectedAPDU[1]),
                    binToHexRep(protectedAPDU[2]),
                    binToHexRep(protectedAPDU[3]),
                    binToHexRep(protectedAPDU[4]),
                    binToHexRep(protectedAPDU[5:-1]),
                    binToHexRep(protectedAPDU[-1]))
Example #5
0
    def protect(self, apdu):
        """
        Protect the apdu following the doc9303 specification
        """

        cmdHeader = self._maskClassAndPad(apdu)
        do87 = b""
        do97 = b""

        tmp = "Concatenate CmdHeader"
        if (apdu.getData()):
            tmp += " and DO87"
            do87 = self._buildD087(apdu)
        if (apdu.getLe()):
            tmp += " and DO97"
            do97 = self._buildD097(apdu)

        M = cmdHeader + do87 + do97
        self.log(tmp)
        self.log("\tM: " + binToHexRep(M))

        self._ssc = self._incSSC()
        self.log("Compute MAC of M")
        self.log("\tIncrement SSC with 1")
        self.log("\t\tSSC: " + binToHexRep(self._ssc))

        N = pad(self._ssc + M)
        self.log("\tConcateate SSC and M and add padding")
        self.log("\t\tN: " + binToHexRep(N))

        CC = mac(self._ksmac, N)
        self.log("\tCompute MAC over N with KSmac")
        self.log("\t\tCC: " + binToHexRep(CC))

        do8e = self._buildD08E(CC)
        size = str(len(do87) + len(do97) + len(do8e))
        protectedAPDU = cmdHeader[:4] + intToBin(
            size) + do87 + do97 + do8e + hexToBin(0x00)

        self.log("Construct and send protected APDU")
        self.log("\tProtectedAPDU: " + binToHexRep(protectedAPDU))

        return CommandAPDU(binToHexRep(protectedAPDU[0]),
                           binToHexRep(protectedAPDU[1]),
                           binToHexRep(protectedAPDU[2]),
                           binToHexRep(protectedAPDU[3]),
                           binToHexRep(protectedAPDU[4]),
                           binToHexRep(protectedAPDU[5:-1]),
                           binToHexRep(protectedAPDU[-1]))
Example #6
0
    def createMAC(self):
        try:
            m = iso9797.mac(hexRepToBin(self.field2Form.get()),
                            iso9797.pad(hexRepToBin(self.field1Form.get())))

            self.writeToLog(
                "MAC:\n  message: {0}\n  Key: {1}\n  MAC: {2}".format(
                    self.field1Form.get(), self.field2Form.get(),
                    binToHexRep(m)))

            self.field1Form.delete(0, END)
            self.field2Form.delete(0, END)
            self.field1Form.insert(0, binToHexRep(m))
        except Exception, msg:
            tkMessageBox.showerror("Error: BAC", str(msg))
 def _maskClassAndPad(self, apdu):
     self.log("Mask class byte and pad command header")
     res = pad( hexRepToBin("0C" + apdu.getIns() + apdu.getP1() + apdu.getP2() ))
     self.log("\tCmdHeader: " + binToHexRep(res))
     return res
    def unprotect(self, rapdu):
        """
        Unprotect the APDU following the iso7816 specification
        """
        needCC = False
        do87 = ""
        do87Data = None
        do99 = ""
        do8e = ""
        offset = 0

        #Check for a SM error
        if(rapdu.sw1 != 0x90 or rapdu.sw2 != 0x00):
            return rapdu

        rapdu = rapdu.getBinAPDU()

        self.log("Receive response APDU of MRTD's chip")
        self.log("\tRAPDU: " + binToHexRep(rapdu))

        #DO'87'
        #Mandatory if data is returned, otherwise absent
        if rapdu[0] == hexRepToBin("87"):
            (encDataLength, o) = asn1Length(rapdu[1:])
            offset = 1 + o

            if rapdu[offset] != hexRepToBin("01"):
                raise SecureMessagingException, "DO87 malformed, must be 87 L 01 <encdata> : " + binToHexRep(rapdu)

            do87 = rapdu[0:offset+encDataLength]
            do87Data = rapdu[offset+1:offset+encDataLength]
            offset += encDataLength
            needCC = True

        #DO'99'
        #Mandatory, only absent if SM error occurs
        do99 = rapdu[offset:offset+4]
        sw1 = rapdu[offset+2]
        sw2 = rapdu[offset+3]
        offset += 4
        needCC = True

        if do99[0:2] != hexRepToBin("9902"):
            #SM error, return the error code
            return ResponseAPDU([], sw1, sw2)

        #DO'8E'
        #Mandatory id DO'87' and/or DO'99' is present
        if rapdu[offset] == hexRepToBin("8E"):
            ccLength = binToHex(rapdu[offset+1])
            CC = rapdu[offset+2:offset+2+ccLength]
            do8e = rapdu[offset:offset+2+ccLength]

            #CheckCC

            tmp = ""
            if do87:
                tmp += " DO'87"
            if do99:
                tmp += " DO'99"
            self.log("Verify RAPDU CC by computing MAC of" + tmp)

            self._ssc = self._incSSC()
            self.log("\tIncrement SSC with 1")
            self.log("\t\tSSC: " + binToHexRep(self._ssc))

            K = pad(self._ssc + do87 + do99)
            self.log("\tConcatenate SSC and" + tmp + " and add padding")
            self.log("\t\tK: " + binToHexRep(K))

            self.log("\tCompute MAC with KSmac")
            CCb = mac(self._ksmac, K)
            self.log("\t\tCC: " + binToHexRep(CCb))

            res = (CC == CCb)
            self.log("\tCompare CC with data of DO'8E of RAPDU")
            self.log("\t\t" + binToHexRep(CC) + " == " + binToHexRep(CCb) + " ? " + str(res))

            if not res:
                raise SecureMessagingException, "Invalid checksum for the rapdu : " + str(binToHex(rapdu))

        elif needCC:
            raise SecureMessagingException, "Mandatory id DO'87' and/or DO'99' is present"

        data = []
        if(do87Data):
            #There is a payload
            tdes= DES3.new(self._ksenc,DES.MODE_CBC, b'\x00\x00\x00\x00\x00\x00\x00\x00')
            data = unpad(tdes.decrypt(do87Data))
            self.log("Decrypt data of DO'87 with KSenc")
            self.log("\tDecryptedData: " + binToHexRep(data))

        self.log("Unprotected APDU: [" + binToHexRep(data) + "] " + binToHexRep(sw1) + " " + binToHexRep(sw2))
        return ResponseAPDU(data, binToHex(sw1), binToHex(sw2))
Example #9
0
 def _maskClassAndPad(self, apdu):
     self.log("Mask class byte and pad command header")
     res = pad(
         hexRepToBin("0C" + apdu.getIns() + apdu.getP1() + apdu.getP2()))
     self.log("\tCmdHeader: " + binToHexRep(res))
     return res
Example #10
0
    def unprotect(self, rapdu):
        """
        Unprotect the APDU following the iso7816 specification
        """
        needCC = False
        do87 = b""
        do87Data = None
        do99 = b""
        do8e = b""
        offset = 0

        #Check for a SM error
        if (rapdu.sw1 != 0x90 or rapdu.sw2 != 0x00):
            return rapdu

        rapdu = rapdu.getBinAPDU()
        self.log(rapdu)
        self.log("Receive response APDU of MRTD's chip")
        self.log("\tRAPDU: " + binToHexRep(rapdu))

        #DO'87'
        #Mandatory if data is returned, otherwise absent
        if rapdu[0] == 0x87:
            (encDataLength, o) = asn1Length(rapdu[1:])
            offset = 1 + o

            if rapdu[offset] != 0x1:
                raise SecureMessagingException(
                    "DO87 malformed, must be 87 L 01 <encdata> : " +
                    binToHexRep(rapdu))

            do87 = rapdu[0:offset + encDataLength]
            do87Data = rapdu[offset + 1:offset + encDataLength]
            offset += encDataLength
            needCC = True

        #DO'99'
        #Mandatory, only absent if SM error occurs
        do99 = rapdu[offset:offset + 4]
        sw1 = rapdu[offset + 2]
        sw2 = rapdu[offset + 3]
        offset += 4
        needCC = True
        # removed hexRepToBin("9902"):
        if do99[0:2] != b"\x99\x02":
            #SM error, return the error code
            return ResponseAPDU([], sw1, sw2)

        self.log(rapdu[offset])
        #DO'8E'
        #Mandatory if DO'87' and/or DO'99' is present
        if rapdu[offset] == 0x8E:
            ccLength = binToHex(rapdu[offset + 1])
            CC = rapdu[offset + 2:offset + 2 + ccLength]
            do8e = rapdu[offset:offset + 2 + ccLength]

            #CheckCC

            tmp = ""
            if do87:
                tmp += " DO'87"
            if do99:
                tmp += " DO'99"
            self.log("Verify RAPDU CC by computing MAC of" + tmp)

            self._ssc = self._incSSC()
            self.log("\tIncrement SSC with 1")
            self.log("\t\tSSC: " + binToHexRep(self._ssc))

            K = pad(self._ssc + do87 + do99)
            self.log("\tConcatenate SSC and" + tmp + " and add padding")
            self.log("\t\tK: " + binToHexRep(K))

            self.log("\tCompute MAC with KSmac")
            CCb = mac(self._ksmac, K)
            self.log("\t\tCC: " + binToHexRep(CCb))

            res = (CC == CCb)
            self.log("\tCompare CC with data of DO'8E of RAPDU")
            self.log("\t\t" + binToHexRep(CC) + " == " + binToHexRep(CCb) +
                     " ? " + str(res))

            if not res:
                raise SecureMessagingException(
                    "Invalid checksum for the rapdu : " + str(binToHex(rapdu)))

        elif needCC:
            raise SecureMessagingException(
                "Mandatory id DO'87' and/or DO'99' is present")

        data = []
        if (do87Data):
            #There is a payload
            tdes = DES3.new(self._ksenc, DES.MODE_CBC, b'\0' * 8)
            data = unpad(tdes.decrypt(do87Data))
            self.log("Decrypt data of DO'87 with KSenc")
            self.log("\tDecryptedData: " + binToHexRep(data))

        self.log("Unprotected APDU: [" + binToHexRep(data) + "] " +
                 binToHexRep(sw1) + " " + binToHexRep(sw2))
        return ResponseAPDU(data, binToHex(sw1), binToHex(sw2))