blob: b953672b127c361bf55e21888533f7a64f96f479 [file] [log] [blame]
Googler25e92cf2023-12-13 10:05:01 +00001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 */
5
6#include "ini_config.h"
7
8#define LOG_TAG "UnifyKey"
9#define LOG_NDEBUG 0
10
11#include "ini_log.h"
12#include "UnifyKey.h"
13#include "ini_size_define.h"
14
15#if (defined (CC_INI_IO_USE_UNIFY_KEY))
16
17#if (!defined (CC_INI_IO_UKEY_USE_OTHER_MODULE))
18
19#if (defined(CC_COMPILE_IN_PC) || defined(CC_COMPILE_IN_ANDROID))
20
21#if (defined CC_COMPILE_IN_PC)
22
23#define CS_KEY_DATA_LIST_DEV_PATH "sys/class/unifykeys/list"
24#define CS_KEY_DATA_NAME_DEV_PATH "sys/class/unifykeys/name"
25
26static char gDevPath[256] = {0};
27static int GetDevPath(char path_buf[]) {
28 int tmp_len = 0;
29 FILE *dev_fp = NULL;
30
31 strcpy(path_buf, "sys/class/unifykeys/");
32 dev_fp = fopen(CS_KEY_DATA_NAME_DEV_PATH, "r");
33 if (dev_fp == NULL) {
34 ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
35 CS_KEY_DATA_NAME_DEV_PATH, strerror(errno));
36 return -1;
37 }
38
39 tmp_len = strlen(path_buf);
40 fscanf(dev_fp, "%s", path_buf + tmp_len);
41
42 fclose(dev_fp);
43 dev_fp = NULL;
44
45 return 0;
46}
47
48static const char *GetKeyDataWriteDevPath() {
49 memset((void *)gDevPath, 0, 256);
50 GetDevPath(gDevPath);
51 return gDevPath;
52}
53
54static const char *GetKeyDataReadDevPath() {
55 memset((void *)gDevPath, 0, 256);
56 GetDevPath(gDevPath);
57 return gDevPath;
58}
59
60#else
61
62#define CS_KEY_DATA_LIST_DEV_PATH "/sys/class/unifykeys/list"
63#define CS_KEY_DATA_NAME_DEV_PATH "/sys/class/unifykeys/name"
64
65static const char *GetKeyDataWriteDevPath() {
66 return "/sys/class/unifykeys/write";
67}
68
69static const char *GetKeyDataReadDevPath() {
70 return "/sys/class/unifykeys/read";
71}
72
73#endif //CC_COMPILE_IN_PC
74
75static int checkKeyNameInList(const char *key_name) {
76 FILE *dev_fp = NULL;
77 char *tmp_ptr = NULL;
78 char lineStr[1024];
79
80 dev_fp = fopen(CS_KEY_DATA_LIST_DEV_PATH, "r");
81 if (dev_fp == NULL) {
82 ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
83 CS_KEY_DATA_LIST_DEV_PATH, strerror(errno));
84 return -1;
85 }
86
87 while (fgets(lineStr, 1024, dev_fp) != NULL) {
88 tmp_ptr = strstr(lineStr, key_name);
89 if (tmp_ptr != NULL) {
90 break;
91 }
92
93 tmp_ptr = NULL;
94 }
95
96 fclose(dev_fp);
97 dev_fp = NULL;
98
99 if (tmp_ptr == NULL) {
100 return -1;
101 }
102
103 return 0;
104}
105
106int readUKeyData_no_header(const char *key_name, unsigned char data_buf[], int rd_size) {
107 int rd_cnt = 0;
108 FILE *dev_fp = NULL;
109
110 if (checkKeyNameInList(key_name) < 0) {
111 ALOGE("%s, key \"%s\" isn't exist in unifykeys list\n", __FUNCTION__, key_name);
112 return -1;
113 }
114
115 dev_fp = fopen(CS_KEY_DATA_NAME_DEV_PATH, "w");
116 if (dev_fp == NULL) {
117 ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
118 CS_KEY_DATA_NAME_DEV_PATH, strerror(errno));
119 return -1;
120 }
121
122 fprintf(dev_fp, "%s", key_name);
123
124 fclose(dev_fp);
125 dev_fp = NULL;
126
127 int mode = 1;
128
129 if (mode == 0) {
130 dev_fp = fopen(GetKeyDataReadDevPath(), "r");
131 if (dev_fp == NULL) {
132 ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
133 GetKeyDataReadDevPath(), strerror(errno));
134 return -1;
135 }
136
137 fscanf(dev_fp, "%s", data_buf);
138 rd_cnt = strlen((char *) data_buf);
139 } else {
140 dev_fp = fopen(GetKeyDataReadDevPath(), "rb");
141 if (dev_fp == NULL) {
142 ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
143 GetKeyDataReadDevPath(), strerror(errno));
144 return -1;
145 }
146
147 rd_cnt = fread(data_buf, 1, CC_ONE_SECTION_SIZE, dev_fp);
148 }
149
150 fclose(dev_fp);
151 dev_fp = NULL;
152
153 return rd_cnt;
154}
155
156int readUKeyData(const char *key_name, unsigned char data_buf[], int rd_size) {
157 int rd_cnt = 0;
158 FILE *dev_fp = NULL;
159
160 if (checkKeyNameInList(key_name) < 0) {
161 ALOGE("%s, key \"%s\" isn't exist in unifykeys list\n", __FUNCTION__, key_name);
162 return -1;
163 }
164
165 dev_fp = fopen(CS_KEY_DATA_NAME_DEV_PATH, "w");
166 if (dev_fp == NULL) {
167 ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
168 CS_KEY_DATA_NAME_DEV_PATH, strerror(errno));
169 return -1;
170 }
171
172 fprintf(dev_fp, "%s", key_name);
173
174 fclose(dev_fp);
175 dev_fp = NULL;
176
177 int mode = 1;
178
179 if (mode == 0) {
180 dev_fp = fopen(GetKeyDataReadDevPath(), "r");
181 if (dev_fp == NULL) {
182 ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
183 GetKeyDataReadDevPath(), strerror(errno));
184 return -1;
185 }
186
187 fscanf(dev_fp, "%s", data_buf);
188 rd_cnt = strlen((char *) data_buf);
189 } else {
190 dev_fp = fopen(GetKeyDataReadDevPath(), "rb");
191 if (dev_fp == NULL) {
192 ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
193 GetKeyDataReadDevPath(), strerror(errno));
194 return -1;
195 }
196
197 rd_cnt = fread(data_buf, 1, CC_ONE_SECTION_SIZE, dev_fp);
198 }
199
200 fclose(dev_fp);
201 dev_fp = NULL;
202
203 return rd_cnt;
204}
205
206int writeUKeyData(const char *key_name, unsigned char data_buf[], int wr_size) {
207 int wr_cnt = 0;
208 int dev_fd = -1;
209 FILE *dev_fp = NULL;
210
211 if (checkKeyNameInList(key_name) < 0) {
212 ALOGE("%s, key \"%s\" isn't exist in unifykeys list\n", __FUNCTION__, key_name);
213 return -1;
214 }
215
216 dev_fp = fopen(CS_KEY_DATA_NAME_DEV_PATH, "w");
217 if (dev_fp == NULL) {
218 ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
219 CS_KEY_DATA_NAME_DEV_PATH, strerror(errno));
220 return -1;
221 }
222
223 fprintf(dev_fp, "%s", key_name);
224
225 fclose(dev_fp);
226 dev_fp = NULL;
227
228 dev_fd = open(GetKeyDataWriteDevPath(), O_WRONLY | O_SYNC | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
229
230 if (dev_fd < 0) {
231 ALOGE("%s, open %s ERROR(%s)!!\n", __FUNCTION__,
232 GetKeyDataWriteDevPath(), strerror(errno));
233 return -1;
234 }
235
236 wr_cnt = write(dev_fd, data_buf, wr_size);
237
238 fsync(dev_fd);
239
240 close(dev_fd);
241 dev_fd = -1;
242
243 return wr_cnt;
244}
245
246#elif (defined CC_COMPILE_IN_UBOOT)
247
248#include "model.h"
249
250#define CC_UKEY_RETRY_CNT_MAX (5)
251
252static int checkUnifyKey(const char *key_name) {
253 int ret = 0, key_exist = 0, isSecure = 0;
254 unsigned int key_len = 0;
255 ssize_t key_size = 0;
256
257 // start check the key is exist?
258 ret = key_unify_query_exist(key_name, &key_exist);
259 if (ret) {
260 ALOGE("%s, %s query exist error.\n",__FUNCTION__, key_name);
261 return -1;
262 }
263 if (key_exist == 0) {
264 ALOGE("%s, %s is not exist.\n",__FUNCTION__, key_name);
265 return -1;
266 }
267 // end check the key is exist?
268
269 // start check the key is secure?
270 ret = key_unify_query_secure(key_name, &isSecure);
271 if (ret) {
272 ALOGE("%s, %s query secure error\n",__FUNCTION__, key_name);
273 return -1;
274 }
275 if (isSecure) {
276 ALOGE("%s, %s is secure key\n",__FUNCTION__, key_name);
277 return -1;
278 }
279 // end check the key is secure?
280
281 // start read and check data integrity
282 ret = key_unify_query_size(key_name, &key_size);
283 if (ret) {
284 ALOGE("%s, %s query size error\n",__FUNCTION__, key_name);
285 return -1;
286 }
287 //ALOGD("%s, %s size: %d\n",__FUNCTION__, key_name, (int)key_size);
288
289 key_len = (int)key_size;
290 //ALOGD("%s, %s size: %d\n",__FUNCTION__, key_name, key_len);
291
292 return key_len;
293}
294
295int readUKeyData_no_header(const char *key_name, unsigned char data_buf[], int rd_size) {
296 int ret = 0, key_len = 0;
297
298 key_len = checkUnifyKey(key_name);
299 if (key_len < 0) {
300 return -1;
301 } else if (key_len == 0) {
302 ALOGE("%s, %s size is zero\n",__FUNCTION__, key_name);
303 return -1;
304 } else if (key_len > rd_size) {
305 ALOGE("%s, %s key len is larger than rd size.\n",__FUNCTION__, key_name);
306 return -1;
307 }
308
309 ret = key_unify_read(key_name, data_buf, key_len);
310 if (ret) {
311 ALOGE("%s, %s unify read error\n",__FUNCTION__, key_name);
312 return -1;
313 }
314
315 return key_len;
316}
317
318int readUKeyData(const char *key_name, unsigned char data_buf[], int rd_size) {
319 int i = 0, ret = 0, key_len = 0, retry_cnt = 0, tmp_content_type = 0;
320 unsigned int key_crc = 0, key_crc32 = 0, tmp_len = 0, tmp_crc = 0;
321 struct all_info_header_s *pHeadPtr = NULL;
322
323 key_len = checkUnifyKey(key_name);
324 if (key_len < 0) {
325 return -1;
326 } else if (key_len == 0) {
327 ALOGE("%s, %s size is zero\n",__FUNCTION__, key_name);
328 return -1;
329 } else if (key_len > rd_size) {
330 ALOGE("%s, %s key len is larger than rd size.\n",__FUNCTION__, key_name);
331 return -1;
332 }
333
334unifykey_read:
335 ret = key_unify_read(key_name, data_buf, key_len);
336 if (ret) {
337 ALOGE("%s, %s unify read error\n",__FUNCTION__, key_name);
338 return -1;
339 }
340
341 //judge unfikey data type, default is binary data
342 tmp_content_type = 0;
343 for (i = 0; i < 14; i++) {
344 if (i < 8 || (i > 9 && i < 13)) {
345 if (!isxdigit(data_buf[i])) {
346 break;
347 }
348 } else if (i == 8 || i == 13) {
349 if (data_buf[i] != ',') {
350 break;
351 }
352 } else if (i == 9) {
353 if (data_buf[i] != 'V' && data_buf[i] != 'v') {
354 break;
355 }
356 }
357 }
358
359 if (i == 14) {
360 tmp_content_type = 1;
361 }
362
363 tmp_crc = 0;
364 tmp_len = 0;
365 if (tmp_content_type == 0) {
366 pHeadPtr = (struct all_info_header_s *)(data_buf);
367 tmp_crc = pHeadPtr->crc32;
368 tmp_len = pHeadPtr->data_len;
369 } else {
370 return key_len;
371 }
372
373 if (key_len != tmp_len) {
374 ALOGE("%s, %s data_len %d is not match key_len %d\n",__FUNCTION__,
375 key_name, tmp_len, key_len);
376 if (retry_cnt < CC_UKEY_RETRY_CNT_MAX) {
377 retry_cnt++;
378 goto unifykey_read;
379 } else {
380 ALOGE("%s, %s load unifykey failed\n",__FUNCTION__, key_name);
381 return -1;
382 }
383 }
384
385 key_crc = crc32(0, &data_buf[4], (key_len - 4)); //except crc32
386 key_crc32 = (unsigned int)key_crc;
387 if (key_crc32 != tmp_crc) {
388 ALOGE("%s, %s crc32 0x%08x is not match 0x%08x\n",__FUNCTION__,
389 key_name, tmp_crc, key_crc32);
390 if (retry_cnt < CC_UKEY_RETRY_CNT_MAX) {
391 retry_cnt++;
392 goto unifykey_read;
393 } else {
394 ALOGE("%s, %s load unifykey failed\n",__FUNCTION__, key_name);
395 return -1;
396 }
397 }
398 // end read and check data integrity
399
400 return key_len;
401}
402
403int writeUKeyData(const char *key_name, unsigned char data_buf[], int wr_size) {
404 // if the key is not burn data, the fucntion will return fail
405 // now we disable the unifykey check function.
406/*
407 int key_len = 0;
408
409 key_len = checkUnifyKey(key_name);
410 if (key_len < 0) {
411 return -1;
412 }
413*/
414 if (key_unify_write(key_name, data_buf, wr_size) == 0) {
415 return wr_size;
416 }
417 return -1;
418}
419
420#endif
421
422#endif
423
424#if (defined CC_UBOOT_RW_SIMULATE)
425
426#include "ini_io.h"
427
428unsigned int crc32(unsigned int crc, const unsigned char *ptr, int buf_len) {
429 return CalCRC32(crc, ptr, buf_len);
430}
431
432static unsigned char gTempBuf[0x400000];
433
434int key_unify_write(const char* keyname, const void* keydata, const unsigned datalen) {
435 int tmp_ret = 0;
436
437 tmp_ret = writeUKeyData(keyname, (unsigned char *)keydata, datalen);
438 if (tmp_ret != datalen) {
439 return -1;
440 }
441 return 0;
442}
443
444int key_unify_read(const char* keyname, void* keydata, const unsigned bufLen) {
445 if (readUKeyData(keyname, (unsigned char *)keydata, CC_ONE_SECTION_SIZE) <= 0) {
446 return -1;
447 }
448
449 return 0;
450}
451
452int key_unify_query_size(const char* keyname, ssize_t *keysize) {
453 int rd_size = 0;
454
455 rd_size = readUKeyData(keyname, gTempBuf, CC_ONE_SECTION_SIZE);
456 if (rd_size > 0) {
457 *keysize = rd_size;
458 return 0;
459 }
460
461 return -1;
462}
463
464int key_unify_query_exist(const char* keyname, int *exist) {
465 if (checkKeyNameInList(keyname) < 0) {
466 ALOGE("%s, key \"%s\" isn't exist in unifykeys list\n", __FUNCTION__, keyname);
467 *exist = 0;
468 return -1;
469 }
470
471 *exist = 1;
472 return 0;
473}
474
475int key_unify_query_secure(const char* keyname, int *isSecure) {
476 *isSecure = 0;
477 return 0;
478}
479
480#endif
481
482#endif //CC_INI_IO_UKEY_USE_OTHER_MODULE