Files
luban-lite/packages/artinchip/uds/UDSLogic/SID27_SecurityAccess.c

214 lines
7.1 KiB
C
Raw Permalink Normal View History

2025-07-22 11:15:46 +08:00
/*
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#include "SID27_SecurityAccess.h"
#include "service_cfg.h"
#include "uds_def.h"
#include <stdlib.h>
#include <time.h>
2025-10-21 13:59:50 +08:00
#define UNLOCKKEY 0x00000000
#define UNLOCKSEED 0x00000000
#define UNDEFINESEED 0xFFFFFFFF
#define SEEDMASK 0x80000000
#define SHIFTBIT 1
#define ALGORITHMASK 0x42303131
#define UDS_SEED_LENGTH (0x04)
#define UDS_REQUEST_SEED (0x01)
#define UDS_SEND_KEY (0x02)
#define UDS_FAS_MAX_TIMES (0x02) /* failed security access */
static uint8_t req_seed = 0; // 接收到请求种子标志
2025-07-22 11:15:46 +08:00
static uint8_t org_seed_buf[UDS_SEED_LENGTH];
// 当前安全访问等级
static uds_sa_lv curr_sa = UDS_SA_NON;
// 安全访问种子匹配错误次数
uint8_t uds_fsa_cnt = 0;
/******************************************************************************
* : void set_current_sa_lv(uds_sa_lv level)
* : 访
* : uds_sa_lv level --访
* :
* :
* :
******************************************************************************/
void set_current_sa_lv(uds_sa_lv level)
{
2025-10-21 13:59:50 +08:00
curr_sa = level;
2025-07-22 11:15:46 +08:00
}
/******************************************************************************
* : uds_session_t get_current_sa_lv(void)
* : 访
* :
* :
* : 访
* :
******************************************************************************/
uds_sa_lv get_current_sa_lv(void)
{
return curr_sa;
}
/******************************************************************************
* : static uint8_t rand_u8 (void)
* :
* :
* :
* : 8
* :
******************************************************************************/
static uint8_t rand_u8(void)
{
static uint8_t initialized = 0;
if (!initialized) {
2025-10-21 13:59:50 +08:00
srand(time(NULL));
2025-07-22 11:15:46 +08:00
initialized = 1;
}
return rand() % 0xFF;
}
/******************************************************************************
* : static uint32_t seedTOKey(uint32_t seed)
* : 访
* : uint32_t seed --
* :
* : key
* :
******************************************************************************/
static uint32_t seedTOKey(uint32_t seed)
{
2025-10-21 13:59:50 +08:00
return (~seed);
2025-07-22 11:15:46 +08:00
}
/******************************************************************************
* : int uds_security_access(uint8_t* key_buf, uint8_t* seed_buf)
* : seed key key
* : uint8_t* key_buf -- key
    uint8_t* seed_buf --
* :
* : 0: ; -1:
* :
******************************************************************************/
2025-10-21 13:59:50 +08:00
int uds_security_access(uint8_t *key_buf, uint8_t *seed_buf)
2025-07-22 11:15:46 +08:00
{
2025-10-21 13:59:50 +08:00
uint32_t key = 0;
uint32_t seed = 0;
key = (key_buf[0] << 24) | (key_buf[1] << 16) | (key_buf[2] << 8) | key_buf[3];
seed = (seed_buf[0] << 24) | (seed_buf[1] << 16) | (seed_buf[2] << 8) | seed_buf[3];
2025-07-22 11:15:46 +08:00
2025-10-21 13:59:50 +08:00
if (key == seedTOKey(seed))
return 0;
else
return -1;
}
2025-07-22 11:15:46 +08:00
/******************************************************************************
* : bool_t service_27_check_len(const uint8_t* msg_buf, uint16_t msg_dlc)
* : 27
* : uint16_t msg_dlc --
* :
* : TRUE: ; FALSE:
* :
******************************************************************************/
2025-10-21 13:59:50 +08:00
bool_t service_27_check_len(const uint8_t *msg_buf, uint16_t msg_dlc)
2025-07-22 11:15:46 +08:00
{
2025-10-21 13:59:50 +08:00
bool_t ret = FALSE;
uint8_t subfunction;
2025-07-22 11:15:46 +08:00
2025-10-21 13:59:50 +08:00
subfunction = UDS_GET_SUB_FUNCTION(msg_buf[1]);
2025-07-22 11:15:46 +08:00
2025-10-21 13:59:50 +08:00
if ((UDS_REQUEST_SEED == subfunction && 2 == msg_dlc) ||
(UDS_SEND_KEY == subfunction && 6 == msg_dlc))
2025-07-22 11:15:46 +08:00
2025-10-21 13:59:50 +08:00
{
ret = TRUE;
}
2025-07-22 11:15:46 +08:00
2025-10-21 13:59:50 +08:00
return ret;
}
2025-07-22 11:15:46 +08:00
/******************************************************************************
* : void service_27_SecurityAccess(const uint8_t* msg_buf, uint16_t msg_dlc)
* : 27 - 访
* : uint8_t* msg_buf --
    uint8_t msg_dlc --
* :
* :
* :
******************************************************************************/
2025-10-21 13:59:50 +08:00
void service_27_SecurityAccess(const uint8_t *msg_buf, uint16_t msg_dlc)
2025-07-22 11:15:46 +08:00
{
uint8_t subfunction;
2025-10-21 13:59:50 +08:00
uint8_t rsp_buf[8];
uint16_t i;
subfunction = UDS_GET_SUB_FUNCTION(msg_buf[1]);
switch (subfunction) {
case UDS_REQUEST_SEED: // 请求种子
{
// 锁定时间要求不能因模块断电被清零,这里暂未实现掉电保存的功能
if (uds_timer_chk(UDS_TIMER_FSA) > 0) {
uds_negative_rsp(SID_27, NRC_REQUIRED_TIME_DELAY_NOT_EXPIRED);
break;
}
req_seed = 1;
rsp_buf[0] = USD_GET_POSITIVE_RSP(SID_27);
rsp_buf[1] = subfunction;
for (i = 0; i < UDS_SEED_LENGTH; i++) {
// ECU 在已经解锁的情况下,如果再次收到请求种子,则返回种子 0x00000000
if (curr_sa == UDS_SA_LV1)
org_seed_buf[i] = 0;
else
org_seed_buf[i] = rand_u8();
rsp_buf[2 + i] = org_seed_buf[i];
}
uds_positive_rsp(rsp_buf, UDS_SEED_LENGTH + 2);
break;
}
case UDS_SEND_KEY: // 发送密钥
{
// 在发送秘钥前必须先请求种子
if (req_seed == 0) {
uds_negative_rsp(SID_27, NRC_REQUEST_SEQUENCE_ERROR);
break;
}
req_seed = 0;
// 判断发送过来的密钥和自己计算的密钥是否一致
if (!uds_security_access((uint8_t *)&msg_buf[2], org_seed_buf)) {
rsp_buf[0] = USD_GET_POSITIVE_RSP(SID_27);
rsp_buf[1] = subfunction;
uds_positive_rsp(rsp_buf, 2);
set_current_sa_lv(UDS_SA_LV1);
} else {
uds_fsa_cnt++;
if (uds_fsa_cnt >= UDS_FAS_MAX_TIMES) {
// 密钥尝试次数超过限值
uds_timer_start(
UDS_TIMER_FSA); // 锁定时间要求不能因模块断电被清零,这里暂未实现掉电保存的功能
uds_negative_rsp(SID_27, NRC_EXCEEDED_NUMBER_OF_ATTEMPTS);
} else {
// 密钥无效
uds_negative_rsp(SID_27, NRC_INVALID_KEY);
}
}
break;
}
default:
uds_negative_rsp(SID_27, NRC_SUBFUNCTION_NOT_SUPPORTED);
break;
}
2025-07-22 11:15:46 +08:00
}
/****************EOF****************/