Обновление

This commit is contained in:
cfif 2026-01-28 14:48:17 +03:00
parent b3698a506a
commit 789bdbf457
3 changed files with 139 additions and 3 deletions

View File

@ -59,7 +59,7 @@ static _Noreturn void Mma_Thread(tMma *env) {
SystemDelayMs(1000); SystemDelayMs(1000);
ModelTask_StartThread(&env->ModelTask); // ModelTask_StartThread(&env->ModelTask);
/* /*

View File

@ -79,10 +79,10 @@ static void Mma_InitSubSystems(tMma *env) {
CanSerialPortCanUds_Start(&env->canUds); CanSerialPortCanUds_Start(&env->canUds);
CanSpamReceiver_Init(&env->canSpamReceiver, &env->canPorts->Can0_IO); CanSpamReceiver_Init(&env->canSpamReceiver, &env->canPorts->Can0_IO);
CanSpamReceiver_StartThread(&env->canSpamReceiver); // CanSpamReceiver_StartThread(&env->canSpamReceiver);
CanSpamTransmitter_Init(&env->canSpamTransmitter, &env->canPorts->Can0_IO); CanSpamTransmitter_Init(&env->canSpamTransmitter, &env->canPorts->Can0_IO);
CanSpamTransmitter_StartThread(&env->canSpamTransmitter); // CanSpamTransmitter_StartThread(&env->canSpamTransmitter);
tLinData *linData = Lin0_Init(GetLin0CallbackHandler); tLinData *linData = Lin0_Init(GetLin0CallbackHandler);
Lin_0_Init(&env->linTaskActuator0, linData, &env->linPorts->lin0_Io, &env->slog.logger); Lin_0_Init(&env->linTaskActuator0, linData, &env->linPorts->lin0_Io, &env->slog.logger);

136
NAMI.c Normal file
View File

@ -0,0 +1,136 @@
//
// Created by cfif on 28.01.2026.
//
#include <stdint.h>
#include <stdbool.h>
/**
* CCU Secure Access Algorithm
* Реализация алгоритма генерации ключа по seed для диагностического доступа
* Согласно спецификации NAMI UMP vehicle, версия 1.1
*/
/* Позиции битов коэффициентов в seed */
#define COEFF1_POS 20 /* Направление сдвига (0 - влево, 1 - вправо) */
#define COEFF2_POS 7 /* Старший бит количества сдвигов */
#define COEFF3_POS 11 /* */
#define COEFF4_POS 5 /* */
#define COEFF5_POS 8 /* Младший бит количества сдвигов */
#define COEFF6_POS 22 /* Старший бит операции инверсии */
#define COEFF7_POS 1 /* Младший бит операции инверсии */
#define COEFF8_POS 21 /* Старший бит побитовой операции */
#define COEFF9_POS 6 /* Младший бит побитовой операции */
/* Позиции битов для инверсии */
#define INV_A_BITS ((1U << 6) | (1U << 15) | (1U << 17))
#define INV_B_BITS ((1U << 11) | (1U << 9) | (1U << 16))
#define INV_C_BITS ((1U << 7) | (1U << 10) | (1U << 13) | (1U << 4))
/**
* Извлечение бита из значения
* position: 0 = младший бит (LSB), 31 = старший бит (MSB)
*/
static inline uint32_t extract_bit(uint32_t value, int position)
{
return (value >> position) & 1U;
}
/**
* Циклический сдвиг вправо (rotation)
*/
static inline uint32_t rotate_right(uint32_t value, int bits)
{
bits = bits % 32;
if (bits == 0) return value;
return (value >> bits) | (value << (32 - bits));
}
/**
* Циклический сдвиг влево (rotation)
*/
static inline uint32_t rotate_left(uint32_t value, int bits)
{
bits = bits % 32;
if (bits == 0) return value;
return (value << bits) | (value >> (32 - bits));
}
/**
* Генерация 32-битного ключа из 32-битного seed
*
* Параметры:
* seed - случайное значение от ECU (32 бита)
*
* Возвращает:
* 32-битный ключ для ответа ECU
*/
uint32_t generate_key(uint32_t seed)
{
/* Извлечение коэффициентов из seed */
uint32_t coeff1 = extract_bit(seed, COEFF1_POS); /* Направление сдвига */
/* Коэффициенты 2-5: количество циклических сдвигов (coeff2 - старший бит) */
uint32_t coeff2 = extract_bit(seed, COEFF2_POS);
uint32_t coeff3 = extract_bit(seed, COEFF3_POS);
uint32_t coeff4 = extract_bit(seed, COEFF4_POS);
uint32_t coeff5 = extract_bit(seed, COEFF5_POS);
uint32_t num_shifts = (coeff2 << 3) | (coeff3 << 2) | (coeff4 << 1) | coeff5;
/* Коэффициенты 6-7: выбор операции инверсии (coeff6 - старший бит) */
uint32_t coeff6 = extract_bit(seed, COEFF6_POS);
uint32_t coeff7 = extract_bit(seed, COEFF7_POS);
uint32_t inversion_op = (coeff6 << 1) | coeff7;
/* Коэффициенты 8-9: побитовая операция (coeff8 - старший бит) */
uint32_t coeff8 = extract_bit(seed, COEFF8_POS);
uint32_t coeff9 = extract_bit(seed, COEFF9_POS);
uint32_t bitwise_op = (coeff8 << 1) | coeff9;
/* Шаг 1: Вычисление intermediate 1 (циклический сдвиг) */
uint32_t intermediate1;
if (coeff1 == 0) {
intermediate1 = rotate_left(seed, num_shifts);
} else {
intermediate1 = rotate_right(seed, num_shifts);
}
/* Шаг 2: Вычисление intermediate 2 (инверсия битов) */
uint32_t intermediate2 = intermediate1;
switch (inversion_op) {
case 1: /* Операция A: инвертировать биты 6, 15, 17 */
intermediate2 ^= INV_A_BITS;
break;
case 2: /* Операция B: инвертировать биты 11, 9, 16 */
intermediate2 ^= INV_B_BITS;
break;
case 3: /* Операция C: инвертировать биты 7, 10, 13, 4 */
intermediate2 ^= INV_C_BITS;
break;
case 0: /* Нет инверсии */
default:
break;
}
/* Шаг 3: Вычисление финального ключа (побитовая операция) */
uint32_t key;
switch (bitwise_op) {
case 0: /* Key = intermediate value */
key = intermediate2;
break;
case 1: /* Key = seed AND intermediate value */
key = seed & intermediate2;
break;
case 2: /* Key = seed XOR intermediate value */
key = seed ^ intermediate2;
break;
case 3: /* Key = seed OR intermediate value */
key = seed | intermediate2;
break;
default:
key = intermediate2;
break;
}
return key;
}