示例#1
0
    def external_authenticate(self, p1, p2, resp_data):
        """Performs the basic access control protocol as defined in
        the ICAO MRTD standard"""
        rnd_icc = self.last_challenge

        # Receive Mutual Authenticate APDU from terminal
        # Decrypt data and check MAC
        Eifd = resp_data[:-8]
        padded_Eifd = vsCrypto.append_padding(self.current_SE.cct.blocklength,
                                              Eifd)
        Mifd = vsCrypto.crypto_checksum("CC", self.KMac, padded_Eifd)
        # Check the MAC
        if not Mifd == resp_data[-8:]:
            raise SwError(SW["ERR_SECMESSOBJECTSINCORRECT"])
        # Decrypt the data
        plain = vsCrypto.decrypt("DES3-CBC", self.KEnc, resp_data[:-8])
        if plain[8:16] != rnd_icc:
            raise SwError(SW["WARN_NOINFO63"])
        # Extract keying material from IFD, generate ICC keying material
        Kifd = plain[16:]
        rnd_ifd = plain[:8]
        Kicc = urandom(16)
        # Generate Answer
        data = plain[8:16] + plain[:8] + Kicc
        Eicc = vsCrypto.encrypt("DES3-CBC", self.KEnc, data)
        padded_Eicc = vsCrypto.append_padding(self.current_SE.cct.blocklength,
                                              Eicc)
        Micc = vsCrypto.crypto_checksum("CC", self.KMac, padded_Eicc)
        # Derive the final keys and set the current SE
        KSseed = vsCrypto.operation_on_string(Kicc, Kifd, lambda a, b: a ^ b)
        self.current_SE.ct.key = self.derive_key(KSseed, 1)
        self.current_SE.cct.key = self.derive_key(KSseed, 2)
        self.current_SE.ssc = stringtoint(rnd_icc[-4:] + rnd_ifd[-4:])
        return SW["NORMAL"], Eicc + Micc
示例#2
0
    def verify_cryptographic_checksum(self, p1, p2, data):
        """
        Verify the cryptographic checksum contained in the data field.
        Data field must contain a cryptographic checksum (tag 0x8E) and a plain
        value (tag 0x80)
        """
        plain = ""
        cct = ""

        algo = self.cct.algorithm
        key = self.cct.key
        iv = self.cct.iv
        if algo == None or key == None:
            raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])

        structure = unpack(data)
        for tag, length, value in structure:
            if tag == 0x80:
                plain = value
            elif tag == 0x8E:
                cct = value
        if plain == "" or cct == "":
            raise SwError(SW["ERR_SECMESSOBJECTSMISSING"])
        else:
            my_cct = vsCrypto.crypto_checksum(algo, key, plain, iv)
            if my_cct == cct:
                return ""
            else:
                raise SwError["ERR_SECMESSOBJECTSINCORRECT"]
示例#3
0
    def verify_cryptographic_checksum(self, p1, p2, data):
        """
        Verify the cryptographic checksum contained in the data field.
        Data field must contain a cryptographic checksum (tag 0x8E) and a plain
        value (tag 0x80)
        """
        plain = ""
        cct = ""

        algo = self.cct.algorithm
        key = self.cct.key
        iv = self.cct.iv
        if algo == None or key == None:
            raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])

        structure = unpack(data)
        for tag, length, value in structure:
            if tag == 0x80:
                plain = value
            elif tag == 0x8E:
                cct = value
        if plain == "" or cct == "":
            raise SwError(SW["ERR_SECMESSOBJECTSMISSING"])
        else:
            my_cct = vsCrypto.crypto_checksum(algo, key, plain, iv)
            if my_cct == cct:
                return ""
            else:
                raise SwError["ERR_SECMESSOBJECTSINCORRECT"]
示例#4
0
    def compute_cryptographic_checksum(self, p1, p2, data):
        """
        Compute a cryptographic checksum (e.g. MAC) for the given data.
        Algorithm and key are specified in the current SE
        """
        if p1 != 0x8E or p2 != 0x80:
            raise SwError(SW["ERR_INCORRECTP1P2"])
        if self.cct.key is None:
            raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])

        checksum = vsCrypto.crypto_checksum(self.cct.algorithm, self.cct.key, data, self.cct.iv)
        return checksum
示例#5
0
    def compute_cryptographic_checksum(self, p1, p2, data):
        """
        Compute a cryptographic checksum (e.g. MAC) for the given data.
        Algorithm and key are specified in the current SE
        """
        if p1 != 0x8E or p2 != 0x80:
            raise SwError(SW["ERR_INCORRECTP1P2"])
        if self.cct.key == None:
            raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])

        checksum = vsCrypto.crypto_checksum(self.cct.algorithm, self.cct.key,
                                            data, self.cct.iv)
        return checksum
示例#6
0
    def compute_cryptographic_checksum(self, p1, p2, data):
        """
        Compute a cryptographic checksum (e.g. MAC) for the given data.
        The ePass uses a Send Sequence Counter for MAC calculation
        """
        if p1 != 0x8E or p2 != 0x80:
            raise SwError(SW["ERR_INCORRECTP1P2"])

        self.ssc += 1
        checksum = vsCrypto.crypto_checksum(self.cct.algorithm, self.cct.key,
                                            data, self.cct.iv, self.ssc)

        return checksum