encrypt.c
5.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include "encrypt.h"
// 密码存储区
const unsigned char encrypt_code[FLASH_SECTOR3_SIZE] __attribute__((at(ADDR_FLASH_SECTOR_3))) = {
eID0, eID1, eID2, eID3, eID4, eID5, eID6, eID7, eID8, eID9, eID10, eID11,
};
// 通用密码和 CRC 计算数据
const unsigned char crc_tmp_data[128]={
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
/*0*/ 0x39, 0x18, 0xbb, 0x5a, 0xdd, 0x21, 0xff, 0xee, 0x62, eID0, eID6, 0x14, 0x66, 0x77, 0x44, 0x55,
/*1*/ 0x2b, 0x90, 0x21, 0x32, 0x42, 0x54, 0x67, 0x76, 0xea, eID1, eID7, 0x89, 0xfe, 0xef, 0x2c, 0xcd,
/*2*/ 0x00, 0x21, 0x22, UID0, 0x44, 0x55, 0xc6, 0x77, 0x88, eID2, eID8, 0xbb, 0xcc, 0x3a, 0xce, 0x2c,
/*3*/ 0x31, 0x10, 0x32, UID1, 0x55, 0x44, 0xf7, 0x66, 0x34, eID3, eID9, 0x01, 0xc3, 0x67, 0x54, 0x05,
/*4*/ 0xaa, 0xbb, 0x88, UID2, 0xf7, 0xff, 0xcc, 0x8d, 0x33, eID4, eID10,0x00, 0xd7, 0x66, 0x55, 0xb4,
/*5*/ 0x5b, 0xaa, 0x99, UID3, 0xdf, 0xf7, 0xdd, 0xfe, 0xff, eID5, eID11,0xcf, 0xbb, 0x3a, 0x99, 0x78,
/*6*/ 0x88, 0xa9, 0xca,UID3+4,0xdc, 0x2d, 0xfe, 0x6f, 0x2c, 0xa1, 0x30, 0x20, 0x50, 0x25, 0x76, 0x3a,
/*7*/ 0x48, 0x55, 0x87,UID3+8,0x08, 0x61, 0x22, 0x23, 0x66, 0x2c, 0x4c, 0x55, 0x2c, 0x33, 0x00, 0x41,
};
// 本机 ID 存储变量
volatile union {
uint32_t dat32[3];
uint8_t dat8[12];
}mcuID;
// 本机密码存储变量
volatile uint8_t eCODE[12];
/*
函数名称: calculate_eCODE
功 能: 计算本机密码
(本函数当前没有进行复杂的算法设计,只简单地进行按位取反)
输 入: pUID,UID 数组指针
输 出: peCODE,本机密码
返 回: 无
*/
void calculate_eCODE(uint8_t *pUID, uint8_t *peCODE)
{
peCODE[0] = ~pUID[0];
peCODE[1] = ~pUID[1];
peCODE[2] = ~pUID[2];
peCODE[3] = ~pUID[3];
peCODE[4] = ~pUID[4];
peCODE[5] = ~pUID[5];
peCODE[6] = ~pUID[6];
peCODE[7] = ~pUID[7];
peCODE[8] = ~pUID[8];
peCODE[9] = ~pUID[9];
peCODE[10]= ~pUID[10];
peCODE[11]= ~pUID[11];
}
/*
函数名称: encrypt_code_save
功 能: 保存密码到 FLASH 中
输 入: 无
返 回: 无
*/
void encrypt_code_save(void)
{
uint32_t PAGEError = 0;
uint32_t write_addr;
uint32_t i;
uint8_t *pbuf;
FLASH_EraseInitTypeDef EraseInitStruct;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
EraseInitStruct.Banks = FLASH_BANK_1;
EraseInitStruct.Sector = FLASH_SECTOR_3;
EraseInitStruct.NbSectors = 1;
EraseInitStruct.VoltageRange= FLASH_VOLTAGE_RANGE_3;
HAL_FLASH_Unlock();
if (HAL_OK == HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError)) {
write_addr = ADDR_FLASH_SECTOR_3;
pbuf = (uint8_t *)eCODE;
for (i=0; i<12; i++) {
HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, write_addr + i, pbuf[i]);
}
}
HAL_FLASH_Lock();
}
/*
函数名称: read_ID
功 能: 读取 ID
输 入: 无
输 出: 读到的 UID 存入 pUID_dat32 指向的存储空间
返 回: 无
*/
void read_ID(uint32_t *pUID_dat32)
{
uint32_t mcuID_add;
uint32_t tmp[4];
// 31:0
// 为了更安全,不使用用立即数访问 UID,
// 所以将 UID 的地址分散在 crc_tmp_data 中,然后通过读取 crc_tmp_data 合成 UID 地址
tmp[0] = *(__IO uint8_t*)&crc_tmp_data[UID0_OFFSET];
tmp[1] = *(__IO uint8_t*)&crc_tmp_data[UID1_OFFSET];
tmp[2] = *(__IO uint8_t*)&crc_tmp_data[UID2_OFFSET];
tmp[3] = *(__IO uint8_t*)&crc_tmp_data[UID3_OFFSET_1];
mcuID_add = (tmp[0]<<24) + (tmp[1]<<16) + (tmp[2]<<8) + tmp[3]; // 合成 UID 地址
pUID_dat32[0] = *(__IO uint32_t*)(mcuID_add); // 读取 UID[31:0]
// 63:32
tmp[0] = *(__IO uint8_t*)&crc_tmp_data[UID0_OFFSET];
tmp[1] = *(__IO uint8_t*)&crc_tmp_data[UID1_OFFSET];
tmp[2] = *(__IO uint8_t*)&crc_tmp_data[UID2_OFFSET];
tmp[3] = *(__IO uint8_t*)&crc_tmp_data[UID3_OFFSET_2];
mcuID_add = (tmp[0]<<24) + (tmp[1]<<16) + (tmp[2]<<8) + tmp[3];
pUID_dat32[1] = *(__IO uint32_t*)(mcuID_add);
// 95:64
tmp[0] = *(__IO uint8_t*)&crc_tmp_data[UID0_OFFSET];
tmp[1] = *(__IO uint8_t*)&crc_tmp_data[UID1_OFFSET];
tmp[2] = *(__IO uint8_t*)&crc_tmp_data[UID2_OFFSET];
tmp[3] = *(__IO uint8_t*)&crc_tmp_data[UID3_OFFSET_3];
mcuID_add = (tmp[0]<<24) + (tmp[1]<<16) + (tmp[2]<<8) + tmp[3];
pUID_dat32[2] = *(__IO uint32_t*)(mcuID_add);
}
/*
函数名称: check_ID
功 能: 校验 ID
输 入: 无
返 回: HAL_OK,校验成功;HAL_ERROR,失败
*/
char check_ID(void)
{
// Step1.读取本机 ID,存入 mcuID 联合体
read_ID((uint32_t*)mcuID.dat32);
// Step2.使用本机 ID 计算本机密码,存入 eCODE 数组
calculate_eCODE((uint8_t*)mcuID.dat8, (uint8_t*)eCODE);
// Step3.对比 FLASH 中存储的密码是否等于通用密码
if((crc_tmp_data[eID0_OFFSET] == *(__IO uint8_t*)&encrypt_code[0])
&& (crc_tmp_data[eID1_OFFSET] == *(__IO uint8_t*)&encrypt_code[1])
&& (crc_tmp_data[eID2_OFFSET] == *(__IO uint8_t*)&encrypt_code[2])
&& (crc_tmp_data[eID3_OFFSET] == *(__IO uint8_t*)&encrypt_code[3])
&& (crc_tmp_data[eID4_OFFSET] == *(__IO uint8_t*)&encrypt_code[4])
&& (crc_tmp_data[eID5_OFFSET] == *(__IO uint8_t*)&encrypt_code[5])
&& (crc_tmp_data[eID6_OFFSET] == *(__IO uint8_t*)&encrypt_code[6])
&& (crc_tmp_data[eID7_OFFSET] == *(__IO uint8_t*)&encrypt_code[7])
&& (crc_tmp_data[eID8_OFFSET] == *(__IO uint8_t*)&encrypt_code[8])
&& (crc_tmp_data[eID9_OFFSET] == *(__IO uint8_t*)&encrypt_code[9])
&& (crc_tmp_data[eID10_OFFSET]== *(__IO uint8_t*)&encrypt_code[10])
&& (crc_tmp_data[eID11_OFFSET]== *(__IO uint8_t*)&encrypt_code[11])
) {
// 如果密码等于通用密码,则将计算的结果写入 FLASH
encrypt_code_save();
return 2;
} else
// Step4.对比计算的本机密码是否等于 FLASH 中存储的密码
if((eCODE[0] == *(__IO uint8_t*)&encrypt_code[0])
&& (eCODE[1] == *(__IO uint8_t*)&encrypt_code[1])
&& (eCODE[2] == *(__IO uint8_t*)&encrypt_code[2])
&& (eCODE[3] == *(__IO uint8_t*)&encrypt_code[3])
&& (eCODE[4] == *(__IO uint8_t*)&encrypt_code[4])
&& (eCODE[5] == *(__IO uint8_t*)&encrypt_code[5])
&& (eCODE[6] == *(__IO uint8_t*)&encrypt_code[6])
&& (eCODE[7] == *(__IO uint8_t*)&encrypt_code[7])
&& (eCODE[8] == *(__IO uint8_t*)&encrypt_code[8])
&& (eCODE[9] == *(__IO uint8_t*)&encrypt_code[9])
&& (eCODE[10]== *(__IO uint8_t*)&encrypt_code[10])
&& (eCODE[11]== *(__IO uint8_t*)&encrypt_code[11])
) {
// 如果密码校验正确,则不进行任何操作
return 1;
} else {
// 如果密码校验错位,则关机或者销毁程序
return 0;
}
}