Beispiel #1
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")
Beispiel #2
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)
Beispiel #3
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)
Beispiel #4
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)
Beispiel #5
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)
Beispiel #6
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]]))))
Beispiel #7
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
Beispiel #8
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
Beispiel #9
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")
Beispiel #10
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
Beispiel #11
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