Спецификация очень плохо написана и расплывчата, но просто сложение всех байтов в сообщении и взятие младших 2 байтов результата, кажется, приводит к правильной контрольной сумме:
#include <vector>
#include <cstdint>
#include <iostream>
#include <iomanip>
int main()
{
std::vector<uint8_t> data{ 0x55, 0xaa, 0x03, 0x01, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
int sum = 0;
for (auto x : data)
{
sum += x;
}
uint8_t sum1 = static_cast<uint8_t>(sum & 0xFF);
uint8_t sum2 = static_cast<uint8_t>((sum >> 8) & 0xFF);
std::cout << std::setfill('0') << std::hex <<
std::setw(2) << static_cast<int>(sum1) << " " <<
std::setw(2) << static_cast<int>(sum2) << "\n";
}