Обновление

This commit is contained in:
cfif 2026-01-27 16:50:02 +03:00
parent a2a6f8d4e5
commit 42742bdc11
1 changed files with 93 additions and 12 deletions

105
CanUds.c
View File

@ -16,19 +16,100 @@
uint32_t randomSecuritySeed = 0x11223344; uint32_t randomSecuritySeed = 0x11223344;
static unsigned long SeedToKeyUAZ_ERA_NAMI(unsigned char rnd, unsigned long dwSeedInfo) { // Определение операций инверсии бит
#define Mask 0x52F387A6UL #define INV_OP_A_MASK ((1UL << 6) | (1UL << 15) | (1UL << 17) | (1UL << 11) | \
unsigned char i; (1UL << 9) | (1UL << 16) | (1UL << 7) | (1UL << 10) | \
unsigned long key = dwSeedInfo; (1UL << 13) | (1UL << 4))
rnd += 35; #define INV_OP_B_MASK ((1UL << 14) | (1UL << 16) | (1UL << 11) | (1UL << 9) | \
if (rnd < 35) rnd = 255; (1UL << 15) | (1UL << 7) | (1UL << 10) | (1UL << 13) | \
(1UL << 4) | (1UL << 1))
for (i = 0; i < rnd; i++) { #define INV_OP_C_MASK ((1UL << 1) | (1UL << 7) | (1UL << 10) | (1UL << 13) | \
if (key & 0x80000000UL) (1UL << 4) | (1UL << 14) | (1UL << 16) | (1UL << 11) | \
key = (key << 1) ^ Mask; (1UL << 9) | (1UL << 15))
else
key <<= 1; /**
* @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; return key;
@ -603,7 +684,7 @@ static uint16_t SecurityAccess_27(tCanUds *env) {
uint32_t securitySeedFromServer = uint32_t securitySeedFromServer =
(env->data.data[2] << 24) | (env->data.data[3] << 16) | (env->data.data[4] << 8) | env->data.data[5]; (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) { if (securitySeedMy != securitySeedFromServer) {
++env->SA.counter_max_attempts_default; ++env->SA.counter_max_attempts_default;