/src/opendnp3/cpp/lib/src/link/CRC.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2013-2022 Step Function I/O, LLC |
3 | | * |
4 | | * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O |
5 | | * LLC (https://stepfunc.io) under one or more contributor license agreements. |
6 | | * See the NOTICE file distributed with this work for additional information |
7 | | * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license |
8 | | * this file to you under the Apache License, Version 2.0 (the "License"); you |
9 | | * may not use this file except in compliance with the License. You may obtain |
10 | | * a copy of the License at: |
11 | | * |
12 | | * http://www.apache.org/licenses/LICENSE-2.0 |
13 | | * |
14 | | * Unless required by applicable law or agreed to in writing, software |
15 | | * distributed under the License is distributed on an "AS IS" BASIS, |
16 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
17 | | * See the License for the specific language governing permissions and |
18 | | * limitations under the License. |
19 | | */ |
20 | | #include "CRC.h" |
21 | | |
22 | | #include <ser4cpp/serialization/LittleEndian.h> |
23 | | |
24 | | namespace opendnp3 |
25 | | { |
26 | | |
27 | | uint16_t CRC::crcTable[256] |
28 | | = {0x0000, 0x365E, 0x6CBC, 0x5AE2, 0xD978, 0xEF26, 0xB5C4, 0x839A, 0xFF89, 0xC9D7, 0x9335, 0xA56B, 0x26F1, 0x10AF, |
29 | | 0x4A4D, 0x7C13, 0xB26B, 0x8435, 0xDED7, 0xE889, 0x6B13, 0x5D4D, 0x07AF, 0x31F1, 0x4DE2, 0x7BBC, 0x215E, 0x1700, |
30 | | 0x949A, 0xA2C4, 0xF826, 0xCE78, 0x29AF, 0x1FF1, 0x4513, 0x734D, 0xF0D7, 0xC689, 0x9C6B, 0xAA35, 0xD626, 0xE078, |
31 | | 0xBA9A, 0x8CC4, 0x0F5E, 0x3900, 0x63E2, 0x55BC, 0x9BC4, 0xAD9A, 0xF778, 0xC126, 0x42BC, 0x74E2, 0x2E00, 0x185E, |
32 | | 0x644D, 0x5213, 0x08F1, 0x3EAF, 0xBD35, 0x8B6B, 0xD189, 0xE7D7, 0x535E, 0x6500, 0x3FE2, 0x09BC, 0x8A26, 0xBC78, |
33 | | 0xE69A, 0xD0C4, 0xACD7, 0x9A89, 0xC06B, 0xF635, 0x75AF, 0x43F1, 0x1913, 0x2F4D, 0xE135, 0xD76B, 0x8D89, 0xBBD7, |
34 | | 0x384D, 0x0E13, 0x54F1, 0x62AF, 0x1EBC, 0x28E2, 0x7200, 0x445E, 0xC7C4, 0xF19A, 0xAB78, 0x9D26, 0x7AF1, 0x4CAF, |
35 | | 0x164D, 0x2013, 0xA389, 0x95D7, 0xCF35, 0xF96B, 0x8578, 0xB326, 0xE9C4, 0xDF9A, 0x5C00, 0x6A5E, 0x30BC, 0x06E2, |
36 | | 0xC89A, 0xFEC4, 0xA426, 0x9278, 0x11E2, 0x27BC, 0x7D5E, 0x4B00, 0x3713, 0x014D, 0x5BAF, 0x6DF1, 0xEE6B, 0xD835, |
37 | | 0x82D7, 0xB489, 0xA6BC, 0x90E2, 0xCA00, 0xFC5E, 0x7FC4, 0x499A, 0x1378, 0x2526, 0x5935, 0x6F6B, 0x3589, 0x03D7, |
38 | | 0x804D, 0xB613, 0xECF1, 0xDAAF, 0x14D7, 0x2289, 0x786B, 0x4E35, 0xCDAF, 0xFBF1, 0xA113, 0x974D, 0xEB5E, 0xDD00, |
39 | | 0x87E2, 0xB1BC, 0x3226, 0x0478, 0x5E9A, 0x68C4, 0x8F13, 0xB94D, 0xE3AF, 0xD5F1, 0x566B, 0x6035, 0x3AD7, 0x0C89, |
40 | | 0x709A, 0x46C4, 0x1C26, 0x2A78, 0xA9E2, 0x9FBC, 0xC55E, 0xF300, 0x3D78, 0x0B26, 0x51C4, 0x679A, 0xE400, 0xD25E, |
41 | | 0x88BC, 0xBEE2, 0xC2F1, 0xF4AF, 0xAE4D, 0x9813, 0x1B89, 0x2DD7, 0x7735, 0x416B, 0xF5E2, 0xC3BC, 0x995E, 0xAF00, |
42 | | 0x2C9A, 0x1AC4, 0x4026, 0x7678, 0x0A6B, 0x3C35, 0x66D7, 0x5089, 0xD313, 0xE54D, 0xBFAF, 0x89F1, 0x4789, 0x71D7, |
43 | | 0x2B35, 0x1D6B, 0x9EF1, 0xA8AF, 0xF24D, 0xC413, 0xB800, 0x8E5E, 0xD4BC, 0xE2E2, 0x6178, 0x5726, 0x0DC4, 0x3B9A, |
44 | | 0xDC4D, 0xEA13, 0xB0F1, 0x86AF, 0x0535, 0x336B, 0x6989, 0x5FD7, 0x23C4, 0x159A, 0x4F78, 0x7926, 0xFABC, 0xCCE2, |
45 | | 0x9600, 0xA05E, 0x6E26, 0x5878, 0x029A, 0x34C4, 0xB75E, 0x8100, 0xDBE2, 0xEDBC, 0x91AF, 0xA7F1, 0xFD13, 0xCB4D, |
46 | | 0x48D7, 0x7E89, 0x246B, 0x1235}; |
47 | | |
48 | | uint16_t CRC::CalcCrc(const uint8_t* input, size_t length) |
49 | 9.07k | { |
50 | 9.07k | uint16_t CRC = 0; |
51 | | |
52 | 1.40M | for (uint32_t i = 0; i < length; ++i) |
53 | 1.40M | { |
54 | 1.40M | uint8_t index = (CRC ^ input[i]) & 0xFF; |
55 | 1.40M | CRC = crcTable[index] ^ (CRC >> 8); |
56 | 1.40M | } |
57 | | |
58 | 9.07k | return ~CRC; |
59 | 9.07k | } |
60 | | |
61 | | uint16_t CRC::CalcCrc(const ser4cpp::rseq_t& view) |
62 | 9.07k | { |
63 | 9.07k | return CalcCrc(view, view.length()); |
64 | 9.07k | } |
65 | | |
66 | | void CRC::AddCrc(uint8_t* input, size_t length) |
67 | 0 | { |
68 | 0 | uint16_t crc = CRC::CalcCrc(input, length); |
69 | |
|
70 | 0 | ser4cpp::wseq_t buffer(input + length, 2); |
71 | 0 | ser4cpp::UInt16::write_to(buffer, crc); |
72 | 0 | } |
73 | | |
74 | | bool CRC::IsCorrectCRC(const uint8_t* input, size_t length) |
75 | 0 | { |
76 | | // This definition is automatically set when compiling for OSS-Fuzz. |
77 | | // See https://llvm.org/docs/LibFuzzer.html#fuzzer-friendly-build-mode |
78 | 0 | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
79 | 0 | return true; |
80 | | #else |
81 | | ser4cpp::rseq_t buffer(input + length, 2); |
82 | | uint16_t crcValue; |
83 | | ser4cpp::UInt16::read_from(buffer, crcValue); |
84 | | return CRC::CalcCrc(input, length) == crcValue; |
85 | | #endif |
86 | 0 | } |
87 | | |
88 | | } // namespace opendnp3 |