TSB-agent分析

00 前言

开源项目地址:TSB-agent · GitHub

01 编译

操作系统:OpenEuler22.03

安装kernel-devel:

yum install -y kernel-devel

yum install -y kernel-headers

proxy 编译

进入到proxy目录下,执行: make

如果使用的操作系统版本过高,可能会编译失败,报错:

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
/opt/TSB-agent/tss-main/read_sysram/read_sysram.c:116:24: 附注:in expansion of macro ‘THIS_MODULE’
116 | cls = class_create(THIS_MODULE, "memread_cls");
| ^~~~~~~~~~~
In file included from ./include/linux/device.h:31,
from ./include/linux/cdev.h:8,
from /opt/TSB-agent/tss-main/read_sysram/read_sysram.c:4:
./include/linux/device/class.h:236:54: 附注:需要类型‘const char *’,但实参的类型为‘struct module *’
236 | struct class * __must_check class_create(const char *name);
| ~~~~~~~~~~~~^~~~
/opt/TSB-agent/tss-main/read_sysram/read_sysram.c:116:11: 错误:提供给函数‘class_create’的实参太多
116 | cls = class_create(THIS_MODULE, "memread_cls");
| ^~~~~~~~~~~~
./include/linux/device/class.h:236:29: 附注:在此声明
236 | struct class * __must_check class_create(const char *name);
| ^~~~~~~~~~~~
/opt/TSB-agent/tss-main/read_sysram/read_sysram.c: 在文件作用域:
/opt/TSB-agent/tss-main/read_sysram/read_sysram.c:90:20: 警告:‘memread_dev’ defined but not used [-Wunused-variable]
90 | static struct cdev memread_dev;
| ^~~~~~~~~~~
/opt/TSB-agent/tss-main/read_sysram/read_sysram.c:20:22: 警告:‘per_len’ defined but not used [-Wunused-variable]
20 | static unsigned long per_len = 1024;
| ^~~~~~~
cc1:有些警告被当作是错误
make[3]: *** [scripts/Makefile.build:243:/opt/TSB-agent/tss-main/read_sysram/read_sysram.o] 错误 1
make[2]: *** [/usr/src/kernels/6.6.0-111.0.0.114.oe2403sp1.aarch64/Makefile:1924:/opt/TSB-agent/tss-main/read_sysram] 错误 2
make[1]: *** [Makefile:234:__sub-make] 错误 2
make[1]: 离开目录“/usr/src/kernels/6.6.0-111.0.0.114.oe2403sp1.aarch64”
make: *** [Makefile:9:all] 错误 2

只需要将操作系统版本安装正确即可,否则后面还会出现其他报错(过来人的经验😂)

tss 编译

进入到tss-main/read_sysram/目录下,执行: make 进入到tss-main/tcf/scripts 目录下,执行:

1
2
./tcs-com.sh [debug|release] 
./tcf-com.sh [debug|release]

tsb 编译

符号表拷贝:

1
cp -rf tss-main/tcf/scripts/tss/kernel/tcsexModule.symvers tsb/kernel/platform/tcsModule.symvers

进入到tsb目录下,执行:

1
./build_tsb.sh enable_white_not_tpcm

ttm 编译

再进入项目根目录拷贝依赖库:

1
2
3
4
5
6
mkdir -p ttm/platform_term/depend/lib mkdir-p ttm/platform_term/build/ttm/bin 
cp tss-main/tcf/scripts/tss/user/libhttctcf.so ttm/platform_term/depend/lib/
cp tss-main/tcf/scripts/tss/user/libhttctcs.so ttm/platform_term/depend/lib/
cp tsb/tsb/libhttctsb.so ttm/platform_term/depend/lib/
cp tss-main/tcf/scripts/tss/user/libhttcutils.so ttm/platform_term/depend/lib/
cp tss-main/tcf/scripts/tss/user/tcm-lib/lib/libtcm.so ttm/platform_term/depend/lib/

进入到ttm/platform_term/agent/目录下,执行:

1
2
make clean;make 
make install

02 部署运行

部署安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mkdir -p /usr/local/httcsec/conf
mkdir -p /usr/local/httcsec/lib
mkdir -p /usr/local/httcsec/log

cp -rf tss-main/tcf/scripts/tss /usr/local/httcsec/
cp -rf proxy/tpcmproxy /usr/local/httcsec/tss/
cp -rf tss-main/read_sysram/read_sysram.ko /usr/local/httcsec/tss/kernel/
cp -rf tsb/tsb /usr/local/httcsec/
cp -rf ttm/platform_term/build/ttm /usr/local/httcsec/

cp /usr/local/httcsec/tss/user/lib* /usr/local/httcsec/lib-frd
cp /usr/local/httcsec/tss/user/tcm-lib/lib/* /usr/local/httcsec/lib-frd
cp /usr/local/httcsec/tsb/libhttctsb.so /usr/local/httcsec/lib-frd
chmod +x /usr/local/httcsec/tss/srv
chmod +x /usr/local/httcsec/tsb/srv
chmod +x /usr/local/httcsec/ttm/srv

初始化

启动tss服务

1
/usr/local/httcsec/tss/srv start 

报错:
f4b8b8caa807651fd0d96790ae2e439c

全局扫描白名单

1
/usr/local/httcsec/ttm/bin/ht_init scan accuracy_first nounzip 

重置license

1
/usr/local/httcsec/ttm/bin/ht_init reset 

image-20251222194708300

设置管理员

1
/usr/local/httcsec/ttm/bin/ht_init set-admin 

下发全局策略

1
/usr/local/httcsec/ttm/bin/ht_init set-default-policy all 

停止tss服务

1
/usr/local/httcsec/tss/srv stop

启动服务

1
/usr/local/httcsec/ttm/srv start

报错:

e978631f9a2167194b15b9c612448fa9

03 tss-main源码阅读

总体结构

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
- tss-main
|
+-- httcutils/ // 通用工具库,提供底层数据结构和算法封装
| +-- include/httcutils/ // 头文件目录
| | -- list.h // 双向链表定义,Linux 内核风格
| | -- array.h // 动态数组操作接口
| | -- rbtree.h // 红黑树定义,用于高效查找
| | -- jhash.h // Jenkins Hash 算法定义
| | -- mem.h // 内存管理封装(分配/释放/清零)
| | -- file.h // 文件读写操作封装
| | -- debug.h // 调试日志宏定义
| | -- sem.h // 信号量/锁机制封装
| | -- sm2.h/sm3.h/sm4.h // 国密算法头文件
| |
| +-- src/ // 源代码目录
| -- list.c // (通常链表实现在头文件中,或此处包含扩展实现)
| -- array.c // 动态数组实现
| -- jhash.c // Hash 算法实现
| -- mem.c // 内存管理实现
| -- file.c // 文件操作实现
| -- debug.c // 调试功能实现
| +-- sm/ // 国密算法软实现目录
| -- sm2.c // SM2 非对称加密/签名软算法
| -- sm3.c // SM3 哈希摘要软算法
| -- sm4.c // SM4 对称加密软算法
| -- ecc.c // 椭圆曲线基础数学运算
|
+-- tcs/ // 核心服务层 (Trusted Core Services)
| +-- include/ // TCS 公共头文件
| | +-- tcsapi/ // 对外暴露的核心 API 定义
| | | -- tcs_bmeasure.h // 启动度量相关 API
| | | -- tcs_attest.h // 远程证明相关 API
| | | -- tcs_key.h // 密钥管理相关 API
| | | -- tcs_auth.h // 授权与认证 API
| | | -- tcs_policy.h // 策略管理 API
| | | -- tcs_tpcm.h // TPCM 芯片管理 API
| | -- tpcm_command.h // TPCM 硬件指令结构体定义
| |
| +-- tcsapi/ // TCS 接口实现
| | +-- tcsu/ // 用户态库实现 (libtcs.so)
| | | -- tcs.c // 库初始化,设备文件句柄管理
| | | -- transmit.c // 核心传输函数,封装 ioctl 发送命令到内核
| | | -- tcs_attest.c // 远程证明接口的用户态实现
| | | -- tcs_key.c // 密钥管理接口的用户态实现
| | | -- tcs_*.c // 其他各项 API 的参数打包实现
| | |
| | +-- tcsk/ // 内核态模块实现 (tcs.ko)
| | -- tcs.c // 内核模块入口,注册字符设备,ioctl 分发处理
| | -- kutils.c // 内核态辅助工具函数
| | -- tcs_auth.c // 内核侧权限检查逻辑
| | -- tcs_key.c // 内核侧密钥加载与保护逻辑
| | -- smk/ // 内核态使用的国密算法实现
| |
| +-- tdd/ // 可信设备驱动 (Trusted Device Driver)
| | -- tdd.c // 驱动入口,字符设备注册
| | -- tdd_tpcm.c // TPCM 芯片的具体物理通信逻辑
| | -- comm_driver.c // 底层通信协议实现
| |
| +-- tddl/ // 驱动库接口层 (Trusted Device Driver Library)
| | -- tddl.h // TDDL 接口定义
| | -- tpcm_tddl.c // 针对 TPCM 设备的指令封装实现
| | -- tcm_tddl.c // 针对 TCM 设备的指令封装实现
| |
| +-- tcm/ // TCM 协议栈 (可选/遗留支持)
| | +-- lib/ // TCM 2.0 协议的序列化/反序列化库
| |
| +-- mocktsb/ // 仿真环境
| -- tsb_admin.c // 模拟管理功能的桩代码
| -- tsb_measure_user.c // 模拟度量功能的桩代码
|
+-- tcf/ // 框架层 (Trusted Computing Framework)
| +-- include/tcfapi/ // 业务层高级 API 定义
| | -- tcf_file_integrity.h // 文件完整性校验接口
| | -- tcf_process.h // 进程白名单接口
| | -- tcf_config.h // 配置文件解析接口
| |
| +-- src/ // 框架业务逻辑实现
| | -- tcf.c // 框架初始化
| | -- tcf_config.c // 策略配置文件 (.cfg/xml) 解析逻辑
| | -- tcf_file_integrity.c // 实现完整性基线比对逻辑
| | -- tcf_attest.c // 封装复杂的证明流程
| | -- tcf_log_notice.c // 审计日志与报警处理
| |
| +-- utils/ // 命令行工具源码
| | -- get_trust_status.c // 工具:获取当前可信状态
| | -- generate_trust_report.c // 工具:生成可信报告
| |
| +-- scripts/ // 辅助脚本
| -- tcf-test.sh // 自动化测试脚本
|
+-- read_sysram/ // 独立工具
-- read_sysram.c // 读取系统 RAM 信息,可能用于辅助内存度量

mermaid-diagram-2025-12-23-191739

proxy

comm_driver.c

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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <asm/poll.h>
#include <comm_driver.h>
#include <sys/ioctl.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <tpcm_debug.h>
#include <assert.h>

char *strerror(int errnum) ;
#include "message.h"
//#include "tcm_debug.h"
struct share_memory{
uint32_t cmd_type;//????????
int32_t cmd_length;//???????????

uint64_t cmd_sequence;//???????��?
uint64_t cmd_addr_phys;//???????????,????????cmd_header

volatile uint32_t cmd_handled;//??????????????????????????0,TPCM ??????????1,?????????��1????cmd_ret?????cmd_handled?????????0??
int32_t cmd_ret;//?????��???????????TPCM???

int32_t notify_type;//??????
int32_t notify_length;//??????
uint64_t notify_sequence;//????
uint64_t notify_addr_phys;//????????????TPCM????
uint32_t notify_pending;//???????????TPCM????????????0????????????1???????????????��???????????0
uint32_t pad;
//char data_area[0];//??????????????????????????
} __attribute__((packed));

struct command_info_impl{
uint32_t cmd_type;
int32_t cmd_length;
uint64_t cmd_sequence;
uint64_t input_addr;
uint64_t output_addr;
int32_t input_length;
int32_t output_maxlength;
uint32_t out_length;
uint32_t out_return;
MAPObject cmd_map;
uint64_t cmd_vaddr;
MAPObject input_map;
MAPObject output_map;
};

struct cmd_header{
//???????
//uint64_t cmd_sequence;?????????????????????????�?????????????
uint64_t input_addr; //??????????
uint64_t output_addr; //??????????
int32_t input_length; //??????????
int32_t output_maxlength;//??????????????

//???????
// uint64_t cmd_sequence;//???????��??????????????????????????????notify_sequence????
volatile int out_length; //????????????????????
volatile int out_return; //??????��??

} __attribute__((packed));

enum{

//NOTIFY_TYPE_SYNC_FINISHED = 0,//??????????????,?????????
NOTIFY_TYPE_CMD_FINISHED = 1,//?????????????,?????????
//NOTIFY_TYPE_LOG = 1 << 16, //??????,???????????
//NOTIFY_TYPE_CMD_CONTROL//??????????
};
#define ERROR_RET -1
#define SHARE_MEM_SIZE 0x1F00000
#define BIOS_OFFSET 0x3c00
#define NOTIFY_DATA_MASK 0xffff
#define NOTIFY_SIMPLE_MASK 0xffff
#define LISTEN_PORT 6666

struct msg_buff{
uint32_t cmd_type;
int32_t cmd_length;
uint64_t cmd_sequence;

uint64_t cmd_addrnum;
uint64_t input_addr_num;
uint64_t output_addr_num;
int32_t input_length;
int32_t output_maxlength;

int32_t res;

struct cmd_header cmd;
//char input_buff[BMC_BUFF_LENGTH];//tmp
//char output_buff[BMC_BUFF_LENGTH];//tmp

unsigned char *total_buff;
};



static COMMAND_NOIFTY notifier;
MAPObject tpcm_share_mobj;
volatile struct share_memory *sharemem;
unsigned long sharemem_addr;
static uint32_t invalid_command_count = 0;
#define NUM_OF_COMMAND_TYPE 16


//static void test_callback_zero(int msgtype, const char *buffer, int length){
// tpcm_sys_tpcm_debug("buffer:%s,%d, msgtype:%d\n", buffer, length, msgtype);
//}
//void netlink_init(){
//
// int sync = 0, type = 1;
// char message[] = "Open the netlink";
// int length;
// length = sizeof(message);
// httcsec_netlink_send_msg(type, message, length, 0, 0);
//
//
//}

struct notify_info{
int notify_type;
unsigned long notify_sequence;
char buffer[0];
}__attribute__((packed));
//void debug_dump_hex (const void *p, int bytes);
volatile int test_sending = 0;


//---20240311---start
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <getopt.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <asm/poll.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/timeb.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <openssl/evp.h>

#define HOST_DEV_NAME "/dev/memread_dev"
char *DEV_NAME = "/dev/lcd3";

typedef enum {
USB_START_TRANS_REQ = 1,
USB_TRANS_PROCESS,
USB_TRANS_COMPLETE,
USB_START_TRANS_STD_MD5_REQ, // ��iBMCv2���MD5�����MD5�iBMCv3��������������MD5����
USB_START_TRANS_SHA256_REQ, // ��sha256����
USB_START_TRANS_SM3_REQ // ��sm3����
} TPCMUsbMsgType;

typedef unsigned long int u_int64_t;
typedef char gchar;
typedef unsigned char guchar;
typedef unsigned char guint8;
typedef signed char gint8;
typedef short gshort;
typedef signed short gint16;
typedef unsigned short guint16;
typedef int gint;
typedef signed int gint32;
typedef unsigned int guint;
typedef unsigned int guint32;
typedef unsigned short gushort;
typedef long glong;
typedef unsigned long gulong;
typedef signed long long gint64;
typedef unsigned long long guint64;
typedef float gfloat;
typedef double gdouble;
typedef gint gboolean;

#define IPMI_MAX_MSG_LENGTH 2060
#define PRINTED_LINE_SIZE_BIT 128
#define PER_READ_LEN 2048

#define PR_SET_NAME 15 /* Set process name */
#define PR_GET_NAME 16 /* Get process name */

typedef struct tag_usb_buffer_info_s {
guint32 usb_id; /*�������USB�*/
guint32 fn_id; /*���/����function����ID��connect�����fn_id�*/
guint32 len; /* ����/�������*/
guint32 timeout; /*��/����������0�����������
��������us����������MAX_TIMEOUT_US�����*/
guint8 overflow; /*������������������
����������������������1���������*/
guint8 splited; /* �������������������������
����������2������������1
���������*/
guint16 reserved; /*����*/
guint32 result; /*�����*/
guint8 *buf; /* ����/�����buffer*/
} USB_BUF_INFO_S;

typedef struct _edma_head_Message {
guint8
msg_type; // 0x01:���������?0x02 �����������; 0x03: �����? 0x04: ��������?����
guint8 flag; // ��������
guint32 data_len; // �����������?
guint32 offset; // ������������
} EDMA_MSG_HEAD, *P_EDMA_MSG_HEAD;

// edma msg
typedef struct _EDMA_Request {
EDMA_MSG_HEAD head_msg;
guint8 data[IPMI_MAX_MSG_LENGTH - sizeof(EDMA_MSG_HEAD)];
} EDMA_MSG_REQ, *P_EDMA_MSG_REQ;

#define MD5_DIGEST_LEN 16
#define MD5_CTX_STAT_LEN 4
#define MD5_CTX_CNT_LEN 2
#define MD5_CTX_BUF_LEN 64

#define MD5_11 7
#define MD5_12 12
#define MD5_13 17
#define MD5_14 22
#define MD5_21 5
#define MD5_22 9
#define MD5_23 14
#define MD5_24 20
#define MD5_31 4
#define MD5_32 11
#define MD5_33 16
#define MD5_34 23
#define MD5_41 6
#define MD5_42 10
#define MD5_43 15
#define MD5_44 21

typedef guchar *P_BUFFER_T;
typedef gulong UL;

#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~(z))))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~(z))))
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
#define FF(a, b, c, d, x, s, ac) \
do { \
(a) += F((b), (c), (d)) + (x) + (UL)(ac); \
(a) = ROTATE_LEFT((a), (s)); \
(a) += (b); \
} while (0)
#define GG(a, b, c, d, x, s, ac) \
do { \
(a) += G((b), (c), (d)) + (x) + (UL)(ac); \
(a) = ROTATE_LEFT((a), (s)); \
(a) += (b); \
} while (0)
#define HH(a, b, c, d, x, s, ac) \
do { \
(a) += H((b), (c), (d)) + (x) + (UL)(ac); \
(a) = ROTATE_LEFT((a), (s)); \
(a) += (b); \
} while (0)
#define II(a, b, c, d, x, s, ac) \
do { \
(a) += I((b), (c), (d)) + (x) + (UL)(ac); \
(a) = ROTATE_LEFT((a), (s)); \
(a) += (b); \
} while (0)

#if PROTOTYPES
#define PROTOTYPE_LIST(list) list
#else
#define PROTOTYPE_LIST(list) ()
#endif

#define MD5_DIGEST_LEN 16
#define MD5_CTX_STAT_LEN 4
#define MD5_CTX_CNT_LEN 2
#define MD5_CTX_BUF_LEN 64
#define LOCAL static

/* MD5 context. */
typedef struct {
UL state[MD5_CTX_STAT_LEN]; /* state (ABCD) */
UL count[MD5_CTX_CNT_LEN]; /* number of bits, modulo 2^64 (lsb first) */
guchar buffer[MD5_CTX_BUF_LEN]; /* input buffer */
} MD5_CTX;

void MD5Init(MD5_CTX *);
void MD5Update(MD5_CTX *, guchar *, guint);
void MD5Final(guchar[MD5_DIGEST_LEN], MD5_CTX *, guint32 length);
LOCAL void MD5Transform(UL[MD5_CTX_STAT_LEN], guint, guchar[MD5_CTX_BUF_LEN]);

LOCAL guchar g_padding[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

LOCAL void MD5Transform(UL[MD5_CTX_STAT_LEN], guint, guchar[MD5_CTX_BUF_LEN]);
LOCAL void UL2UC(guchar *, UL *, guint);
LOCAL void UC2UL(UL *, guchar *, guint);
/*****************************************************************************
� � � : MD5Init
���� : MD5�����
���� : MD5_CTX *md5_ctx
���� : �
� � � :

���� :
1.� � : 2012�5�11�
� � :
���� : �����

*****************************************************************************/
void MD5Init(MD5_CTX *md5_ctx)
{
md5_ctx->count[0] = md5_ctx->count[1] = 0;

// ���magic number
md5_ctx->state[0] = 0x67452301;
md5_ctx->state[1] = 0xefcdab89;
md5_ctx->state[2] = 0x98badcfe;
md5_ctx->state[3] = 0x10325476;
}

/*****************************************************************************
� � � : MD5Update
���� : ��MD5�����
���� : MD5_CTX *md5_ctx
guchar *input
guint inputLen
���� : �
� � � :

���� :
1.� � : 2012�5�11�
� � :
���� : �����

*****************************************************************************/
void MD5Update(MD5_CTX *md5_ctx, guchar *input, guint inputLen)
{
guint i, index, partLen;

index = (guint)((md5_ctx->count[0] >> 3) & 0x3F);

if ((md5_ctx->count[0] += ((UL)inputLen << 3)) < ((UL)inputLen << 3)) {
md5_ctx->count[1]++;
}

md5_ctx->count[1] += ((UL)inputLen >> 29);

partLen = 64 - index;

if (inputLen >= partLen) {
memcpy((P_BUFFER_T)&md5_ctx->buffer[index], (P_BUFFER_T)input, partLen);
MD5Transform(md5_ctx->state, MD5_CTX_STAT_LEN, md5_ctx->buffer);

for (i = partLen; i + 63 < inputLen; i += 64) {
MD5Transform(md5_ctx->state, MD5_CTX_STAT_LEN, &input[i]);
}

index = 0;
} else {
i = 0;
}
memcpy((P_BUFFER_T)&md5_ctx->buffer[index], (P_BUFFER_T)&input[i], inputLen - i);
}

/*****************************************************************************
� � � : MD5Final
���� : ��MD5�����
���� : guchar *digest:��buffer
MD5_CTX *md5_ctx: md5��
length: buffer��
���� : �
� � � :

���� :
1.� � : 2012�5�11�
� � :
���� : �����

*****************************************************************************/
void MD5Final(guchar *digest, MD5_CTX *md5_ctx, guint32 length)
{
guchar bits[8];
guint index, padLen;

UL2UC(bits, md5_ctx->count, 8);

index = (guint)((md5_ctx->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update(md5_ctx, g_padding, padLen);

MD5Update(md5_ctx, bits, 8);

UL2UC(digest, md5_ctx->state, length);

memset((P_BUFFER_T)md5_ctx, 0, sizeof(*md5_ctx));
}

/*****************************************************************************
� � � : MD5Transform
���� : MD5��
���� : UL *state: MD5��
guint32 state_len: state buffer��
guchar *block: input buffer
���� : �
� � � : LOCAL

���� :
1.� � : 2012�5�11�
� � :
���� : �����

*****************************************************************************/
LOCAL void MD5Transform(UL *state, guint32 state_len, guchar *block)
{
UL xa;
UL xb;
UL xc;
UL xd;
UL x[MD5_DIGEST_LEN] = {0};

if (state_len != MD5_CTX_STAT_LEN) {
return;
}

xa = state[0]; /* 0:��0 */
xb = state[1]; /* 1:��1 */
xc = state[2]; /* 2:��2 */
xd = state[3]; /* 3:��3 */

UC2UL(x, block, 64);

/* Round 1 */
FF(xa, xb, xc, xd, x[0], MD5_11, 0xd76aa478); /* 0:�������1 */
FF(xd, xa, xb, xc, x[1], MD5_12, 0xe8c7b756); /* 1:�������2 */
FF(xc, xd, xa, xb, x[2], MD5_13, 0x242070db); /* 2:�������3 */
FF(xb, xc, xd, xa, x[3], MD5_14, 0xc1bdceee); /* 3:�������4 */
FF(xa, xb, xc, xd, x[4], MD5_11, 0xf57c0faf); /* 4:�������5 */
FF(xd, xa, xb, xc, x[5], MD5_12, 0x4787c62a); /* 5:�������6 */
FF(xc, xd, xa, xb, x[6], MD5_13, 0xa8304613); /* 6:�������7 */
FF(xb, xc, xd, xa, x[7], MD5_14, 0xfd469501); /* 7:�������8 */
FF(xa, xb, xc, xd, x[8], MD5_11, 0x698098d8); /* 8:�������9 */
FF(xd, xa, xb, xc, x[9], MD5_12, 0x8b44f7af); /* 9:�������10 */
FF(xc, xd, xa, xb, x[10], MD5_13, 0xffff5bb1); /* 10:�������11 */
FF(xb, xc, xd, xa, x[11], MD5_14, 0x895cd7be); /* 11:�������12 */
FF(xa, xb, xc, xd, x[12], MD5_11, 0x6b901122); /* 12:�������13 */
FF(xd, xa, xb, xc, x[13], MD5_12, 0xfd987193); /* 13:�������14 */
FF(xc, xd, xa, xb, x[14], MD5_13, 0xa679438e); /* 14:�������15 */
FF(xb, xc, xd, xa, x[15], MD5_14, 0x49b40821); /* 15:�������16 */

/* Round 2 */
GG(xa, xb, xc, xd, x[1], MD5_21, 0xf61e2562); /* 1:�������17 */
GG(xd, xa, xb, xc, x[6], MD5_22, 0xc040b340); /* 6:�������18 */
GG(xc, xd, xa, xb, x[11], MD5_23, 0x265e5a51); /* 11:�������19 */
GG(xb, xc, xd, xa, x[0], MD5_24, 0xe9b6c7aa); /* 0:�������20 */
GG(xa, xb, xc, xd, x[5], MD5_21, 0xd62f105d); /* 5:�������21 */
GG(xd, xa, xb, xc, x[10], MD5_22, 0x2441453); /* 10:�������22 */
GG(xc, xd, xa, xb, x[15], MD5_23, 0xd8a1e681); /* 15:�������23 */
GG(xb, xc, xd, xa, x[4], MD5_24, 0xe7d3fbc8); /* 4:�������24 */
GG(xa, xb, xc, xd, x[9], MD5_21, 0x21e1cde6); /* 9:�������25 */
GG(xd, xa, xb, xc, x[14], MD5_22, 0xc33707d6); /* 14:�������26 */
GG(xc, xd, xa, xb, x[3], MD5_23, 0xf4d50d87); /* 3:�������27 */
GG(xb, xc, xd, xa, x[8], MD5_24, 0x455a14ed); /* 8:�������28 */
GG(xa, xb, xc, xd, x[13], MD5_21, 0xa9e3e905); /* 13:�������29 */
GG(xd, xa, xb, xc, x[2], MD5_22, 0xfcefa3f8); /* 2:�������30 */
GG(xc, xd, xa, xb, x[7], MD5_23, 0x676f02d9); /* 7:�������31 */
GG(xb, xc, xd, xa, x[12], MD5_24, 0x8d2a4c8a); /* 12:�������32 */

/* Round 3 */
HH(xa, xb, xc, xd, x[5], MD5_31, 0xfffa3942); /* 5:�������33 */
HH(xd, xa, xb, xc, x[8], MD5_32, 0x8771f681); /* 8:�������34 */
HH(xc, xd, xa, xb, x[11], MD5_33, 0x6d9d6122); /* 11:�������35 */
HH(xb, xc, xd, xa, x[14], MD5_34, 0xfde5380c); /* 14:�������36 */
HH(xa, xb, xc, xd, x[1], MD5_31, 0xa4beea44); /* 1:�������37 */
HH(xd, xa, xb, xc, x[4], MD5_32, 0x4bdecfa9); /* 4:�������38 */
HH(xc, xd, xa, xb, x[7], MD5_33, 0xf6bb4b60); /* 7:�������39 */
HH(xb, xc, xd, xa, x[10], MD5_34, 0xbebfbc70); /* 10:�������40 */
HH(xa, xb, xc, xd, x[13], MD5_31, 0x289b7ec6); /* 13:�������41 */
HH(xd, xa, xb, xc, x[0], MD5_32, 0xeaa127fa); /* 0:�������42 */
HH(xc, xd, xa, xb, x[3], MD5_33, 0xd4ef3085); /* 3:�������43 */
HH(xb, xc, xd, xa, x[6], MD5_34, 0x4881d05); /* 6:�������44 */
HH(xa, xb, xc, xd, x[9], MD5_31, 0xd9d4d039); /* 9:�������45 */
HH(xd, xa, xb, xc, x[12], MD5_32, 0xe6db99e5); /* 12:�������46 */
HH(xc, xd, xa, xb, x[15], MD5_33, 0x1fa27cf8); /* 15:�������47 */
HH(xb, xc, xd, xa, x[2], MD5_34, 0xc4ac5665); /* 2:�������48 */

/* Round 4 */
II(xa, xb, xc, xd, x[0], MD5_41, 0xf4292244); /* 0:�������49 */
II(xd, xa, xb, xc, x[7], MD5_42, 0x432aff97); /* 7:�������50 */
II(xc, xd, xa, xb, x[14], MD5_43, 0xab9423a7); /* 14:�������51 */
II(xb, xc, xd, xa, x[5], MD5_44, 0xfc93a039); /* 5:�������52 */
II(xa, xb, xc, xd, x[12], MD5_41, 0x655b59c3); /* 12:�������53 */
II(xd, xa, xb, xc, x[3], MD5_42, 0x8f0ccc92); /* 3:�������54 */
II(xc, xd, xa, xb, x[10], MD5_43, 0xffeff47d); /* 10:�������55 */
II(xb, xc, xd, xa, x[1], MD5_44, 0x85845dd1); /* 1:�������56 */
II(xa, xb, xc, xd, x[8], MD5_41, 0x6fa87e4f); /* 8:�������57 */
II(xd, xa, xb, xc, x[15], MD5_42, 0xfe2ce6e0); /* 15:�������58 */
II(xc, xd, xa, xb, x[6], MD5_43, 0xa3014314); /* 6:�������59 */
II(xb, xc, xd, xa, x[13], MD5_44, 0x4e0811a1); /* 13:�������60 */
II(xa, xb, xc, xd, x[4], MD5_41, 0xf7537e82); /* 4:�������61 */
II(xd, xa, xb, xc, x[11], MD5_42, 0xbd3af235); /* 11:�������62 */
II(xc, xd, xa, xb, x[2], MD5_43, 0x2ad7d2bb); /* 2:�������63 */
II(xb, xc, xd, xa, x[9], MD5_44, 0xeb86d391); /* 9:�������64 */

state[0] += xa; /* 0:��0 */
state[1] += xb; /* 1:��1 */
state[2] += xc; /* 2:��2 */
state[3] += xd; /* 3:��3 */

memset((P_BUFFER_T)x, 0, sizeof(x));
}

/*****************************************************************************
� � � : UL2UC
���� : �gulong�����guchar��
���� : guchar *output
UL *input
guint len
���� : �
� � � : LOCAL

���� :
1.� � : 2012�5�11�
� � :
���� : �����

*****************************************************************************/
LOCAL void UL2UC(guchar *output, UL *input, guint len)
{
guint i, j;

for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (guchar)(input[i] & 0xff);
output[j + 1] = (guchar)((input[i] >> 8) & 0xff); /*lint !e661*/
output[j + 2] = (guchar)((input[i] >> 16) & 0xff); /*lint !e661 !e662*/
output[j + 3] = (guchar)((input[i] >> 24) & 0xff); /*lint !e661 !e662*/
}
}

/*****************************************************************************
� � � : UC2UL
���� : �guchar�����gulong��
���� : UL *output
guchar *input
guint len
���� : �
� � � : LOCAL
���� :

���� :
1.� � : 2012�5�11�
� � :
���� : �����

*****************************************************************************/
LOCAL void UC2UL(UL *output, guchar *input, guint len)
{
guint i, j;

for (i = 0, j = 0; j < len; i++, j += 4) {
output[i] = ((UL)input[j]) | (((UL)input[j + 1]) << 8) | /*lint !e661 !e662*/
(((UL)input[j + 2]) << 16) | (((UL)input[j + 3]) << 24); /*lint !e661 !e662*/
}
}
guchar g_digest[32];
guint g_digest_len = 0;
int md5check(const char *buf, int inputlen)
{
memset(g_digest, 0, 32);
gchar encodedDigest[25];
MD5_CTX context;
guint32 i;
gchar *p = NULL;
MD5Init(&context);
MD5Update(&context, buf, inputlen);
MD5Final(g_digest, &context, MD5_DIGEST_LEN);
g_digest_len = MD5_DIGEST_LEN;
}

/* ============================= MD5�����openssl���� ============================= */
static void md5check_std(guint8 *buf, gint32 inputlen)
{
memset(g_digest, 0, 32);
EVP_MD_CTX *mdctx;
guint32 md5_digest_len = (guint32)EVP_MD_size(EVP_md5());

// MD5_Init
mdctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);

// MD5_Update
EVP_DigestUpdate(mdctx, buf, inputlen);

// MD5_Final
guint8 *md5_digest = (guint8 *)OPENSSL_malloc(md5_digest_len);
EVP_DigestFinal_ex(mdctx, md5_digest, &md5_digest_len);
EVP_MD_CTX_free(mdctx);

memcpy(g_digest, md5_digest, md5_digest_len);
OPENSSL_free(md5_digest);
g_digest_len = md5_digest_len;
}

/*
* Description: ��sm3
*/
static void sm3hash(unsigned char *input, unsigned int input_len)
{
memset(g_digest, 0, 32);
EVP_MD_CTX *md_ctx;
const EVP_MD *md;

md = EVP_sm3();
md_ctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(md_ctx, md, NULL);
EVP_DigestUpdate(md_ctx, input, input_len);
EVP_DigestFinal_ex(md_ctx, g_digest, &g_digest_len);
EVP_MD_CTX_free(md_ctx);
}

/*
* Description: ��sha256
*/
static void sha256hash(unsigned char *input, unsigned int input_len)
{
memset(g_digest, 0, 32);
EVP_MD_CTX *md_ctx;
const EVP_MD *md;

md = EVP_sha256();
md_ctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(md_ctx, md, NULL);
EVP_DigestUpdate(md_ctx, input, input_len);
EVP_DigestFinal_ex(md_ctx, g_digest, &g_digest_len);
EVP_MD_CTX_free(md_ctx);
}

unsigned long DEV_ADDR = 0;
unsigned long DATA_LEN = 0;

int ADDR_LEN = 0;
guint8 *COM_DATA = NULL;
unsigned int OFFSET = 0;

int g_edmaUsbFd = -1;
int trans_len = 0;

int prepare_data(EDMA_MSG_REQ msg_read, TPCMUsbMsgType msg_type)
{
FILE *file_handle = NULL;
time_t tmpcal_ptr;
struct tm *tmp_ptr = NULL;
memcpy(&DEV_ADDR, msg_read.data, sizeof(unsigned long));
//printf("addr = 0x%lx ", DEV_ADDR);

memcpy(&DATA_LEN, msg_read.data + sizeof(unsigned long), sizeof(unsigned long));
//printf("datalen = %lu\n", DATA_LEN);

COM_DATA = (guint8 *)malloc(DATA_LEN);
memset(COM_DATA, 0, DATA_LEN);

int fd = open(HOST_DEV_NAME, O_RDONLY);
if (fd == -1) {
printf("file %s is opening......failure!", HOST_DEV_NAME);
return -1;
} else {
//printf("file %s is opening......successfully!\nits fd is %d\n", HOST_DEV_NAME, fd);
}
int ret = 0;

unsigned long cur_len = DATA_LEN;
unsigned long cur_pos = DEV_ADDR;
guint8 *tmp_buf = COM_DATA;

while (0 < cur_len) {
if (cur_len < PER_READ_LEN) {
ret = ioctl(fd, 0, cur_pos);
ret = ioctl(fd, 1, cur_len);
ret = read(fd, tmp_buf, cur_len);
if (ret == -1) {
goto error;
}
cur_len = cur_len - cur_len;
tmp_buf = tmp_buf + cur_len;
cur_pos = cur_pos + cur_len;
} else {
ret = ioctl(fd, 0, cur_pos);
ret = ioctl(fd, 1, PER_READ_LEN);
ret = read(fd, tmp_buf, PER_READ_LEN);
if (ret == -1) {
goto error;
}
cur_len = cur_len - PER_READ_LEN;
tmp_buf = tmp_buf + PER_READ_LEN;
cur_pos = cur_pos + PER_READ_LEN;
}
}
if (msg_type == USB_START_TRANS_REQ) {
md5check(COM_DATA, DATA_LEN);
} else if (msg_type == USB_START_TRANS_STD_MD5_REQ) {
md5check_std(COM_DATA, DATA_LEN);
} else if (msg_type == USB_START_TRANS_SHA256_REQ) {
sha256hash(COM_DATA, DATA_LEN);
} else if (msg_type == USB_START_TRANS_SM3_REQ) {
sm3hash(COM_DATA, DATA_LEN);
} else {
//printf("msg_type(%d) cannot support to calculate md5\n", msg_type);
goto error;
}
//printf("total digest(type: %d):\n", msg_type);
for (int i = 0; i < g_digest_len; i++) {
//printf("%02x ", g_digest[i]);
}
//printf("\n");

close(fd);
return 0;
error:
close(fd);
return -2;
}

int send_response(int prepare) //
{
int prepare_stat = 0x00;
if (prepare == 0) {
prepare_stat = 0x00;
} else if (prepare == -1) {
prepare_stat = 0x01;
} else {
prepare_stat = 0x02;
}

EDMA_MSG_REQ msg_write = {0};
msg_write.head_msg.msg_type = 0x01;
msg_write.head_msg.flag = prepare_stat;
msg_write.head_msg.offset = 0x00;
msg_write.head_msg.data_len = 0;

gint32 ret = write(g_edmaUsbFd, &msg_write, sizeof(EDMA_MSG_HEAD));
return ret;
}

guint8 pmbus_crc8_make_bitwise(const guint8 *buf, guint16 size)
{
#define CHAR_BITS 8
#define CRC8_POLY 0x07
#define CRC8_INIT_REM 0x0
guint16 i;
guint8 j;
guint8 crc = CRC8_INIT_REM;

for (i = 0; i < size; i++) {
crc ^= buf[i];

for (j = 0; j < CHAR_BITS; j++) { /* � byte � bit �� */
if (crc & 0x80) {
crc <<= 1;
crc ^= CRC8_POLY;
} else {
crc <<= 1;
}
}
}

return crc;
}

int write_data()
{
EDMA_MSG_HEAD msg_hdr = {0};
msg_hdr.msg_type = 0x02;
guint8 checksum;
int max_data_len = IPMI_MAX_MSG_LENGTH - sizeof(EDMA_MSG_HEAD);
int digest_len = g_digest_len;

int remain_data_len = DATA_LEN - OFFSET; // �������?
if (remain_data_len <= max_data_len) {
trans_len = remain_data_len + digest_len;
msg_hdr.flag = 0x01;
} else {
trans_len = max_data_len;
msg_hdr.flag = 0x00;
}

msg_hdr.offset = OFFSET;
msg_hdr.data_len = trans_len;

int ret = write(g_edmaUsbFd, &msg_hdr, sizeof(EDMA_MSG_HEAD));

guint8 *msg_data = (guint8 *)malloc(trans_len);
if (msg_hdr.flag == 0x01) {
for (int i = 0; i < digest_len; i++) {
msg_data[trans_len - digest_len + i] = g_digest[i];
}
for (int i = trans_len - digest_len; i > 0; i--) {
msg_data[trans_len - digest_len - i] = COM_DATA[OFFSET + trans_len - digest_len - i];
}
} else {
for (int i = trans_len; i > 0; i--) {
msg_data[trans_len - i] = COM_DATA[OFFSET + trans_len - i];
}
}

ret = write(g_edmaUsbFd, msg_data, trans_len);
free(msg_data);
OFFSET = OFFSET + trans_len; // ���������?
}

void EdmaUsbLcd2ReadTask(void)
{
gint32 ret = -1;
USB_BUF_INFO_S buff_info;
gchar edma_buf[40] = {0};
EDMA_MSG_REQ msg_read = {0};
int retry = 0;

struct pollfd client = {};
client.fd = g_edmaUsbFd;
client.events = POLLRDNORM | POLLIN;
//printf("listening on %s ... \n", DEV_NAME);
unsigned char *pp;

while (1) {
ret = poll(&client, 1, 1000);
if (ret) {
if (client.revents & client.events) {
ret = read(g_edmaUsbFd, &msg_read.head_msg, sizeof(EDMA_MSG_HEAD));
if (ret < 0) {
retry++;

if (retry >= 3) {
//printf("close\n");
close(g_edmaUsbFd);
DEV_ADDR = 0;
DATA_LEN = 0;
OFFSET = 0;
if (COM_DATA != NULL) {
free(COM_DATA);
COM_DATA = NULL;
}
return;
}

continue;
} else if (ret > 0) {
if (msg_read.head_msg.data_len > 0) {
read(g_edmaUsbFd, msg_read.data, 2 * sizeof(gulong));
}

if (msg_read.head_msg.msg_type == USB_START_TRANS_REQ ||
msg_read.head_msg.msg_type == USB_START_TRANS_STD_MD5_REQ ||
msg_read.head_msg.msg_type == USB_START_TRANS_SHA256_REQ ||
msg_read.head_msg.msg_type ==
USB_START_TRANS_SM3_REQ) { // �������?x01��������������
int prepare =
prepare_data(msg_read, msg_read.head_msg.msg_type); // prepare 0�������?������
send_response(prepare);
} else if (msg_read.head_msg.msg_type ==
USB_TRANS_PROCESS) { // �������?x02�����������
write_data();
} else if (msg_read.head_msg.msg_type ==
USB_TRANS_COMPLETE) { // �����?x03�����������������������?
DEV_ADDR = 0;
DATA_LEN = 0;
OFFSET = 0;
if (COM_DATA != NULL) {
free(COM_DATA);
COM_DATA = NULL;
}
close(g_edmaUsbFd);
g_edmaUsbFd = -1;
return;
} else { // ���������?
//printf("The request code is incorrect: 0x%x", msg_read.head_msg.msg_type);
return;
}
}
}
}
}
}

void ready_to_usb()
{
char s1[30] = {0};
char s2[30] = {0};
char s3[30] = {0};
while (1) {
g_edmaUsbFd = open(DEV_NAME, O_RDWR | O_NONBLOCK);
if (g_edmaUsbFd < 0) {
sleep(1);
continue;
}
break;
}

EdmaUsbLcd2ReadTask();

//printf("end\n");
}

int main_loop()
{
while (1) {
int fd = open("usblockfile", O_RDWR | O_CREAT, 0666);
if (fd == -1) {
printf("open fail, errno = %d:%s\n", errno, strerror(errno));
sleep(5);
continue;
}

if (flock(fd, LOCK_EX) == -1) {
printf("flock fail, errno = %d:%s\n", errno, strerror(errno));
close(fd);
sleep(5);
continue;
}

// ���������
//printf("start open usb\n");
ready_to_usb();
sleep(1);

flock(fd, LOCK_UN);
close(fd);
}
}

//---20240311---end



int socket_tcpsocket_connect(char *ip, int port)
{
assert(ip);

struct sockaddr_in serveraddr;
struct timeval tm = {1, 0};
socklen_t len = sizeof(tm);

int sockfd = socket(AF_INET, SOCK_STREAM, 0);

if (sockfd < 0)
return -1;

setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tm, len);

bzero(&serveraddr, sizeof(struct sockaddr_in));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(ip);
serveraddr.sin_port = htons(port);

if (connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(struct sockaddr_in)) < 0) {
close(sockfd);
tpcm_debug( "connect fail, server IP :%s, port :%d, errmsg: %s", ip, port, strerror(errno));
printf( "connect fail, server IP :%s, port :%d, errmsg: %s %ld\n", ip, port, strerror(errno),time(NULL));
return -1;
}

tpcm_debug("new connect to server IP :%s, port :%d, fd: %d", ip, port, sockfd);
printf("new connect to server IP :%s, port :%d, fd: %d\n", ip, port, sockfd);
return sockfd;
}

#if 0
int socket_tcpv6socket_connect(char *ip, int port)
{
assert(ip);

struct sockaddr_in6 serveraddr;
struct timeval tm = {1, 0};
socklen_t len = sizeof(tm);

int sockfd = socket(AF_INET6, SOCK_STREAM, 0);

if (sockfd < 0)
return -1;

setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tm, len);

bzero(&serveraddr, sizeof(struct sockaddr_in6));
serveraddr.sin6_family = AF_INET6;
//serveraddr.sin_addr.s_addr = inet_addr(ip);
inet_pton(AF_INET6, ip, &serveraddr.sin6_addr);
serveraddr.sin6_port = htons(port);
serveraddr.sin6_scope_id = if_nametoindex("enp125s0f3");

if (connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(struct sockaddr_in)) < 0) {
close(sockfd);
printf( "connect fail, server IP :%s, port :%d, errmsg: %s", ip, port, strerror(errno));
return -1;
}

tpcm_debug("new connect to server IP :%s, port :%d, fd: %d", ip, port, sockfd);
return sockfd;
}
#else

int socket_tcpv6socket_connect(char *ip, int port)
{
int sk;
int ret = 0;
int retry = 0;
struct sockaddr_in6 addr;

//struct sockaddr_in6 laddr;

sk = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (sk < 0) {
return -1;
}

// memset(&laddr, 0, sizeof(laddr));
//laddr.sin6_family = AF_INET6;
//laddr.sin6_port = htons(8092);
//laddr.sin6_scope_id = if_nametoindex("veth");
//ret = inet_pton(AF_INET6, "fe80::9e7d:a3ff:fe28:6ff9", &laddr.sin6_addr);
//if (ret <= 0) {
// printf("Can't convert addr\n");
// return -1;
// }

// if(bind(sk,(struct sockaddr_in6*)&laddr,sizeof(struct sockaddr_in6)) != 0){
// printf("can't connect local ipv6 addr\n");
// close(sk);
// return -1;
// }

//printf("Connecting to %s:%d\n", ip, port);
memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
ret = inet_pton(AF_INET6, ip, &addr.sin6_addr);
if (ret <= 0) {
printf("Can't convert addr\n");
return -1;
}
addr.sin6_port = htons(port);
//addr.sin6_scope_id = if_nametoindex("enp125s0f3");
addr.sin6_scope_id = if_nametoindex("veth");

tpcm_debug("before connect ,ip %s,port %d\n",ip,port);
ret = connect(sk, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0) {
tpcm_debug("Can't connect,ip %s,port %d, err:%s\n",ip,port,strerror(errno));
}


tpcm_debug("connect,ip %s,port %d\n",ip,port);

return sk;

}

#endif



void os_handle(int msgtype, const char *buffer, int length){

unsigned char cmd[1024] = {0};
uint64_t cmd_addr_phys;
int bmc_sockfd = 0;
struct command_info_impl info;
MAPObject mobj = NULL;
struct cmd_header *vadrr =NULL;
memset(&info,0,sizeof(info));
info.cmd_sequence = sharemem->cmd_sequence;
info.cmd_type = sharemem->cmd_type;
if(info.cmd_type == TDD_CMD_CATEGORY_INIT)
info.cmd_type = TDD_CMD_CATEGORY_TPCM;
info.cmd_length = sharemem->cmd_length;
cmd_addr_phys = sharemem->cmd_addr_phys;
tpcm_debug("Normal Command type=%u seq = %lx, addr = %lx,length=%u\n",info.cmd_type,
info.cmd_sequence,cmd_addr_phys,info.cmd_length);





if(info.cmd_type == TDD_CMD_CATEGORY_RESERVED_4){
tpcm_error("Invalid command type=%u seq = %lx, addr = %lx,length=%u\n",info.cmd_type,
info.cmd_sequence,cmd_addr_phys,info.cmd_length);
sharemem->cmd_ret = TPCM_ERROR_INVALID_COMMAND;
//asm volatile ("dsb st");
sharemem->cmd_handled = 1;
invalid_command_count++;
test_sending = 1;
//asm volatile ("dsb st");
//return ;
}

if(!cmd_addr_phys || !info.cmd_length || info.cmd_length > 0x200000){
tpcm_error("Invalid command type=%u seq = %lx, addr = %lx,length=%u\n",info.cmd_type,
info.cmd_sequence,cmd_addr_phys,info.cmd_length);
sharemem->cmd_ret = TPCM_ERROR_INVALID_COMMAND;
//asm volatile ("dsb st");
sharemem->cmd_handled = 1;
invalid_command_count++;
//asm volatile ("dsb st");
return ;
}

if(info.cmd_type >= NUM_OF_COMMAND_TYPE){
tpcm_error("Unsuppored CMD type %u\n",info.cmd_type);
sharemem->cmd_ret = TPCM_ERROR_UNSUPPORTED_CMD_TYPE;
//asm volatile ("dsb st");
sharemem->cmd_handled = 1;
invalid_command_count++;
//asm volatile ("dsb st");
return ;
}
mobj = tpcm_sys_map(cmd_addr_phys,info.cmd_length,(void **)&vadrr);
if(!mobj){
tpcm_error("Map Address fail %lx \n",cmd_addr_phys);
sharemem->cmd_ret = TPCM_ERROR_INVALID_COMMAND;
//asm volatile ("dsb st");
sharemem->cmd_handled = 1;
invalid_command_count++;
//asm volatile ("dsb st");
tpcm_sys_unmap(mobj);
return ;
}
info.cmd_map = mobj;
info.input_addr = vadrr->input_addr;
info.input_length = vadrr->input_length;
info.output_addr = vadrr->output_addr;
info.output_maxlength = vadrr->output_maxlength;
info.cmd_vaddr = (uint64_t)vadrr;
tpcm_debug("Sync command type=%u seq = %lx, in addr = %lx,in length=%u,out addr = %lx,out max length=%u\n",info.cmd_type,
info.cmd_sequence,info.input_addr,info.input_length,
info.output_addr,info.output_maxlength
);

#if 1
int send_header_len = 0;
int send_body_len = 0;
struct msg_buff send_msg;
int recv_header_len = 0;
int recv_body_len = 0;
struct msg_buff recv_msg;
unsigned char* recv_total_buff = NULL;



memset(&send_msg, 0 ,sizeof(struct msg_buff));
memset(&recv_msg, 0 ,sizeof(struct msg_buff));

send_msg.cmd_type = sharemem->cmd_type;
send_msg.cmd_length = sharemem->cmd_length;
send_msg.cmd_sequence = sharemem->cmd_sequence;

send_msg.cmd_addrnum = sharemem->cmd_addr_phys;
send_msg.input_addr_num = vadrr->input_addr;
send_msg.output_addr_num = vadrr->output_addr;

send_msg.input_length = vadrr->input_length;
send_msg.output_maxlength = vadrr->output_maxlength;

memset(&send_msg.cmd,0,sizeof(struct cmd_header));
memcpy(&send_msg.cmd,vadrr,sizeof(struct cmd_header));

#if 0
memset(send_msg.input_buff,0,sizeof(send_msg.input_buff));
memcpy(send_msg.input_buff,sharemem_addr+vadrr->input_addr,vadrr->input_length);

memset(send_msg.output_buff,-1,sizeof(send_msg.output_buff));
memcpy(send_msg.output_buff,sharemem_addr+vadrr->output_addr,vadrr->output_maxlength);
#endif

send_msg.total_buff = malloc(vadrr->input_length+vadrr->output_maxlength);
if(send_msg.total_buff){
memcpy(send_msg.total_buff,sharemem_addr+vadrr->input_addr,vadrr->input_length);
memcpy(send_msg.total_buff+vadrr->input_length,sharemem_addr+vadrr->output_addr,vadrr->output_maxlength);
}

tpcm_debug("test buffer info\n");
tpcm_debug("Sync command type=%u seq = %lx, in addr = %lx,in length=%u,out addr = %lx,out max length=%u\n",info.cmd_type,
info.cmd_sequence,info.input_addr,info.input_length,
info.output_addr,info.output_maxlength
);
tpcm_debug("cmd_header addr %lx,cmd_header len %d\n",sharemem->cmd_addr_phys,sharemem->cmd_length);



void *input = NULL;
void *output = NULL;

int recv_total_len = 0;
int read_len = 0;


tpcm_comm_map_address(&info,&input,&output);
tpcm_debug("cmd tag %lu,cmd len %lu, cmd uicode %lu\n",ntohl(*(uint32_t*)input),ntohl(*(uint32_t*)(input+4)),ntohl(*(uint32_t*)(input+8)));


#if 0
bmc_sockfd = socket_tcpsocket_connect("127.0.0.1", LISTEN_PORT);
#else
//bmc_sockfd = socket_tcpv6socket_connect("fe80::47aa:c942:597f:2460", LISTEN_PORT);
bmc_sockfd = socket_tcpv6socket_connect("fe80::9e7d:a3ff:fe28:6ffa", LISTEN_PORT);
#endif

if(bmc_sockfd > 0){




send_header_len = write(bmc_sockfd,&send_msg,sizeof(struct msg_buff));


send_body_len = write(bmc_sockfd,send_msg.total_buff,vadrr->input_length+vadrr->output_maxlength);



tpcm_debug("send buffer length %d, header len %d, body len %d\n",send_header_len+send_body_len,send_header_len,send_body_len);
}else{

tpcm_debug("connect failed\n");
goto out;
}

free(send_msg.total_buff);
memset(&send_msg, 0 ,sizeof(struct msg_buff));


recv_header_len = read(bmc_sockfd,&recv_msg,sizeof(struct msg_buff));


vadrr->out_length = recv_msg.cmd.out_length;
vadrr->out_return = recv_msg.cmd.out_return;

if(recv_msg.input_length + recv_msg.output_maxlength){
tpcm_debug("TTTT recv total length %d,input len %d,output len %d\n",recv_msg.input_length + recv_msg.output_maxlength,recv_msg.input_length,recv_msg.output_maxlength);
tpcm_debug("TTTT recv output addr %lx\n",recv_msg.output_addr_num);
recv_total_buff = malloc(recv_msg.input_length + recv_msg.output_maxlength);

if(recv_total_buff){
int tmp = 0;
memset(recv_total_buff,0,recv_msg.input_length + recv_msg.output_maxlength);
read_len = read(bmc_sockfd,recv_total_buff,recv_msg.input_length + recv_msg.output_maxlength);

recv_total_len = read_len;

while((recv_total_len < (recv_msg.input_length + recv_msg.output_maxlength)) && (read_len > 0)){

tpcm_debug("TtTT recv output addr %lx %d %d\n",recv_msg.output_addr_num,recv_total_len,read_len);
read_len = read(bmc_sockfd,recv_total_buff+recv_total_len,recv_msg.input_length + recv_msg.output_maxlength-recv_total_len);
recv_total_len += read_len;
}

memcpy(sharemem_addr + recv_msg.output_addr_num,recv_total_buff+recv_msg.input_length,recv_msg.output_maxlength);
sharemem->cmd_ret = recv_msg.res;
sharemem->cmd_handled = 1;


#if 1
for(int tmp = 0;tmp<12;tmp++){
tpcm_debug("%02x ",*(char*)(recv_total_buff+tmp));
}
free(recv_total_buff);

#endif

#if 1
for(int tmp = 0;tmp<12;tmp++){
tpcm_debug(" %02x ",*(char*)(sharemem_addr + recv_msg.output_addr_num+tmp));
//tpcm_debug("index %d, %02x ",tmp,*(char*)(recv_total_buff+recv_msg.input_length+tmp));
}
#endif
tpcm_debug("process finish,recv output addr %lx!\n",recv_msg.output_addr_num);
}
}else{
tpcm_debug("recv buffer error! %d\n",recv_msg.input_length + recv_msg.output_maxlength);
}

tpcm_debug("res tag %lu,res len %lu, res ret %lu\n",ntohl(*(uint32_t*)output),ntohl(*(uint32_t*)(output+4)),ntohl(*(uint32_t*)(output+8)));
tpcm_debug("orig res tag %lu,res len %lu, res ret %lu\n",(*(uint32_t*)output),(*(uint32_t*)(output+4)),(*(uint32_t*)(output+8)));

out:

//printf("test buffer info end L442\n");



if(bmc_sockfd){
close(bmc_sockfd);
bmc_sockfd = 0;
}




//end
#endif
return ;
}

int tpcm_comm_map_address(struct command_info *info,void **input,void **output){
struct command_info_impl *impl = (struct command_info_impl *)(info);

if(impl->input_addr && impl->input_length){
impl->input_map = tpcm_sys_map(impl->input_addr,impl->input_length,input);
tpcm_debug("map result:%d", impl->input_map);
if(!impl->input_map){
tpcm_error("Map input Address fail %lx \n",impl->input_addr);
return -1;
}
}
if(impl->output_addr && impl->output_maxlength){
impl->output_map = tpcm_sys_map(impl->output_addr,impl->output_maxlength,output);
if(!impl->output_map){
tpcm_error("Map out Address fail %lx \n",impl->output_addr);
return -1;
}
}
tpcm_debug("PK cmd_map = %p,%p,%p\n",impl->cmd_map,impl->input_map,impl->output_map);
return 0;
}
void tpcm_comm_release_command(struct command_info *info){
struct command_info_impl *impl = (struct command_info_impl *)(info);
tpcm_debug("PK cmd_map = %p,%p,%p\n",impl->cmd_map,impl->input_map,impl->output_map);
if(impl->cmd_map){
tpcm_sys_unmap(impl->cmd_map);
}
if(impl->input_map){
tpcm_sys_unmap(impl->input_map);
}
if(impl->output_map){
tpcm_sys_unmap(impl->output_map);
}
tpcm_debug("Out map return\n");
}

void tpcm_comm_set_notify_handler(COMMAND_NOIFTY func){
notifier = func;
}

static inline void interrut(int type,unsigned long cmd_sequence ){
//tpcm_sys_tpcm_debug("Sending notify not implemented\n");
int r;
struct notify_info ninfo;
ninfo.notify_type = type;
ninfo.notify_sequence = cmd_sequence;
r = httcsec_netlink_send_msg(1,&ninfo,sizeof(struct notify_info),0,0);
tpcm_debug("Send result %d\n",r);
}
void tpcm_comm_async_command_handled(struct command_info *info){

struct command_info_impl *impl = (struct command_info_impl *)(info);
struct cmd_header *header = (struct cmd_header *)impl->cmd_vaddr;
// while( sharemem->notify_type == 1 ){//&& (sharemem->notify_type & NOTIFY_DATA_MASK
// tpcm_sys_tpcm_debug("Waiting for previous command finished\n");
// tpcm_sys_msleep(1);
// }

//if(sharemem->notify_pending){
// sharemem->notify_type = sharemem->notify_type | NOTIFY_TYPE_CMD_FINISHED;
//}
//else{
sharemem->notify_type = NOTIFY_TYPE_CMD_FINISHED;
//}
header->out_length = info->out_length;
sharemem->cmd_ret = header->out_return = impl->out_return;
sharemem->notify_sequence = info->cmd_sequence;
sharemem->notify_pending = 1;
tpcm_debug("Send commnd finished notify cmd sequence = %lu\n",info->cmd_sequence);
interrut(1,info->cmd_sequence);
// void *cmd_addr = NULL;
// int length = sizeof(struct cmd_header);
// struct command_info_impl *impl = (struct command_info_impl *)(inf);
// MAPObject share = tpcm_sys_map((unsigned long)impl->cmd_vaddr,length,(void **)&cmd_addr);
// struct cmd_header *header = (struct cmd_header *)cmd_addr;
// while(sharemem->notify_pending &&
// (sharemem->notify_type & NOTIFY_DATA_MASK) ){
// tpcm_sys_tpcm_debug("Waiting for previous command finished\n");
// tpcm_sys_msleep(1);
// }
//
// if(sharemem->notify_pending){
// sharemem->notify_type = sharemem->notify_type | NOTIFY_TYPE_CMD_FINISHED;
// }
// else{
// sharemem->notify_type = NOTIFY_TYPE_CMD_FINISHED;
// }
// header->out_length = inf->out_length;
// sharemem->cmd_ret = header->out_return = impl->out_return;
// sharemem->notify_sequence = inf->cmd_sequence;
// sharemem->notify_pending = 1;
// tpcm_sys_tpcm_debug("Send commnd finished notify cmd sequence = %lu\n",inf->cmd_sequence);
// tpcm_sys_unmap(share);
//return 0;
}

void tpcm_comm_send_bios_measure_result(uint32_t ret){
tpcm_info("send Boot measure result %x\n",ret);
}
void tpcm_comm_send_simple_notify(uint32_t notify_type){
// if(notify_type <= 1){
// tpcm_sys_tpcm_debug("Invalid notify type %d\n",notify_type);
// return;
// }
// while(sharemem->notify_pending && sharemem->notify_type == 1){//&&(sharemem->notify_type & NOTIFY_DATA_MASK)
// tpcm_sys_tpcm_debug("Waiting for command finished\n");
// tpcm_sys_msleep(1);
// }
// if(sharemem->notify_pending){
// sharemem->notify_type = sharemem->notify_type | (notify_type << 16 ) ;
// }
// else{
sharemem->notify_type = notify_type;//notify_type << 16 ;
// }
tpcm_debug("Try to sending notify %d\n",sharemem->notify_type);
*(unsigned char * )(sharemem + 1) = 'A';
sharemem->notify_sequence = 9;
sharemem->notify_length = 2;
sharemem->notify_addr_phys = (unsigned long )(sharemem + 1);
sharemem->notify_pending = 1;
interrut(sharemem->notify_type,sharemem->notify_sequence);
}
void debug_dump_hex (const void *p, int bytes);
static int dev_fd;
int comm_init(void){

//char buffer[1024]
unsigned char cmd[1024] = {0};
dev_fd = open("/dev/tpcm_comm", O_RDWR);
if(dev_fd < 0){
tpcm_error("Open comm dev file error\n");
return -1;
}
sharemem_addr = (unsigned long)mmap(NULL, SHARE_MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED,
dev_fd, 0);

if(!sharemem_addr){
tpcm_error("Share memory map error\n");
return -1;
}
tpcm_info("Share memory virtual addr %p\n",sharemem_addr);
sharemem = (volatile struct share_memory *)sharemem_addr;
//tpcm_sys_tpcm_debug("Mapperd");
//tpcm_sys_rand(((char *)sharemem) + 4096,4096);
//tpcm_dump(((char *)sharemem) + 4096,100);
HTTCSEC_NETLINK_HANLDLE handle = httcsec_alloc_netlink_listener();
if(httcsec_register_netlink_callback(handle, 1, os_handle)){
tpcm_error("httcsec_register_netlink_callback error\n");
return -1;
}


return httcsec_start_netlink_listener(handle, 0);
}

#define ___IO(cmd) _IO(0xD2,(cmd))

int httcsec_ioctl(unsigned long cmd,unsigned long param){
int r = 0;
if ((r = ioctl(dev_fd, ___IO(cmd), param)) < 0) {
tpcm_debug("ioctl cmd %lu ,param %lu fail,%s\n",cmd,param,strerror(errno));
return -1;
}
return r;
}

tss-main/httcutils

它提供了一套独立于业务的通用 C 语言工具函数,供上层(TCS、TCF)调用。

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
- tss-main/httcutils/
|
+-- Makefile // 构建脚本,定义如何编译整个工具库为 libhttcutils.a 或 .so
|
+-- include/httcutils/ // 【对外头文件】上层代码引用工具库时包含的头文件
| |-- array.h // 动态数组(Dynamic Array)接口定义。
| | // 作用:提供类似 C++ vector 的功能,支持自动扩容的数组操作。
| |-- convert.h // 数据转换工具宏/函数定义。
| | // 作用:处理字节序转换(大小端)、十六进制字符串与字节流互转等。
| |-- debug.h // 调试日志宏定义。
| | // 作用:定义 httc_log, httc_debug 等宏,统一控制日志打印格式和级别。
| |-- file.h // 文件 I/O 操作封装。
| | // 作用:提供简化的文件读写接口,如“一次性读整个文件”或“写入并同步”。
| |-- jhash.h // Jenkins Hash 算法定义。
| | // 作用:一种快速的哈希函数,常用于哈希表(Hash Table)的索引计算,而非加密。
| |-- list.h // 双向链表(Doubly Linked List)定义。
| | // 作用:直接移植自 Linux 内核的链表实现,用于高效管理策略列表、对象集合。
| |-- mem.h // 内存管理封装。
| | // 作用:包装 malloc/free,增加内存清零(zalloc)功能,防止敏感数据残留在内存中。
| |-- offset.h // 偏移量计算宏。
| | // 作用:包含 offsetof, container_of 等标准宏,用于结构体成员访问。
| |-- sem.h // 信号量(Semaphore)与锁机制封装。
| | // 作用:封装 pthread 互斥锁或信号量,用于多线程并发控制。
| |-- sm2.h // 国密 SM2 算法头文件。
| | // 作用:定义 SM2 签名、验签、加密、解密的函数原型和密钥结构。
| |-- sm3.h // 国密 SM3 算法头文件。
| | // 作用:定义 SM3 哈希计算的上下文(Context)和函数原型。
| |-- sm4.h // 国密 SM4 算法头文件。
| | // 作用:定义 SM4 对称加密算法的密钥设置和加解密函数原型。
| |-- sys.h // 系统级操作封装。
| | // 作用:获取系统信息(如 CPU、内存)、执行系统命令等底层操作的抽象。
| |-- types.h // 基础数据类型定义。
| | // 作用:定义 u8, u32, uint64_t 等跨平台类型,保证位宽一致。
|
+-- src/ // 【源代码】上述头文件的具体实现
|-- array.c // 动态数组的具体逻辑实现(扩容、插入、删除)。
|-- debug.c // 调试日志功能的实现(日志级别控制、输出到 stderr/syslog)。
|-- file.c // 文件操作的具体实现(httc_util_file_read_full 等)。
|-- jhash.c // Jenkins Hash 算法的数学实现。
|-- mem.c // 内存管理函数的实现(httc_malloc, httc_free 等)。
|-- sem.c // 信号量操作的封装实现。
|-- sys.c // 系统操作函数的实现。
|-- util.c // 其他杂项工具函数(如字符串处理、随机数获取辅助)。
|
+-- sm/ // 【核心子目录】国密算法的纯软件实现(Soft Implementation)
| // 当没有硬件加速卡(TPCM)时,或者在计算非敏感数据的哈希时使用。
|-- Makefile.objs // 定义该子目录编译目标的辅助文件。
|-- sub.mk // 子模块构建规则。
|-- ecc.c / ecc.h // 椭圆曲线密码学(ECC)基础数学运算库。
| // 作用:SM2 是基于 ECC 的,这里实现了点乘、点加等基础数学运算。
|-- sm2.c // SM2 算法的具体逻辑实现。
| // 作用:实现了国密公钥密码算法,用于非对称加解密和签名。
|-- sm3.c // SM3 算法的具体逻辑实现。
| // 作用:实现了国密哈希算法(类似 SHA-256),用于计算完整性摘要。
|-- sm3_impl.h // SM3 内部宏和常数定义,不对外暴露。
|-- sm4.c // SM4 算法的具体逻辑实现。
| // 作用:实现了国密分组密码算法(类似 AES),用于数据加密。

核心服务层 tss-main/tcs

tcs/tdd

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
- tss-main/tcs/tdd/
|
|-- tdd.c / tdd.h // 【驱动入口与骨架】
| // 作用:Linux 字符设备驱动的标准框架。
| // 关键逻辑:
| // 1. module_init/exit: 负责加载和卸载 tcs.ko 内核模块。
| // 2. device_create: 创建设备文件节点 (通常是 /dev/tcs 或 /dev/tcm)。
| // 3. file_operations: 定义 open, release, ioctl 等文件操作。
| // 当上层调用 ioctl 时,请求会从这里进入驱动。
|
|-- tdd_tpcm.c / tdd_tpcm.h // 【硬件通信核心逻辑】
| // 作用:实现了针对 TPCM 芯片的具体通信协议。
| // 关键逻辑:
| // 1. 物理层读写:通过 SPI/LPC/I2C 总线读写芯片的状态寄存器 (Status Register) 和数据寄存器 (Data Register)。
| // 2. 协议握手:实现“等待就绪”、“发送命令头”、“发送数据体”、“等待完成”、“读取响应”的时序状态机。
| // 3. 它是真正“摸”到硬件代码的地方。
|
|-- comm_driver.c / comm_driver.h // 【通信接口抽象】
| // 作用:对底层物理总线(Interface)的封装。
| // 场景:TPCM 可能挂在 SPI 总线上,也可能挂在 LPC 总线上。
| // 这个文件负责探测底层具体的总线类型,并提供统一的 read_byte/write_byte 接口给 tdd_tpcm.c 使用。
|
|-- cmd_man.c / cmd_man.h // 【命令管理器 (Command Manager)】
| // 作用:负责管理并发的命令请求。
| // 关键逻辑:
| // 1. 互斥锁 (Mutex): TPCM 芯片同一时间只能处理一个命令。这个文件保证多进程同时调用 TSB 时,命令能排队执行,不会冲突。
| // 2. 超时控制: 防止硬件卡死导致驱动永久等待。
|
|-- netlink.c // 【异步通知机制】
| // 作用:实现 Kernel 到 User Space 的异步消息推送。
| // 场景:当 TPCM 硬件产生中断(例如检测到物理入侵、完整性校验失败)时,
| // 驱动通过 Netlink Socket 主动发消息给用户态的守护进程(如 tsb_admin 或审计进程),而不是被动等待 ioctl。
|
|-- ft_tpcm.h // 【特定硬件定义】
| // 作用:可能包含飞腾 (Phytium/FT) 平台特定的 TPCM 硬件定义或寄存器地址映射。
|
|-- msg.h // 【消息结构定义】
| // 作用:定义了驱动内部传递的消息结构体。

cmd_man.c

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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/spinlock_types.h>
#include <linux/atomic.h>
#include <asm/io.h>
#include "cmd_man.h"
#include "tdd_tpcm.h"
struct share_memory_area{
int offset;
int unit_size;
int size;
};

#define BUFFER_AREA_NUM 10
struct share_memory_area areas[BUFFER_AREA_NUM] = {
{0x200000,0x1000,0x200000},//4k,2m
{0x400000,0x2000,0x200000},//8K
{0x600000,0x4000,0x200000},//16K
{0x800000,0x8000,0x200000},//32K
{0xA00000,0x10000,0x200000},//64K
{0xC00000,0x20000,0x200000},//128K
{0xE00000,0x40000,0x200000},//256K
{0x1000000,0x80000,0x200000},//256K
{0x1200000,0x100000,0x400000},//1m,4m
{0x1600000,0x200000,0x800000}//2m,8m
};
#define TPCM_BUFFER_AREA_OFFSET 0x200000//2M
#define TPCM_BUFFER_AREA_SIZE 0x1C00000//28M
#define TPCM_CMD_HEADER_AREA_OFFSET 0x1E00000//30M
#define TPCM_CMD_HEADER_AREA_SIZE 0x100000//1M
#define TPCM_SHARE_MEMORY_SIZE 0x1F00000//31M

#define CMD_BUFFER_NUMBER (TPCM_CMD_HEADER_AREA_SIZE/sizeof(struct cmd_header ))

void *sharemem_base;
struct cmd_header * cmd_header_base;
struct share_memory * share_memory_base;
void * data_buffer_base;
void * data_buffer_end;
short cmd_headers[CMD_BUFFER_NUMBER];
short buffer_next[BUFFER_AREA_NUM];
//void *data_buffer_base[BUFFER_AREA_NUM];
short *buffer_head[BUFFER_AREA_NUM];

int cmd_next = CMD_BUFFER_NUMBER - 1;

static DEFINE_SPINLOCK(buffer_lock);

int shm_init(void){
int i,j;
int num,r,ret;
//sharemem_base = ioremap_nocache(
// (unsigned long)TPCM_SHARE_BUFFER, (unsigned long)TPCM_SHARE_MEMORY_SIZE);
sharemem_base = vmalloc(TPCM_SHARE_MEMORY_SIZE);
if (!sharemem_base){
ret = -ENOMEM;
return ret;
}
share_memory_base = sharemem_base;
cmd_header_base = sharemem_base + TPCM_CMD_HEADER_AREA_OFFSET;
data_buffer_base = sharemem_base + TPCM_BUFFER_AREA_OFFSET;
data_buffer_end = data_buffer_base + TPCM_BUFFER_AREA_SIZE;
//huge_data_buffer_base = sharemem_base + TPCM_HUGE_DATA_BUFFER_OFFSET;
//huge_data_buffer_end = sharemem_base + TPCM_HUGE_DATA_BUFFER_END ;
printk("Share memory base = 0x%lx,Command memory base = 0x%lx\n"
,(unsigned long)sharemem_base,(unsigned long)cmd_header_base);
printk("data_buffer_base = 0x%lx,data_buffer_end= 0x%lx\n",
(unsigned long)data_buffer_base,(unsigned long)data_buffer_end);
if( sharemem_base == 0 )return -1;
for(i=0;i<CMD_BUFFER_NUMBER;i++){
cmd_headers[i] = i - 1;
}

for(i=0;i<BUFFER_AREA_NUM;i++){

num = areas[i].size/areas[i].unit_size;
buffer_next[i] = num -1;
buffer_head[i] = kmalloc(num * sizeof(short),GFP_KERNEL);
if(!buffer_head[i]){
printk("No memory for share memory management\n");
r = -1;
goto error;
}
for(j=0;j<num;j++){
buffer_head[i][j] = j - 1;
}
}
return 0;
error:
for(i=0;i<BUFFER_AREA_NUM;i++){
if(buffer_head[i])kfree(buffer_head[i]);
}
return -1;

}

void shm_exit(void){
int i;
for(i=0;i<BUFFER_AREA_NUM;i++){
kfree(buffer_head[i]);
}
vfree(sharemem_base);
return;
}

int tdd_free_cmd_header(struct cmd_header * header){
int index;
int r = 0;
index = ((unsigned long)header - (unsigned long)cmd_header_base)/sizeof(struct cmd_header);
if(index < 0 || index >= CMD_BUFFER_NUMBER){
printk("[%s:%d] hter command header address %p\n",__func__, __LINE__,header);
return -1;
}
spin_lock(&buffer_lock);
if(cmd_headers[index] != -2){
printk("Duplicated Free command header at index %d\n",index);
r = -1;
}
else{
#ifdef __DEBUG__
printk("Free command header at index %d\n",index);
#endif
cmd_headers[index] = cmd_next;
cmd_next = index;
}
spin_unlock(&buffer_lock);
return r;
}
EXPORT_SYMBOL_GPL(tdd_free_cmd_header);

struct cmd_header *tdd_alloc_cmd_header(void ){
int index;
struct cmd_header *cmd = 0;
spin_lock(&buffer_lock);
if(cmd_next != -1){
index = cmd_next;
cmd_next = cmd_headers[index];
cmd_headers[index] = -2;//set to in use
#ifdef __DEBUG__
printk("Get command at index %d\n",index);
#endif
cmd = cmd_header_base + index;
}
spin_unlock(&buffer_lock);
return cmd;
}
EXPORT_SYMBOL_GPL(tdd_alloc_cmd_header);

unsigned long tdd_get_phys_addr(void *buffer){
if(buffer >= sharemem_base + TPCM_SHARE_MEMORY_SIZE
|| buffer < sharemem_base)
{
return (unsigned long)buffer;
}
// printk("----tdd_get_phys_addr: %d---\n", buffer - sharemem_base);
return buffer - sharemem_base;//返回buffer - sharemem_base
}
EXPORT_SYMBOL_GPL(tdd_get_phys_addr);

static inline int get_area_point(void *buffer){
int i;
for(i = 0 ; i< BUFFER_AREA_NUM -1 ;i++){
if(buffer < sharemem_base + areas[i + 1].offset){
break;
}
}

return i;
}

int tdd_free_data_buffer(void *buffer){
int area,diff,index,r = 0;
if(buffer >= data_buffer_end){
printk("[%s:%d]Free data buffer hter 1 %p\n",__func__, __LINE__,buffer);
return -1;
}
if(buffer < data_buffer_base){
printk("[%s:%d]Free data buffer hter 2 %p,data_buffer_base=%p\n",__func__, __LINE__,buffer,data_buffer_base);
return -1;
}
area = get_area_point(buffer);
diff = buffer -(sharemem_base + areas[area].offset);
if(diff % areas[area].unit_size){
printk("[%s:%d]Free data align hter , area = %d,address = %p\n",__func__, __LINE__,area,buffer);
return -1;
}
index = diff/areas[area].unit_size;

spin_lock(&buffer_lock);
if(buffer_head[area][index] != -2){
printk("Duplicated freee data buffer at area %d, index %d\n",area,index);
r = -1;
}
else{
#ifdef __DEBUG__
printk("Free data buffer at area %d, index %d\n",area,index);
#endif
buffer_head[area][index] = buffer_next[area];
buffer_next[area] = index;
}
spin_unlock(&buffer_lock);

return r;
}
EXPORT_SYMBOL_GPL(tdd_free_data_buffer);

static inline int get_area(int size){
int i;
for(i = 0 ; i< BUFFER_AREA_NUM -1 ;i++){
if(size <= areas[i].unit_size){
break;
}
}
return i;
}

void *tdd_alloc_data_buffer(unsigned int size){
int area,index;
void *buf = 0;
if(size == 0 || size > areas[BUFFER_AREA_NUM - 1].unit_size){
return 0;
}
area = get_area(size);
spin_lock(&buffer_lock);
#ifdef __DEBUG__
printk("Try to Alloc size = %x,area = %d\n",size,area);
#endif
for(;area < BUFFER_AREA_NUM ;area++){
if(buffer_next[area] != -1){
index = buffer_next[area];
buffer_next[area] = buffer_head[area][index];
buffer_head[area][index] = -2;//set to in use
#ifdef __DEBUG__
printk("Get Buffer size=%x,at area %d,index %d\n",size,area,index);
#endif
buf = sharemem_base + areas[area].offset
+ index * areas[area].unit_size;
#ifdef __DEBUG__
printk("Get buf = %p\n",buf);
#endif
break;
}
}
spin_unlock(&buffer_lock);
return buf;
}
EXPORT_SYMBOL_GPL(tdd_alloc_data_buffer);

void *tdd_alloc_data_buffer_api(unsigned int size)
{
return tdd_alloc_data_buffer (size);
}
EXPORT_SYMBOL_GPL(tdd_alloc_data_buffer_api);

tdd_tpcm.c

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
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include "msg.h"
#include "tdd.h"
#include "tdd_tpcm.h"
#include "cmd_man.h"
#define PID 1

struct share_memory * share_memory_begin;

static DEFINE_MUTEX(mutex);

int send_command(int cmd_type,int cmd_length,unsigned long cmd_sequence, unsigned long cmd_addr_phys, int *cmd_ret){

//u32 pid = PID;
//int length;
int r;
int i;
unsigned long proxypid = 0;

mutex_lock (&mutex);//加锁,进入临界区

share_memory_begin = (struct share_memory *)sharemem_base;//填充共享内存sharemem_base

// while(share_memory_begin->cmd_handled){
// printk("There are orders not processed\n");
// mdelay(1);
// }

/*将命令类型、长度、物理地址等数据写入共享内存*/
share_memory_begin->cmd_type = cmd_type;
share_memory_begin->cmd_length = cmd_length;
share_memory_begin->cmd_sequence = cmd_sequence;
share_memory_begin->cmd_addr_phys = cmd_addr_phys;

share_memory_begin->cmd_handled = 0;//将标志位置0表示已写完


r = httcsec_io_send_message(&cmd_addr_phys,sizeof(cmd_addr_phys), 1);//发送消息(通过中断)

if(r){//失败解锁并返回错误
mutex_unlock (&mutex);
return r;
}

for(i=0;i<600;i++){ //等待十分钟
//当对端把cmd_handled置1时表示已经读完,可释放锁
if(share_memory_begin->cmd_handled){
mutex_unlock (&mutex);
return 0;
}

schedule_timeout_uninterruptible(HZ);//让当前任务主动交出 CPU 控制权,挂起(Sleep)一段时间,不会响应信号

if(i%10 == 0){ //每隔 10 秒检查一次
//如果是第一次运行(proxypid 为 0),或者之前没获取到,就去尝试获取用户态代理进程的PID
if(proxypid == 0){
proxypid = get_proxy_pid();
}
/*检查这个 proxypid 对应的进程是否还在正常运行
如果没有正常运行就释放锁并返回(接收消息的代理已经消失或重启,原先的任务不需要再等待了)*/
if(compare_proxy(proxypid,PROXY_RUNNING_CHECK) != 0){
mutex_unlock (&mutex);
return 0;
}
}
}

mutex_unlock (&mutex);
return 1;
//share_memory_begin->cmd_ret = *cmd_ret;


//length = sizeof(&cmd_addr_phys);
//send_netlink_back_data(pid, (void *)&cmd_addr_phys, length, 1);
//return 0;
}
EXPORT_SYMBOL_GPL(send_command);

mermaid-diagram-2025-12-23-154059

调用关系(三层):

image-20251223172131906

tcs/tddl

tcs/tcsapi

  • tcs/tcsapi/tcsu/

  • tcs/tcsapi/tcsk/

tcs/tcm/

tcs/mocktsb/

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
- tss-main/tcs/
|
+-- common/ // 【公共定义区】内核态与用户态代码共用的基础定义
| |-- tcs_config.h // 全局编译配置宏(如是否开启 DEBUG,是否支持某些特定功能)。
| |-- tpcm_command.h // TPCM 硬件指令的原始二进制结构体定义(命令头、响应头)。
| |
| +-- kernel/ // 内核态专用的通用工具
| | |-- kutils.h // 内核开发辅助宏。
| | |-- memdebug.h // 内核内存泄漏检测工具。
| | |-- version.h // 版本号定义。
| |
| +-- user/ // 用户态专用的通用工具
| |-- tutils.h // 用户态辅助函数声明。
|
+-- include/ // 【对外头文件区】定义了 TCS 提供的所有服务接口
| |-- tpcm_def.h // TPCM 芯片相关的常量定义(如错误码、寄存器地址偏移)。
| |
| +-- tcsapi/ // **核心 API 定义** (这是上层 TCF 调用的菜单)
| | |-- tcs_attest.h // 远程证明服务:获取 Quote,验证平台身份。
| | |-- tcs_auth.h // 授权服务:管理谁有权限调用 TSB 功能。
| | |-- tcs_bmeasure.h // 启动度量服务:获取 BIOS/Bootloader 阶段的度量日志。
| | |-- tcs_key.h // 密钥服务:创建、加载、卸载密钥,数据封存(Sealing)。
| | |-- tcs_license.h // 授权 License 管理:导入/验证 License。
| | |-- tcs_policy.h // 策略管理:设置白名单策略、关键文件保护策略。
| | |-- tcs_process.h // 进程身份标识相关接口。
| | |-- tcs_protect.h // 运行时保护相关接口。
| | |-- tcs_tnc.h // 可信网络连接 (TNC) 支持接口。
| | |-- tcs_constant.h // 全局常量(如哈希算法 ID、密钥类型 ID)。
| | |-- tcs_error.h // 统一错误码定义。
|
+-- tdd/ // 【驱动层】(Trusted Device Driver) - Linux 内核驱动
| |-- tdd.c // 驱动入口:
| | // 1. module_init/exit。
| | // 2. 注册字符设备 /dev/tcs (或类似)。
| | // 3. 实现 file_operations (open, release, ioctl)。
| |-- tdd_tpcm.c // 硬件通信逻辑:
| | // 1. 实现与 TPCM 芯片的物理 IO (ioread/iowrite)。
| | // 2. 处理硬件中断或轮询状态寄存器。
| |-- comm_driver.c // 通用通信层实现。
| |-- netlink.c // Netlink 接口,用于内核向用户态发送异步通知(如告警)。
| |-- cmd_man.c // 命令管理,可能用于处理并发命令队列。
|
+-- tddl/ // 【驱动库层】(TDD Library) - 硬件抽象层
| | // 作用:将逻辑请求打包成硬件特定的二进制包,屏蔽不同芯片差异。
| |-- tddl.h // TDDL 接口定义。
| |-- tpcm_tddl.c // 针对 TPCM 规范的指令打包实现。
| |-- tcm_tddl.c // 针对 TCM 规范的指令打包实现。
|
+-- tcsapi/ // 【核心实现层】业务逻辑的具体代码
| |
| +-- tcsu/ // **用户态库 (libtcs.so)**
| | |-- tcs.c // 库初始化,打开驱动设备句柄。
| | |-- transmit.c // **关键**:封装 ioctl,将打包好的命令结构体发送给内核。
| | |-- tcs_attest.c // 实现 tcs_attest.h 定义的接口(参数检查 -> 打包 -> transmit)。
| | |-- tcs_key.c // 实现密钥相关接口。
| | |-- tcs_*.c // 对应 include/tcsapi/ 下的每个头文件的具体实现。
| |
| +-- tcsk/ // **内核模块 (tcs.ko)**
| |-- tcs.c // 模块主逻辑:
| | // 1. 接收来自 tcsu 的 ioctl 请求。
| | // 2. 解析命令字 (cmd_id)。
| | // 3. 分发给具体的处理函数 (dispatch)。
| |-- tcs_auth.c // 权限检查核心:判断当前进程/用户是否有权执行该操作。
| |-- tcs_policy.c // 策略引擎:在内核中维护白名单链表/红黑树。
| |-- tcs_protect.c // 保护逻辑实现。
| |-- kutils.c // 内核辅助工具。
| +-- smk/ // 内核态国密算法实现 (SM3/SM4),用于内核内计算哈希。
|
+-- tcm/ // 【协议栈层】TCM 2.0 协议支持库
| +-- lib/ // 包含大量 .c 文件,实现了 TCM 协议规范
| |-- bind.c // 数据绑定 (Bind) 命令封装。
| |-- seal.c // 数据封装 (Seal) 命令封装。
| |-- sign.c // 签名 (Sign) 命令封装。
| |-- pcrs.c // PCR 读取与扩展操作。
| |-- keys.c // 密钥对象构建。
| |-- serialize.c // 序列化工具:将 C 结构体转换为网络字节序二进制流。
| |-- tcm_util.c // TCM 工具函数。
|
+-- mocktsb/ // 【仿真层】
|-- tsb_admin.c // 模拟管理接口,用于在非 TPCM 环境下开发测试。
|-- tsb_measure_user.c // 模拟度量接口,返回预设的“成功”状态。

对外API tcs/tcsapi


TSB-agent分析
http://yzsandw.com/2025/12/23/TSB-agent分析/
作者
5Y2z
发布于
2025年12月23日
许可协议