示例#1
0
    def test_find_generated_crc16(self):
        mb = MessageTypeBuilder("data")
        mb.add_label(FieldType.Function.PREAMBLE, 8)
        mb.add_label(FieldType.Function.SYNC, 16)
        mb.add_label(FieldType.Function.LENGTH, 8)
        mb.add_label(FieldType.Function.DATA, 32)
        mb.add_checksum_label(16, GenericCRC.from_standard_checksum("CRC16 CCITT"))

        mb2 = MessageTypeBuilder("data2")
        mb2.add_label(FieldType.Function.PREAMBLE, 8)
        mb2.add_label(FieldType.Function.SYNC, 16)
        mb2.add_label(FieldType.Function.LENGTH, 8)
        mb2.add_label(FieldType.Function.DATA, 16)

        mb2.add_checksum_label(16, GenericCRC.from_standard_checksum("CRC16 CCITT"))

        pg = ProtocolGenerator([mb.message_type, mb2.message_type], syncs_by_mt={mb.message_type: "0x1234", mb2.message_type: "0x1234"})

        num_messages = 5

        for i in range(num_messages):
            pg.generate_message(data="{0:032b}".format(i), message_type=mb.message_type)
            pg.generate_message(data="{0:016b}".format(i), message_type=mb2.message_type)

        #self.save_protocol("crc16_test", pg)
        self.clear_message_types(pg.protocol.messages)

        ff = FormatFinder(pg.protocol.messages)
        ff.run()

        self.assertEqual(len(ff.message_types), 2)
        for mt in ff.message_types:
            checksum_label = mt.get_first_label_with_type(FieldType.Function.CHECKSUM)
            self.assertEqual(checksum_label.length, 16)
            self.assertEqual(checksum_label.checksum.caption, "CRC16 CCITT")
示例#2
0
    def test_bruteforce_parameters_and_data_range_improved(self):
        c = GenericCRC(polynomial="16_ccitt",
                       start_value=False,
                       final_xor=False,
                       reverse_polynomial=False,
                       reverse_all=False,
                       lsb_first=False,
                       little_endian=False)
        inpt = "101010101010101010000000111000000000000011100000001011010010110100000000111000000101001010000100000000000100111001111110010000000011011111111001001101100001100010100000000000111011110100010"
        vrfy_crc = "0011101111010001"

        t1 = 0
        runs = 100
        for i in range(0, runs):
            t = time.time()
            result = c.bruteforce_parameters_and_data_range(
                c.str2arr(inpt),
                len(inpt) - len(vrfy_crc) - 1)
            t1 += time.time() - t
            # print(result, c.bit2str(c.crc(c.str2arr(inpt[result[1]:result[2]]))))
            self.assertEqual(result[0], 2)  # Parameters = 2
            self.assertEqual(result[1],
                             len(inpt) - 1 - 16 - 88)  # start of datarange
            self.assertEqual(result[2], len(inpt) - 1 - 16)  # end of datarange
            inpt = "0" + inpt if i % 2 == 0 else "1" + inpt
        # print("Performance:", t1/runs)
        self.assertLess(t1 / runs,
                        0.1)  # Should be faster than 100ms in average
    def test_configure_crc_parameters(self):
        crc_label = ChecksumLabel("crc_label", 25, 120, 0, FieldType("crc", FieldType.Function.CHECKSUM))

        crc_widget_controller = ChecksumWidgetController(crc_label, Message([0] * 150, 0, MessageType("test")), 0)

        crc = GenericCRC(polynomial=list(GenericCRC.DEFAULT_POLYNOMIALS.keys())[0])
        self.assertEqual(crc_widget_controller.ui.lineEditCRCPolynomial.text(), crc.polynomial_as_hex_str)
        self.assertEqual(crc_widget_controller.ui.lineEditStartValue.text(), util.bit2hex(crc.start_value))
        self.assertEqual(crc_widget_controller.ui.lineEditFinalXOR.text(), util.bit2hex(crc.final_xor))

        crc_widget_controller.ui.comboBoxCRCFunction.setCurrentIndex(2)
        crc.polynomial = crc.choose_polynomial(2)
        self.assertEqual(crc_widget_controller.ui.lineEditCRCPolynomial.text(), crc.polynomial_as_hex_str)

        crc_widget_controller.ui.lineEditCRCPolynomial.setText("abcde")
        crc_widget_controller.ui.lineEditCRCPolynomial.editingFinished.emit()
        self.assertEqual(crc_label.checksum.polynomial, array.array("B", [1]) + util.hex2bit("abcde"))

        crc_widget_controller.ui.lineEditStartValue.setText("12345")
        crc_widget_controller.ui.lineEditStartValue.editingFinished.emit()
        self.assertEqual(util.bit2hex(crc_label.checksum.start_value), "12345")

        crc_widget_controller.ui.lineEditFinalXOR.setText("cccaa")
        crc_widget_controller.ui.lineEditFinalXOR.editingFinished.emit()
        self.assertEqual(util.bit2hex(crc_label.checksum.final_xor), "cccaa")
示例#4
0
    def test_configure_crc_parameters(self):
        crc_label = ChecksumLabel(
            "crc_label", 25, 120, 0,
            FieldType("crc", FieldType.Function.CHECKSUM))

        crc_widget_controller = ChecksumWidgetController(
            crc_label, Message([0] * 150, 0, MessageType("test")), 0)

        crc = GenericCRC(
            polynomial=list(GenericCRC.DEFAULT_POLYNOMIALS.keys())[0])
        self.assertEqual(crc_widget_controller.ui.lineEditCRCPolynomial.text(),
                         crc.polynomial_as_hex_str)
        self.assertEqual(crc_widget_controller.ui.lineEditStartValue.text(),
                         util.bit2hex(crc.start_value))
        self.assertEqual(crc_widget_controller.ui.lineEditFinalXOR.text(),
                         util.bit2hex(crc.final_xor))

        crc_widget_controller.ui.comboBoxCRCFunction.setCurrentIndex(2)
        crc.polynomial = crc.choose_polynomial(2)
        self.assertEqual(crc_widget_controller.ui.lineEditCRCPolynomial.text(),
                         crc.polynomial_as_hex_str)

        crc_widget_controller.ui.lineEditCRCPolynomial.setText("abcde")
        crc_widget_controller.ui.lineEditCRCPolynomial.editingFinished.emit()
        self.assertEqual(crc_label.checksum.polynomial,
                         array.array("B", [1]) + util.hex2bit("abcde"))

        crc_widget_controller.ui.lineEditStartValue.setText("12345")
        crc_widget_controller.ui.lineEditStartValue.editingFinished.emit()
        self.assertEqual(util.bit2hex(crc_label.checksum.start_value), "12345")

        crc_widget_controller.ui.lineEditFinalXOR.setText("cccaa")
        crc_widget_controller.ui.lineEditFinalXOR.editingFinished.emit()
        self.assertEqual(util.bit2hex(crc_label.checksum.final_xor), "cccaa")
示例#5
0
    def test_crc(self):
        # http://depa.usst.edu.cn/chenjq/www2/software/crc/CRC_Javascript/CRCcalculation.htm
        # CRC-16: polynomial="16_standard", start_value = False, final_xor = False, reverse_polynomial=False, reverse_all=False
        # CRC-16-CCITT: polynomial="16_ccitt", start_value = False, final_xor = False, reverse_polynomial=False, reverse_all=False

        # http://www.lammertbies.nl/comm/info/crc-calculation.html <- Fehler
        # CRC-16: polynomial="16_standard", start_value = False, final_xor = False, reverse_polynomial=False, reverse_all=False
        c = GenericCRC(polynomial=WSPChecksum.CRC_8_POLYNOMIAL)
        e = Encoding()

        bitstr = [
            "010101010110100111011010111011101110111011100110001011101010001011101110110110101101",
            "010101010110101001101110111011101110111011100110001011101010001011101110110111100101",
            "010101010110100111010010111011101110111011100110001011101010001011101110110110100101"
        ]

        expected = ["78", "c9", "f2"]

        for value, expect in zip(bitstr, expected):
            nv = ""
            for i in range(0, len(value)):
                if value[i] == "1":
                    nv += "0"
                else:
                    nv += "1"

            self.assertEqual(util.bit2hex(c.crc(e.str2bit(value[4:-8]))),
                             expect)
示例#6
0
    def test_crc(self):
        # http://depa.usst.edu.cn/chenjq/www2/software/crc/CRC_Javascript/CRCcalculation.htm
        # CRC-16: polynomial="16_standard", start_value = False, final_xor = False, reverse_polynomial=False, reverse_all=False
        # CRC-16-CCITT: polynomial="16_ccitt", start_value = False, final_xor = False, reverse_polynomial=False, reverse_all=False

        # http://www.lammertbies.nl/comm/info/crc-calculation.html <- Fehler
        # CRC-16: polynomial="16_standard", start_value = False, final_xor = False, reverse_polynomial=False, reverse_all=False
        c = GenericCRC(polynomial=WSPChecksum.CRC_8_POLYNOMIAL)
        e = Encoding()

        bitstr = ["010101010110100111011010111011101110111011100110001011101010001011101110110110101101",
                  "010101010110101001101110111011101110111011100110001011101010001011101110110111100101",
                  "010101010110100111010010111011101110111011100110001011101010001011101110110110100101"]

        expected = ["78", "c9", "f2"]

        for value, expect in zip(bitstr, expected):
            nv = ""
            for i in range(0, len(value)):
                if value[i] == "1":
                    nv += "0"
                else:
                    nv += "1"

            self.assertEqual(util.bit2hex(c.crc(e.str2bit(value[4:-8]))), expect)
示例#7
0
    def test_crc8(self):
        messages = ["aabbcc", "abcdee", "dacafe"]

        expected = ["7d", "24", "33"]
        crc = GenericCRC(polynomial=GenericCRC.DEFAULT_POLYNOMIALS["8_ccitt"])

        for msg, expect in zip(messages, expected):
            bits = util.hex2bit(msg)
            self.assertEqual(util.bit2hex(crc.crc(bits)), expect)
示例#8
0
 def test_cache(self):
     c = GenericCRC(polynomial="16_standard",
                    start_value=False,
                    final_xor=False,
                    reverse_polynomial=False,
                    reverse_all=False,
                    lsb_first=False,
                    little_endian=False)
     c.calculate_cache(8)
     self.assertEqual(len(c.cache), 256)
示例#9
0
    def test_find_crc8(self):
        messages = ["aabbcc7d", "abcdee24", "dacafe33"]
        message_bits = [np.array(msg, dtype=np.uint8) for msg in map(util.hex2bit, messages)]

        checksum_engine = ChecksumEngine(message_bits, n_gram_length=8)
        result = checksum_engine.find()
        self.assertEqual(len(result), 1)
        checksum_range = result[0]  # type: ChecksumRange
        self.assertEqual(checksum_range.length, 8)
        self.assertEqual(checksum_range.start, 24)

        reference = GenericCRC()
        reference.set_polynomial_from_hex("0x07")
        self.assertEqual(checksum_range.crc.polynomial, reference.polynomial)

        self.assertEqual(checksum_range.message_indices, {0, 1, 2})
示例#10
0
    def _prepare_protocol_3() -> ProtocolGenerator:
        alice = Participant("Alice", address_hex="1337")
        bob = Participant("Bob", address_hex="beef")

        checksum = GenericCRC.from_standard_checksum("CRC8 CCITT")

        mb = MessageTypeBuilder("data")
        mb.add_label(FieldType.Function.PREAMBLE, 16)
        mb.add_label(FieldType.Function.SYNC, 16)
        mb.add_label(FieldType.Function.LENGTH, 8)
        mb.add_label(FieldType.Function.SRC_ADDRESS, 16)
        mb.add_label(FieldType.Function.DST_ADDRESS, 16)
        mb.add_label(FieldType.Function.SEQUENCE_NUMBER, 8)
        mb.add_label(FieldType.Function.DATA, 10 * 8)
        mb.add_checksum_label(8, checksum)

        mb_ack = MessageTypeBuilder("ack")
        mb_ack.add_label(FieldType.Function.PREAMBLE, 16)
        mb_ack.add_label(FieldType.Function.SYNC, 16)
        mb_ack.add_label(FieldType.Function.LENGTH, 8)
        mb_ack.add_label(FieldType.Function.DST_ADDRESS, 16)
        mb_ack.add_checksum_label(8, checksum)

        pg = ProtocolGenerator([mb.message_type, mb_ack.message_type],
                               syncs_by_mt={
                                   mb.message_type: "0x9a7d",
                                   mb_ack.message_type: "0x9a7d"
                               },
                               preambles_by_mt={
                                   mb.message_type: "10" * 8,
                                   mb_ack.message_type: "10" * 8
                               },
                               participants=[alice, bob])

        return pg
示例#11
0
    def __set_crc_function_index(self):
        # Get the combobox index
        crc_found = False
        for crc_name in GenericCRC.DEFAULT_POLYNOMIALS:
            test_crc = GenericCRC(crc_name)
            if test_crc == self.checksum_label.checksum:
                self.ui.comboBoxCRCFunction.setCurrentText(crc_name)
                crc_found = True
                break

        if not crc_found:
            for crc_name, crc in self.SPECIAL_CRCS.items():
                if self.checksum_label.checksum == crc:
                    self.ui.comboBoxCRCFunction.setCurrentText(crc_name)
                    crc_found = True
                    break

        if not crc_found:
            self.__add_and_select_custom_item()
        elif "Custom" in [
                self.ui.comboBoxCRCFunction.itemText(i)
                for i in range(self.ui.comboBoxCRCFunction.count())
        ]:
            self.ui.comboBoxCRCFunction.removeItem(
                self.ui.comboBoxCRCFunction.count() - 1)
示例#12
0
    def test_find_crc16(self):
        messages = ["12345678347B", "abcdefffABBD", "cafe1337CE12"]
        message_bits = [np.array(msg, dtype=np.uint8) for msg in map(util.hex2bit, messages)]

        checksum_engine = ChecksumEngine(message_bits, n_gram_length=8)
        result = checksum_engine.find()
        self.assertEqual(len(result), 1)
        checksum_range = result[0]  # type: ChecksumRange
        self.assertEqual(checksum_range.start, 32)
        self.assertEqual(checksum_range.length, 16)

        reference = GenericCRC()
        reference.set_polynomial_from_hex("0x8005")
        self.assertEqual(checksum_range.crc.polynomial, reference.polynomial)

        self.assertEqual(checksum_range.message_indices, {0, 1, 2})
示例#13
0
    def test_find_crc32(self):
        messages = ["deadcafe5D7F3F5A", "47111337E3319242", "beefaffe0DCD0E15"]
        message_bits = [np.array(msg, dtype=np.uint8) for msg in map(util.hex2bit, messages)]

        checksum_engine = ChecksumEngine(message_bits, n_gram_length=8)
        result = checksum_engine.find()
        self.assertEqual(len(result), 1)
        checksum_range = result[0]  # type: ChecksumRange
        self.assertEqual(checksum_range.start, 32)
        self.assertEqual(checksum_range.length, 32)

        reference = GenericCRC()
        reference.set_polynomial_from_hex("0x04C11DB7")
        self.assertEqual(checksum_range.crc.polynomial, reference.polynomial)

        self.assertEqual(checksum_range.message_indices, {0, 1, 2})
示例#14
0
    def test_guess_standard_parameters_and_datarange(self):
        c = GenericCRC(polynomial="16_ccitt", start_value=False, final_xor=False,
                       reverse_polynomial=False, reverse_all=False, lsb_first=False, little_endian=False)
        inpt = "101010101010101010000000111000000000000011100000001011010010110100000000111000000101001010000100000000000100111001111110010000000011011111111001001101100001100010100000000000111011110100010"
        vrfy_crc = "0011101111010001"

        result = c.guess_standard_parameters_and_datarange(c.str2arr(inpt), c.str2arr(vrfy_crc))
        self.assertEqual(result, (2, 84, 172))
        self.assertEqual(vrfy_crc, c.bit2str(c.crc(c.str2arr(inpt[result[1]:result[2]]))))
示例#15
0
    def __init__(self, name: str, start: int, end: int, color_index: int, field_type: FieldType,
                 fuzz_created=False, auto_created=False, data_range_start=0):
        assert field_type.function == FieldType.Function.CHECKSUM
        super().__init__(name, start, end, color_index, fuzz_created, auto_created, field_type)

        self.__category = self.Category.generic
        self.__data_ranges = [[data_range_start, self.start]]  # type: list[list[int,int]]
        self.checksum = GenericCRC(polynomial=0)  # type: GenericCRC or WSPChecksum
示例#16
0
 def category(self, value: Category):
     if value != self.category:
         self.__category = value
         if self.category == self.Category.generic:
             self.checksum = GenericCRC()
         elif self.category == self.Category.wsp:
             self.checksum = WSPChecksum()
         else:
             raise ValueError("Unknown Category")
示例#17
0
    def test_reverse_engineering(self):
        c = GenericCRC(polynomial="16_standard", start_value=False, final_xor=False,
                       reverse_polynomial=False, reverse_all=False, lsb_first=False, little_endian=False)
        bitstring_set = [
            "1110001111001011100010000101010100000010110111000101100010100100111110111101100110110111011001010010001011101010",
            "1110010011001011100010000101010100000010110111000101100010100100111110111101100110110111011001010010001011101010",
            "1110010111001011100010000101010100000010110111000101100010100100111110111101100110110111011001010010001011101010",
            "1110011011001011100010000101010100000010110111000101100010100100111110111101100110110111011001010010001011101010"]
        bitset = []
        crcset = []

        for i in bitstring_set:
            tmp = c.str2bit(i)
            bitset.append(tmp)
            crcset.append(c.crc(tmp))

        # print(c.guess_standard_parameters(bitset[0], crcset[0]))
        polynomial = c.reverse_engineer_polynomial(bitset, crcset)
        if polynomial:
            self.assertEqual(c.bit2str(polynomial), "1000000000000101")
            self.assertEqual(util.bit2hex(polynomial), "8005")
示例#18
0
    def test_reverse_engineering(self):
        c = GenericCRC(polynomial="16_standard",
                       start_value=False,
                       final_xor=False,
                       reverse_polynomial=False,
                       reverse_all=False,
                       lsb_first=False,
                       little_endian=False)
        bitstring_set = [
            "1110001111001011100010000101010100000010110111000101100010100100111110111101100110110111011001010010001011101010",
            "1110010011001011100010000101010100000010110111000101100010100100111110111101100110110111011001010010001011101010",
            "1110010111001011100010000101010100000010110111000101100010100100111110111101100110110111011001010010001011101010",
            "1110011011001011100010000101010100000010110111000101100010100100111110111101100110110111011001010010001011101010"
        ]
        bitset = []
        crcset = []

        for i in bitstring_set:
            tmp = c.str2bit(i)
            bitset.append(tmp)
            crcset.append(c.crc(tmp))

        polynomial = c.reverse_engineer_polynomial(bitset, crcset)
        if polynomial:
            self.assertEqual(c.bit2str(polynomial), "1000000000000101")
            self.assertEqual(util.bit2hex(polynomial), "8005")
示例#19
0
 def test_not_aligned_data_len(self):
     c = GenericCRC(polynomial="16_standard", start_value=False, final_xor=False,
                    reverse_polynomial=False, reverse_all=False, lsb_first=False, little_endian=False)
     polynomials = ["8_standard", "16_standard", "16_ccitt", "16_dnp"]
     crcs = {"8_standard": 0xd5, "16_standard": 0x8005, "16_ccitt": 0x1021, "16_dnp": 0x3d65}
     for j in polynomials:
         c.polynomial = c.choose_polynomial(j)
         inpt = "1"
         for i in range(0, 32):
             val = c.bit2int(c.crc(c.str2bit(inpt)))
             self.assertEqual(val, crcs[j])
             inpt = "0" + inpt
示例#20
0
    def _prepare_protocol_4() -> ProtocolGenerator:
        alice = Participant("Alice", address_hex="1337")
        bob = Participant("Bob", address_hex="beef")

        checksum = GenericCRC.from_standard_checksum("CRC16 CCITT")

        mb = MessageTypeBuilder("data1")
        mb.add_label(FieldType.Function.PREAMBLE, 16)
        mb.add_label(FieldType.Function.SYNC, 16)
        mb.add_label(FieldType.Function.LENGTH, 8)
        mb.add_label(FieldType.Function.SRC_ADDRESS, 16)
        mb.add_label(FieldType.Function.DST_ADDRESS, 16)
        mb.add_label(FieldType.Function.DATA, 8 * 8)
        mb.add_checksum_label(16, checksum)

        mb2 = MessageTypeBuilder("data2")
        mb2.add_label(FieldType.Function.PREAMBLE, 16)
        mb2.add_label(FieldType.Function.SYNC, 16)
        mb2.add_label(FieldType.Function.LENGTH, 8)
        mb2.add_label(FieldType.Function.SRC_ADDRESS, 16)
        mb2.add_label(FieldType.Function.DST_ADDRESS, 16)
        mb2.add_label(FieldType.Function.DATA, 64 * 8)
        mb2.add_checksum_label(16, checksum)

        mb_ack = MessageTypeBuilder("ack")
        mb_ack.add_label(FieldType.Function.PREAMBLE, 16)
        mb_ack.add_label(FieldType.Function.SYNC, 16)
        mb_ack.add_label(FieldType.Function.LENGTH, 8)
        mb_ack.add_label(FieldType.Function.DST_ADDRESS, 16)
        mb_ack.add_checksum_label(16, checksum)

        mt1, mt2, mt3 = mb.message_type, mb2.message_type, mb_ack.message_type

        preamble = "10001000" * 2

        pg = ProtocolGenerator([mt1, mt2, mt3],
                               syncs_by_mt={
                                   mt1: "0x9a7d",
                                   mt2: "0x9a7d",
                                   mt3: "0x9a7d"
                               },
                               preambles_by_mt={
                                   mt1: preamble,
                                   mt2: preamble,
                                   mt3: preamble
                               },
                               participants=[alice, bob])

        return pg
示例#21
0
    def from_xml(cls, tag: ET.Element, field_types_by_type_id=None):
        lbl = super().from_xml(tag, field_types_by_type_id)
        result = cls.from_label(lbl)
        result.data_ranges = ast.literal_eval(tag.get("data_ranges", "[]"))
        result.category = cls.Category[tag.get("category", "generic")]

        crc_tag = tag.find("crc")
        if crc_tag is not None:
            result.checksum = GenericCRC.from_xml(crc_tag)

        wsp_tag = tag.find("wsp_checksum")
        if wsp_tag is not None:
            result.checksum = WSPChecksum.from_xml(wsp_tag)

        return result
示例#22
0
    def _prepare_protocol_7() -> ProtocolGenerator:
        alice = Participant("Alice", address_hex="313370")
        bob = Participant("Bob", address_hex="031337")
        charly = Participant("Charly", address_hex="110000")
        daniel = Participant("Daniel", address_hex="001100")
        # broadcast = Participant("Broadcast", address_hex="ff")     #TODO: Sometimes messages to broadcast

        checksum = GenericCRC.from_standard_checksum("CRC16 CC1101")

        mb = MessageTypeBuilder("data")
        mb.add_label(FieldType.Function.PREAMBLE, 16)
        mb.add_label(FieldType.Function.SYNC, 16)
        mb.add_label(FieldType.Function.LENGTH, 8)
        mb.add_label(FieldType.Function.DST_ADDRESS, 24)
        mb.add_label(FieldType.Function.SRC_ADDRESS, 24)
        mb.add_label(FieldType.Function.DATA, 8 * 8)
        mb.add_checksum_label(16, checksum)

        mb_ack = MessageTypeBuilder("ack")
        mb_ack.add_label(FieldType.Function.PREAMBLE, 8)
        mb_ack.add_label(FieldType.Function.SYNC, 16)
        mb_ack.add_label(FieldType.Function.DST_ADDRESS, 24)
        mb_ack.add_checksum_label(16, checksum)

        mb_kex = MessageTypeBuilder("kex")
        mb_kex.add_label(FieldType.Function.PREAMBLE, 24)
        mb_kex.add_label(FieldType.Function.SYNC, 16)
        mb_kex.add_label(FieldType.Function.DST_ADDRESS, 24)
        mb_kex.add_label(FieldType.Function.SRC_ADDRESS, 24)
        mb_kex.add_label(FieldType.Function.DATA, 64 * 8)
        mb_kex.add_checksum_label(16, checksum)

        pg = ProtocolGenerator(
            [mb.message_type, mb_ack.message_type, mb_kex.message_type],
            syncs_by_mt={
                mb.message_type: "0x0420",
                mb_ack.message_type: "0x2222",
                mb_kex.message_type: "0x6767"
            },
            preambles_by_mt={
                mb.message_type: "10" * 8,
                mb_ack.message_type: "10" * 4,
                mb_kex.message_type: "10" * 12
            },
            participants=[alice, bob, charly, daniel])

        return pg
示例#23
0
    def test_adaptive_crc_calculation(self):
        c = GenericCRC(polynomial="16_ccitt", start_value=False, final_xor=False,
                       reverse_polynomial=False, reverse_all=False, lsb_first=False, little_endian=False)
        inpt1 = "10101010101010"
        inpt2 = "1010101010101001"

        crc1 = c.crc(c.str2arr(inpt1))
        crc2 = c.crc(c.str2arr(inpt2))

        # Compute crc2 from crc1 in a faster way
        # Note: In general only forward direction
        delta = "01"
        c.start_value = crc1
        crcx = c.crc(c.str2arr(delta))

        self.assertEqual(crcx, crc2)
示例#24
0
    def from_xml(cls, tag: ET.Element, field_types_by_caption=None):
        lbl = super().from_xml(tag, field_types_by_caption)
        if lbl.field_type is None or lbl.field_type.function != FieldType.Function.CHECKSUM:
            checksum_field_type = next(
                (ft for ft in field_types_by_caption.values() if ft.function == FieldType.Function.CHECKSUM),
                FieldType("checksum", FieldType.Function.CHECKSUM, display_format_index=1))
            lbl.field_type = checksum_field_type
        result = cls.from_label(lbl)
        result.data_ranges = ast.literal_eval(tag.get("data_ranges", "[]"))
        result.category = cls.Category[tag.get("category", "generic")]

        crc_tag = tag.find("crc")
        if crc_tag is not None:
            result.checksum = GenericCRC.from_xml(crc_tag)

        wsp_tag = tag.find("wsp_checksum")
        if wsp_tag is not None:
            result.checksum = WSPChecksum.from_xml(wsp_tag)

        return result
示例#25
0
    def apply_data_whitening(self, decoding, inpt):
        len_sync = len(self.data_whitening_sync)
        len_polynomial = len(self.data_whitening_polynomial)
        inpt_from = 0
        inpt_to = len(inpt)

        # Crop last bit, if duplicate
        if decoding and inpt_to > 1:
            if inpt[-1] == inpt[-2]:
                inpt_to -= 1

        # # Crop last bit, if len not multiple of 8
        # if decoding and inpt_to % 8 != 0:
        #     inpt_to -= (8 - (inpt_to % 8)) % 8

        # inpt empty, polynomial or syncbytes are zero! (Shouldn't happen)
        if inpt_to < 1 or len_polynomial < 1 or len_sync < 1:
            return inpt[
                inpt_from:inpt_to], 0, self.ErrorState.MISC  # Misc Error

        # Search for whitening start position (after sync bytes)
        whitening_start_pos = inpt_from
        i = inpt_from
        while i < (inpt_to - len_sync):
            equalbits = 0
            for j in range(0, len_sync):
                if inpt[i + j] == self.data_whitening_sync[j]:
                    equalbits += 1
                else:
                    continue
            if len_sync == equalbits:
                whitening_start_pos = i + j + 1
                break
            else:
                i += 1
        # Sync not found
        if decoding and whitening_start_pos == inpt_from:
            return inpt[inpt_from:inpt_to], 0, self.ErrorState.SYNC_NOT_FOUND

        # Prepare keystream
        self.lfsr_state = array.array("B", [])
        keystream = self.lfsr(0)
        for i in range(whitening_start_pos, inpt_to, 8):
            keystream.extend(self.lfsr(8))

        # If data whitening polynomial is wrong, keystream can be less than needed. Check and exit.
        if len(keystream) < inpt_to - whitening_start_pos:
            return inpt[
                inpt_from:inpt_to], 0, self.ErrorState.MISC  # Error 31338

        # Overwrite crc16 in encoding case
        if not decoding and self.cc1101_overwrite_crc:
            # Remove additional bits
            offset = inpt_to % 8
            data_end = inpt_to - 16 - offset
            c = GenericCRC(polynomial="16_standard", start_value=True)
            crc = c.crc(inpt[whitening_start_pos:data_end])
            for i in range(0, 16):
                inpt[data_end + i] = crc[i]

        # Apply keystream (xor)
        for i in range(whitening_start_pos, inpt_to):
            inpt[i] ^= keystream[i - whitening_start_pos]

        # Duplicate last bit when encoding
        if not decoding:
            inpt += array.array("B", [inpt[-1]])
            inpt_to += 1

        return inpt[inpt_from:inpt_to], 0, self.ErrorState.SUCCESS
示例#26
0
    def test_different_crcs_fast(self):
        c = GenericCRC(polynomial="16_standard",
                       start_value=False,
                       final_xor=False,
                       reverse_polynomial=False,
                       reverse_all=False,
                       lsb_first=False,
                       little_endian=False)
        bitstring_set = [
            "10101010", "00000001", "000000010", "000000011",
            "0000000100000001",
            "101001001010101010101011101111111000000000000111101010011101011",
            "101001001010101101111010110111101010010110111010",
            "00000000000000000000000000000000100000000000000000000000000000000001111111111111",
            "1111111111111111111111111111111110111111111111111111110111111111111111110000000000"
            "1"
        ]

        for j in c.DEFAULT_POLYNOMIALS:
            c.polynomial = c.choose_polynomial(j)
            for i in bitstring_set:
                for cache in [8, 4, 7, 12, 16]:
                    c.calculate_cache(cache)
                    # Standard
                    crc_new = c.cached_crc(c.str2bit(i))
                    crc_old = c.reference_crc(c.str2bit(i))
                    self.assertEqual(crc_old, crc_new)

                    # Special final xor
                    c.final_xor = c.str2bit("0000111100001111")
                    crc_new = c.cached_crc(c.str2bit(i))
                    crc_old = c.reference_crc(c.str2bit(i))
                    self.assertEqual(crc_old, crc_new)
                    c.final_xor = [False] * 16

                    # Special start value
                    c.start_value = c.str2bit("1010101010101010")
                    crc_new = c.cached_crc(c.str2bit(i))
                    crc_old = c.reference_crc(c.str2bit(i))
                    self.assertEqual(crc_old, crc_new)
                    c.start_value = [False] * 16

                    # little_endian
                    c.little_endian = True
                    crc_new = c.cached_crc(c.str2bit(i))
                    crc_old = c.reference_crc(c.str2bit(i))
                    self.assertEqual(crc_old, crc_new)
                    c.little_endian = False

                    # reverse all
                    c.reverse_all = True
                    crc_new = c.cached_crc(c.str2bit(i))
                    crc_old = c.reference_crc(c.str2bit(i))
                    self.assertEqual(crc_old, crc_new)
                    c.reverse_all = False

                    # reverse_polynomial
                    # We need to clear the cache before and after
                    c.cache = []
                    #
                    c.reverse_polynomial = True
                    crc_new = c.cached_crc(c.str2bit(i))
                    crc_old = c.reference_crc(c.str2bit(i))
                    self.assertEqual(crc_old, crc_new)
                    c.reverse_polynomial = False
                    #
                    c.cache = []

                    # TODO: Does only work for cachesize = 8
                    # lsb_first
                    c.calculate_cache(8)
                    c.lsb_first = True
                    crc_new = c.cached_crc(c.str2bit(i))
                    crc_old = c.reference_crc(c.str2bit(i))
                    self.assertEqual(crc_old, crc_new)
                    c.lsb_first = False
示例#27
0
    def generate_homematic(cls, num_messages: int, save_protocol=True):
        mb_m_frame = MessageTypeBuilder("mframe")
        mb_c_frame = MessageTypeBuilder("cframe")
        mb_r_frame = MessageTypeBuilder("rframe")
        mb_a_frame = MessageTypeBuilder("aframe")

        participants = [
            Participant("CCU", address_hex="3927cc"),
            Participant("Switch", address_hex="3101cc")
        ]

        checksum = GenericCRC.from_standard_checksum("CRC16 CC1101")
        for mb_builder in [mb_m_frame, mb_c_frame, mb_r_frame, mb_a_frame]:
            mb_builder.add_label(FieldType.Function.PREAMBLE, 32)
            mb_builder.add_label(FieldType.Function.SYNC, 32)
            mb_builder.add_label(FieldType.Function.LENGTH, 8)
            mb_builder.add_label(FieldType.Function.SEQUENCE_NUMBER, 8)
            mb_builder.add_label(FieldType.Function.TYPE, 16)
            mb_builder.add_label(FieldType.Function.SRC_ADDRESS, 24)
            mb_builder.add_label(FieldType.Function.DST_ADDRESS, 24)
            if mb_builder.name == "mframe":
                mb_builder.add_label(FieldType.Function.DATA,
                                     16,
                                     name="command")
            elif mb_builder.name == "cframe":
                mb_builder.add_label(FieldType.Function.DATA,
                                     16 * 4,
                                     name="command+challenge+magic")
            elif mb_builder.name == "rframe":
                mb_builder.add_label(FieldType.Function.DATA,
                                     32 * 4,
                                     name="cipher")
            elif mb_builder.name == "aframe":
                mb_builder.add_label(FieldType.Function.DATA,
                                     10 * 4,
                                     name="command + auth")
            mb_builder.add_checksum_label(16, checksum)

        message_types = [
            mb_m_frame.message_type, mb_c_frame.message_type,
            mb_r_frame.message_type, mb_a_frame.message_type
        ]
        preamble = "0xaaaaaaaa"
        sync = "0xe9cae9ca"
        initial_sequence_number = 36
        pg = ProtocolGenerator(
            message_types,
            participants,
            preambles_by_mt={mt: preamble
                             for mt in message_types},
            syncs_by_mt={mt: sync
                         for mt in message_types},
            sequence_numbers={
                mt: initial_sequence_number
                for mt in message_types
            },
            message_type_codes={
                mb_m_frame.message_type: 42560,
                mb_c_frame.message_type: 40962,
                mb_r_frame.message_type: 40963,
                mb_a_frame.message_type: 32770
            })

        for i in range(num_messages):
            mt = pg.message_types[i % 4]
            data_length = mt.get_first_label_with_type(
                FieldType.Function.DATA).length
            data = "".join(
                random.choice(["0", "1"]) for _ in range(data_length))
            pg.generate_message(mt,
                                data,
                                source=pg.participants[i % 2],
                                destination=pg.participants[(i + 1) % 2])

        if save_protocol:
            cls.save_protocol("homematic", pg)

        cls.clear_message_types(pg.messages)
        return pg.protocol
示例#28
0
class ChecksumWidgetController(QWidget):
    SPECIAL_CRCS = OrderedDict([
        ("CC1101", GenericCRC(polynomial="16_standard", start_value=True)),
    ])

    class RangeTableModel(QAbstractTableModel):
        header_labels = ["Start", "End"]

        def __init__(self,
                     checksum_label: ChecksumLabel,
                     message: Message,
                     proto_view: int,
                     parent=None):
            """

            :param message:
            :type field_types: list of FieldType
            :param parent:
            """
            super().__init__(parent)
            self.checksum_label = checksum_label
            self.message = message
            self.proto_view = proto_view
            self.update()

        def update(self):
            self.beginResetModel()
            self.endResetModel()

        def columnCount(self, parent: QModelIndex = None, *args, **kwargs):
            return len(self.header_labels)

        def rowCount(self, parent: QModelIndex = None, *args, **kwargs):
            return len(self.checksum_label.data_ranges)

        def headerData(self, section, orientation, role=Qt.DisplayRole):
            if role == Qt.DisplayRole and orientation == Qt.Horizontal:
                return self.header_labels[section]
            return super().headerData(section, orientation, role)

        def data(self, index: QModelIndex, role=Qt.DisplayRole):
            if not index.isValid():
                return None

            i, j = index.row(), index.column()

            if role == Qt.DisplayRole:
                data_range = self.checksum_label.data_ranges[i]
                if j == 0:
                    return self.message.convert_index(
                        data_range[0], 0, self.proto_view, True)[0] + 1
                elif j == 1:
                    return self.message.convert_index(data_range[1], 0,
                                                      self.proto_view, True)[0]
            return None

        def setData(self, index: QModelIndex, value, role: int = ...):
            try:
                int_val = int(value)
            except ValueError:
                return False

            i, j = index.row(), index.column()

            if i > len(self.checksum_label.data_ranges):
                return False

            data_range = self.checksum_label.data_ranges[i]

            if j == 0:
                converted_index = self.message.convert_index(
                    int_val - 1, self.proto_view, 0, True)[0]
                if converted_index < data_range[1]:
                    data_range[0] = converted_index
            elif j == 1:
                converted_index = self.message.convert_index(
                    int_val, self.proto_view, 0, True)[0]
                if converted_index > data_range[0]:
                    data_range[1] = converted_index

            return True

        def flags(self, index):
            if not index.isValid():
                return Qt.NoItemFlags

            try:
                _ = self.checksum_label.data_ranges[index.row()]
            except IndexError:
                return Qt.NoItemFlags

            return Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable

    def __init__(self,
                 checksum_label: ChecksumLabel,
                 message: Message,
                 proto_view: int,
                 parent=None):
        super().__init__(parent)
        self.ui = Ui_ChecksumOptions()
        self.ui.setupUi(self)
        self.checksum_label = checksum_label
        self.data_range_table_model = self.RangeTableModel(checksum_label,
                                                           message,
                                                           proto_view,
                                                           parent=self)
        self.ui.tableViewDataRanges.setItemDelegateForColumn(
            0, SpinBoxDelegate(1, 999999, self))
        self.ui.tableViewDataRanges.setItemDelegateForColumn(
            1, SpinBoxDelegate(1, 999999, self))
        self.ui.tableViewDataRanges.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)
        self.ui.tableViewDataRanges.setModel(self.data_range_table_model)
        self.ui.tableViewDataRanges.setEditTriggers(
            QAbstractItemView.AllEditTriggers)
        self.display_crc_data_ranges_in_table()
        self.ui.comboBoxCRCFunction.addItems(
            [crc_name for crc_name in GenericCRC.DEFAULT_POLYNOMIALS])
        self.ui.comboBoxCRCFunction.addItems(
            [special_crc_name for special_crc_name in self.SPECIAL_CRCS])
        self.ui.lineEditCRCPolynomial.setValidator(
            QRegExpValidator(QRegExp("[0-9,a-f]*")))
        self.ui.comboBoxCategory.clear()
        for _, member in self.checksum_label.Category.__members__.items():
            self.ui.comboBoxCategory.addItem(member.value)
        self.set_ui_for_category()
        self.setFocus()
        self.create_connects()

    @property
    def proto_view(self):
        return self.data_range_table_model.proto_view

    @proto_view.setter
    def proto_view(self, value):
        if value != self.data_range_table_model.proto_view:
            self.data_range_table_model.proto_view = value
            self.data_range_table_model.update()

    def create_connects(self):
        self.ui.comboBoxCRCFunction.currentIndexChanged.connect(
            self.on_combobox_crc_function_current_index_changed)
        self.ui.btnAddRange.clicked.connect(self.on_btn_add_range_clicked)
        self.ui.btnRemoveRange.clicked.connect(
            self.on_btn_remove_range_clicked)
        self.ui.lineEditCRCPolynomial.editingFinished.connect(
            self.on_line_edit_crc_polynomial_editing_finished)
        self.ui.lineEditStartValue.editingFinished.connect(
            self.on_line_edit_start_value_editing_finished)
        self.ui.lineEditFinalXOR.editingFinished.connect(
            self.on_line_edit_final_xor_editing_finished)
        self.ui.comboBoxCategory.currentIndexChanged.connect(
            self.on_combobox_category_current_index_changed)
        self.ui.radioButtonWSPAuto.clicked.connect(
            self.on_radio_button_wsp_auto_clicked)
        self.ui.radioButtonWSPChecksum4.clicked.connect(
            self.on_radio_button_wsp_checksum4_clicked)
        self.ui.radioButtonWSPChecksum8.clicked.connect(
            self.on_radio_button_wsp_checksum8_clicked)
        self.ui.radioButtonWSPCRC8.clicked.connect(
            self.on_radio_button_wsp_crc8_clicked)

    def set_checksum_ui_elements(self):
        if self.checksum_label.is_generic_crc:
            self.ui.lineEditCRCPolynomial.setText(
                self.checksum_label.checksum.polynomial_as_hex_str)
            self.ui.lineEditStartValue.setText(
                util.bit2hex(self.checksum_label.checksum.start_value))
            self.ui.lineEditFinalXOR.setText(
                util.bit2hex(self.checksum_label.checksum.final_xor))
            self.__ensure_same_length()
            self.__set_crc_info_label()
        elif self.checksum_label.category == self.checksum_label.Category.wsp:
            if self.checksum_label.checksum.mode == WSPChecksum.ChecksumMode.auto:
                self.ui.radioButtonWSPAuto.setChecked(True)
            elif self.checksum_label.checksum.mode == WSPChecksum.ChecksumMode.checksum4:
                self.ui.radioButtonWSPChecksum4.setChecked(True)
            elif self.checksum_label.checksum.mode == WSPChecksum.ChecksumMode.checksum8:
                self.ui.radioButtonWSPChecksum8.setChecked(True)
            elif self.checksum_label.checksum.mode == WSPChecksum.ChecksumMode.crc8:
                self.ui.radioButtonWSPCRC8.setChecked(True)

    def set_ui_for_category(self):
        self.ui.comboBoxCategory.setCurrentText(
            self.checksum_label.category.value)
        if self.checksum_label.category == self.checksum_label.Category.generic:
            self.ui.stackedWidget.setCurrentWidget(self.ui.page_crc)
        elif self.checksum_label.category == self.checksum_label.Category.wsp:
            self.ui.stackedWidget.setCurrentWidget(self.ui.page_wsp)
        else:
            raise ValueError("Unknown category")

        self.set_checksum_ui_elements()

    def display_crc_data_ranges_in_table(self):
        self.data_range_table_model.update()

    def __set_crc_info_label(self):
        crc = self.checksum_label.checksum  # type: GenericCRC
        self.ui.label_crc_info.setText("<b>CRC Summary:</b><ul>"
                                       "<li>Polynomial = {}<>"
                                       "<li>Length of checksum = {} bit</li>"
                                       "<li>start value length = {} bit</li>"
                                       "<li>final XOR length = {} bit</li>"
                                       "</ul>".format(crc.polynomial_to_html,
                                                      crc.poly_order - 1,
                                                      len(crc.start_value),
                                                      len(crc.final_xor)))

    def __ensure_same_length(self):
        for dependant_line_edit in [
                self.ui.lineEditStartValue, self.ui.lineEditFinalXOR
        ]:  # type: QLineEdit
            if len(self.ui.lineEditCRCPolynomial.text()) < len(
                    dependant_line_edit.text()):
                dependant_line_edit.setText(
                    dependant_line_edit.text()
                    [:len(self.ui.lineEditCRCPolynomial.text())])
                dependant_line_edit.editingFinished.emit()
            elif len(self.ui.lineEditCRCPolynomial.text()) > len(
                    dependant_line_edit.text()):
                # pad zeros at front
                dependant_line_edit.setText(
                    "0" * (len(self.ui.lineEditCRCPolynomial.text()) -
                           len(dependant_line_edit.text())) +
                    dependant_line_edit.text())
                dependant_line_edit.editingFinished.emit()

    @pyqtSlot()
    def on_btn_add_range_clicked(self):
        self.checksum_label.data_ranges.append([0, self.checksum_label.start])
        self.data_range_table_model.update()

    @pyqtSlot()
    def on_btn_remove_range_clicked(self):
        if len(self.checksum_label.data_ranges) > 1:
            self.checksum_label.data_ranges.pop(-1)
            self.data_range_table_model.update()

    @pyqtSlot(int)
    def on_combobox_crc_function_current_index_changed(self, index: int):
        poly_str = self.ui.comboBoxCRCFunction.itemText(index)
        if poly_str in GenericCRC.DEFAULT_POLYNOMIALS:
            self.checksum_label.checksum.polynomial = self.checksum_label.checksum.choose_polynomial(
                poly_str)
            self.checksum_label.checksum.start_value = array.array(
                "B", [0] * (self.checksum_label.checksum.poly_order - 1))
            self.checksum_label.checksum.final_xor = array.array(
                "B", [0] * (self.checksum_label.checksum.poly_order - 1))
        elif poly_str in self.SPECIAL_CRCS:
            self.checksum_label.checksum = copy.deepcopy(
                self.SPECIAL_CRCS[poly_str])
        else:
            logger.error("Unknown CRC")
            return

        self.ui.lineEditCRCPolynomial.setText(
            self.checksum_label.checksum.polynomial_as_hex_str)
        self.ui.lineEditStartValue.setText(
            util.bit2hex(self.checksum_label.checksum.start_value))
        self.ui.lineEditFinalXOR.setText(
            util.bit2hex(self.checksum_label.checksum.final_xor))
        self.ui.lineEditCRCPolynomial.editingFinished.emit()

    @pyqtSlot()
    def on_line_edit_crc_polynomial_editing_finished(self):
        self.checksum_label.checksum.set_polynomial_from_hex(
            self.ui.lineEditCRCPolynomial.text())
        self.__ensure_same_length()
        self.__set_crc_info_label()

    @pyqtSlot()
    def on_line_edit_start_value_editing_finished(self):
        crc = self.checksum_label.checksum
        start_value = util.hex2bit(self.ui.lineEditStartValue.text())
        # pad with zeros at front
        start_value = array.array(
            "B", [0] * (crc.poly_order - 1 - len(start_value))) + start_value
        crc.start_value = start_value[0:crc.poly_order - 1]
        self.ui.lineEditStartValue.setText(util.bit2hex(crc.start_value))
        self.__set_crc_info_label()

    @pyqtSlot()
    def on_line_edit_final_xor_editing_finished(self):
        crc = self.checksum_label.checksum
        final_xor = util.hex2bit(self.ui.lineEditFinalXOR.text())
        final_xor = array.array(
            "B", [0] * (crc.poly_order - 1 - len(final_xor))) + final_xor
        crc.final_xor = final_xor[0:crc.poly_order - 1]
        self.ui.lineEditFinalXOR.setText(util.bit2hex(crc.final_xor))
        self.__set_crc_info_label()

    @pyqtSlot(int)
    def on_combobox_category_current_index_changed(self, index: int):
        self.checksum_label.category = self.checksum_label.Category(
            self.ui.comboBoxCategory.currentText())
        self.set_ui_for_category()

    @pyqtSlot()
    def on_radio_button_wsp_auto_clicked(self):
        self.checksum_label.checksum.mode = WSPChecksum.ChecksumMode.auto

    @pyqtSlot()
    def on_radio_button_wsp_checksum4_clicked(self):
        self.checksum_label.checksum.mode = WSPChecksum.ChecksumMode.checksum4

    @pyqtSlot()
    def on_radio_button_wsp_checksum8_clicked(self):
        self.checksum_label.checksum.mode = WSPChecksum.ChecksumMode.checksum8

    @pyqtSlot()
    def on_radio_button_wsp_crc8_clicked(self):
        self.checksum_label.checksum.mode = WSPChecksum.ChecksumMode.crc8
示例#29
0
    def test_different_crcs(self):
        c = GenericCRC(polynomial="16_standard",
                       start_value=False,
                       final_xor=False,
                       reverse_polynomial=False,
                       reverse_all=False,
                       lsb_first=False,
                       little_endian=False)
        bitstring_set = [
            "101001001010101010101011101111111000000000000111101010011101011",
            "101001001010101101111010110111101010010110111010",
            "00000000000000000000000000000000100000000000000000000000000000000001111111111111",
            "1111111111111111111111111111111110111111111111111111110111111111111111110000000000"
            "1"
        ]

        for j in c.DEFAULT_POLYNOMIALS:
            c.polynomial = c.choose_polynomial(j)
            for i in bitstring_set:
                # Standard
                crc_new = c.crc(c.str2bit(i))
                crc_old = c.reference_crc(c.str2bit(i))
                self.assertEqual(crc_new, crc_old)

                # Special final xor
                c.final_xor = c.str2bit("0000111100001111")
                crc_new = c.crc(c.str2bit(i))
                crc_old = c.reference_crc(c.str2bit(i))
                self.assertEqual(crc_new, crc_old)
                c.final_xor = [False] * 16

                # Special start value
                c.start_value = c.str2bit("1010101010101010")
                crc_new = c.crc(c.str2bit(i))
                crc_old = c.reference_crc(c.str2bit(i))
                self.assertEqual(crc_new, crc_old)
                c.start_value = [False] * 16

                # reverse_polynomial
                c.reverse_polynomial = True
                crc_new = c.crc(c.str2bit(i))
                crc_old = c.reference_crc(c.str2bit(i))
                self.assertEqual(crc_new, crc_old)
                c.reverse_polynomial = False

                # lsb_first
                c.lsb_first = True
                crc_new = c.crc(c.str2bit(i))
                crc_old = c.reference_crc(c.str2bit(i))
                self.assertEqual(crc_new, crc_old)
                c.lsb_first = False

                # little_endian
                c.little_endian = True
                crc_new = c.crc(c.str2bit(i))
                crc_old = c.reference_crc(c.str2bit(i))
                self.assertEqual(crc_new, crc_old)
                c.little_endian = False

                # reverse all
                c.reverse_all = True
                crc_new = c.crc(c.str2bit(i))
                crc_old = c.reference_crc(c.str2bit(i))
                self.assertEqual(crc_new, crc_old)
                c.reverse_all = False
示例#30
0
    def find(self):
        result = list()
        bitvectors_by_n_gram_length = defaultdict(list)
        for i, bitvector in enumerate(self.bitvectors):
            bin_num = int(math.ceil(len(bitvector) / self.n_gram_length))
            bitvectors_by_n_gram_length[bin_num].append(i)

        crc = GenericCRC()
        for length, message_indices in bitvectors_by_n_gram_length.items():
            checksums_for_length = []
            for index in message_indices:
                bits = self.bitvectors[index]
                data_start, data_stop, crc_start, crc_stop = WSPChecksum.search_for_wsp_checksum(
                    bits)
                if (data_start, data_stop, crc_start, crc_stop) != (0, 0, 0,
                                                                    0):
                    checksum_range = ChecksumRange(start=crc_start,
                                                   length=crc_stop - crc_start,
                                                   data_range_start=data_start,
                                                   data_range_end=data_stop,
                                                   crc=WSPChecksum(),
                                                   score=1 /
                                                   len(message_indices),
                                                   field_type="checksum",
                                                   message_indices={index})
                    try:
                        present = next(c for c in checksums_for_length
                                       if c == checksum_range)
                        present.message_indices.add(index)
                    except StopIteration:
                        checksums_for_length.append(checksum_range)
                    continue

                crc_object, data_start, data_stop, crc_start, crc_stop = crc.guess_all(
                    bits, ignore_positions=self.already_labeled_cols)

                if (crc_object, data_start, data_stop, crc_start,
                        crc_stop) != (0, 0, 0, 0, 0):
                    checksum_range = ChecksumRange(start=crc_start,
                                                   length=crc_stop - crc_start,
                                                   data_range_start=data_start,
                                                   data_range_end=data_stop,
                                                   crc=copy.copy(crc_object),
                                                   score=1 /
                                                   len(message_indices),
                                                   field_type="checksum",
                                                   message_indices={index})

                    try:
                        present = next(rng for rng in checksums_for_length
                                       if rng == checksum_range)
                        present.message_indices.add(index)
                        continue
                    except StopIteration:
                        pass

                    checksums_for_length.append(checksum_range)

                    matching = awre_util.check_crc_for_messages(
                        message_indices, self.bitvectors, data_start,
                        data_stop, crc_start, crc_stop,
                        *crc_object.get_parameters())

                    checksum_range.message_indices.update(matching)

            # Score ranges
            for rng in checksums_for_length:
                rng.score = len(rng.message_indices) / len(message_indices)

            try:
                result.append(max(checksums_for_length, key=lambda x: x.score))
            except ValueError:
                pass  # no checksums found for this length

        self._debug("Found Checksums", result)
        try:
            max_scored = max(filter(
                lambda x: len(x.message_indices) >= 2 and x.score >= self.
                minimum_score, result),
                             key=lambda x: x.score)
        except ValueError:
            return []

        result = list(filter(lambda x: x.crc == max_scored.crc, result))
        self._debug("Filtered Checksums", result)

        return result
示例#31
0
文件: Encoding.py 项目: jopohl/urh
    def apply_data_whitening(self, decoding, inpt):
        len_sync = len(self.data_whitening_sync)
        len_polynomial = len(self.data_whitening_polynomial)
        inpt_from = 0
        inpt_to = len(inpt)

        # Crop last bit, if duplicate
        if decoding and inpt_to > 1:
            if inpt[-1] == inpt[-2]:
                inpt_to -= 1

        # # Crop last bit, if len not multiple of 8
        # if decoding and inpt_to % 8 != 0:
        #     inpt_to -= (8 - (inpt_to % 8)) % 8

        # inpt empty, polynomial or syncbytes are zero! (Shouldn't happen)
        if inpt_to < 1 or len_polynomial < 1 or len_sync < 1:
            return inpt[inpt_from:inpt_to], 0, self.ErrorState.MISC  # Misc Error

        # Search for whitening start position (after sync bytes)
        whitening_start_pos = inpt_from
        i = inpt_from
        while i < (inpt_to - len_sync):
            equalbits = 0
            for j in range(0, len_sync):
                if inpt[i + j] == self.data_whitening_sync[j]:
                    equalbits += 1
                else:
                    continue
            if len_sync == equalbits:
                whitening_start_pos = i + j + 1
                break
            else:
                i += 1
        # Sync not found
        if decoding and whitening_start_pos == inpt_from:
            return inpt[inpt_from:inpt_to], 0, self.ErrorState.SYNC_NOT_FOUND

        # Prepare keystream
        self.lfsr_state = array.array("B", [])
        keystream = self.lfsr(0)
        for i in range(whitening_start_pos, inpt_to, 8):
            keystream.extend(self.lfsr(8))

        # If data whitening polynomial is wrong, keystream can be less than needed. Check and exit.
        if len(keystream) < inpt_to - whitening_start_pos:
            return inpt[inpt_from:inpt_to], 0, self.ErrorState.MISC  # Error 31338

        # Overwrite crc16 in encoding case
        if not decoding and self.cc1101_overwrite_crc:
            # Remove additional bits
            offset = inpt_to % 8
            data_end = inpt_to - 16 - offset
            c = GenericCRC(polynomial="16_standard", start_value=True)
            crc = c.crc(inpt[whitening_start_pos:data_end])
            for i in range(0, 16):
                inpt[data_end + i] = crc[i]

        # Apply keystream (xor)
        for i in range(whitening_start_pos, inpt_to):
            inpt[i] ^= keystream[i - whitening_start_pos]

        # Duplicate last bit when encoding
        if not decoding:
            inpt += array.array("B", [inpt[-1]])
            inpt_to += 1

        return inpt[inpt_from:inpt_to], 0, self.ErrorState.SUCCESS
示例#32
0
 def crc8(cls, bits: array.array):
     return array.array(
         "B",
         GenericCRC(polynomial=cls.CRC_8_POLYNOMIAL).crc(bits))