Обновление
This commit is contained in:
parent
a2a6f8d4e5
commit
42742bdc11
105
CanUds.c
105
CanUds.c
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue