diff --git a/CanUds.c b/CanUds.c index 6ca2357..e395216 100644 --- a/CanUds.c +++ b/CanUds.c @@ -16,19 +16,100 @@ uint32_t randomSecuritySeed = 0x11223344; -static unsigned long SeedToKeyUAZ_ERA_NAMI(unsigned char rnd, unsigned long dwSeedInfo) { -#define Mask 0x52F387A6UL - unsigned char i; - unsigned long key = dwSeedInfo; +// Определение операций инверсии бит +#define INV_OP_A_MASK ((1UL << 6) | (1UL << 15) | (1UL << 17) | (1UL << 11) | \ + (1UL << 9) | (1UL << 16) | (1UL << 7) | (1UL << 10) | \ + (1UL << 13) | (1UL << 4)) - rnd += 35; - if (rnd < 35) rnd = 255; +#define INV_OP_B_MASK ((1UL << 14) | (1UL << 16) | (1UL << 11) | (1UL << 9) | \ + (1UL << 15) | (1UL << 7) | (1UL << 10) | (1UL << 13) | \ + (1UL << 4) | (1UL << 1)) - for (i = 0; i < rnd; i++) { - if (key & 0x80000000UL) - key = (key << 1) ^ Mask; - else - key <<= 1; +#define INV_OP_C_MASK ((1UL << 1) | (1UL << 7) | (1UL << 10) | (1UL << 13) | \ + (1UL << 4) | (1UL << 14) | (1UL << 16) | (1UL << 11) | \ + (1UL << 9) | (1UL << 15)) + +/** + * @brief Генерация ключа по сиду согласно алгоритму CCU + * @param seed Входное 32-битное значение сида + * @return 32-битный ключ + */ +static uint32_t generate_key_from_seed(uint32_t seed) { + // Шаг 1: Извлечение коэффициентов из сида + // Коэффициенты извлекаются из определенных битовых позиций (0 - LSB) + + // Коэффициент 1 (бит 20): направление сдвига (0=влево, 1=вправо) + uint8_t shift_direction = (seed >> 20) & 0x01; + + // Коэффициенты 2-5 (биты 7,11,5,8): количество сдвигов (4-битное число) + uint8_t shift_count = 0; + shift_count |= ((seed >> 7) & 0x01) << 3; // coefficient2 (MSB) + shift_count |= ((seed >> 11) & 0x01) << 2; // coefficient3 + shift_count |= ((seed >> 5) & 0x01) << 1; // coefficient4 + shift_count |= ((seed >> 8) & 0x01) << 0; // coefficient5 (LSB) + + // Коэффициенты 6-7 (биты 22,1): выбор операции инверсии (2 бита) + uint8_t inversion_operation = 0; + inversion_operation |= ((seed >> 22) & 0x01) << 1; // coefficient6 (MSB) + inversion_operation |= ((seed >> 1) & 0x01) << 0; // coefficient7 (LSB) + + // Коэффициенты 8-9 (биты 21,6): выбор битовой операции (2 бита) + uint8_t bitwise_operation = 0; + bitwise_operation |= ((seed >> 21) & 0x01) << 1; // coefficient8 (MSB) + bitwise_operation |= ((seed >> 6) & 0x01) << 0; // coefficient9 (LSB) + + // Шаг 2: Операция вращения (циклический сдвиг) + uint32_t intermediate1; + + if (shift_direction == 0) { + // Вращение влево + intermediate1 = (seed << shift_count) | (seed >> (32 - shift_count)); + } else { + // Вращение вправо + intermediate1 = (seed >> shift_count) | (seed << (32 - shift_count)); + } + + // Шаг 3: Операция инверсии бит + uint32_t intermediate2 = intermediate1; + + switch (inversion_operation) { + case 0x00: // Нет инверсии + // Ничего не делаем + break; + case 0x01: // Операция инверсии A + intermediate2 = intermediate1 ^ INV_OP_A_MASK; + break; + case 0x02: // Операция инверсии B + intermediate2 = intermediate1 ^ INV_OP_B_MASK; + break; + case 0x03: // Операция инверсии C + intermediate2 = intermediate1 ^ INV_OP_C_MASK; + break; + default: + // Недопустимая операция - оставляем как есть + break; + } + + // Шаг 4: Финальная битовая операция + uint32_t key; + + switch (bitwise_operation) { + case 0x00: // Key = intermediate2 + key = intermediate2; + break; + case 0x01: // Key = seed AND intermediate2 + key = seed & intermediate2; + break; + case 0x02: // Key = seed XOR intermediate2 + key = seed ^ intermediate2; + break; + case 0x03: // Key = seed OR intermediate2 + key = seed | intermediate2; + break; + default: + // Недопустимая операция - возвращаем intermediate2 + key = intermediate2; + break; } return key; @@ -603,7 +684,7 @@ static uint16_t SecurityAccess_27(tCanUds *env) { uint32_t securitySeedFromServer = (env->data.data[2] << 24) | (env->data.data[3] << 16) | (env->data.data[4] << 8) | env->data.data[5]; - uint32_t securitySeedMy = SeedToKeyUAZ_ERA_NAMI(0, randomSecuritySeed); + uint32_t securitySeedMy = generate_key_from_seed(randomSecuritySeed); if (securitySeedMy != securitySeedFromServer) { ++env->SA.counter_max_attempts_default;