首先贴出一个 IMA 度量文件的实例:
binary_runtime_measurement:
00000000 00 0a 00 00 9d 4c 81 b9 db f2 b4 c5 27 17 7f 49 |.....L......'..I|
00000010 75 9d e9 8f dc 50 a2 f6 00 06 00 00 6d 69 2d 61 |u....P......mi-a|
00000020 67 6e 00 31 00 00 00 1a 00 00 68 73 31 61 00 3a |gn.1......hs1a.:|
00000030 99 92 05 e7 2f 9f 3c 26 9a c8 61 55 cf e2 87 58 |..../.<&..aU...X|
00000040 98 cc 9b 30 00 0f 00 00 6f 62 74 6f 61 5f 67 67 |...0....obtoa_gg|
00000050 65 72 61 67 65 74 0a 00 00 00 97 00 62 2d 5b ff |eraget......b-[.|
00000060 74 3a 99 e8 e0 52 0b 98 99 20 d4 ee f8 9b 06 f0 |t:...R... ......|
00000070 00 00 69 00 61 6d 6e 2d 28 67 00 00 1a 00 00 00 |..i.amn-(g......|
对应的ascii_runtime_measurement:
10 4c9db981f2dbc5b41727497f9d758fe950dcf6a2 ima-ng sha1:9299e7059f2f263cc89a5561e2cf5887cc98309b boot_aggregate
10 972d62ff5b3a74e89952e0980b2099eed49bf8f0 ima-ng sha1:e9002ba6c5a98f5b7a33dc6bbf9ac1863873b713 /init
10 db389c4b5590a7450cb7b20d6fa4a97bc901420d ima-ng sha1:3cdd378dde62d830349e4221591655229a757ae5 /usr/bin/sh
对应读取的结构体如下:
struct event {
struct {
u_int32_t pcr;
u_int8_t digest[SHA_DIGEST_LENGTH];
u_int32_t name_len;
} header;
char name[TCG_EVENT_NAME_LEN_MAX + 1];
struct ima_template_desc *template_desc; /* template descriptor */
u_int32_t template_data_len;
u_int8_t *template_data; /* template related data */
};
-
header
读取时,首先填充 event 结构体中 header 结构体的内容,这部分长度是固定的。首先是4字节 PCR 索引,然后是哈希值,这里采用的是 SHA1,因此是20字节,接着是4字节的 IMA 模板名称长度。该部分对应下面的二进制内容:
00000000 00 0a 00 00 9d 4c 81 b9 db f2 b4 c5 27 17 7f 49 |.....L......'..I| 00000010 75 9d e9 8f dc 50 a2 f6 00 06 00 00 |u....P...... |
-
name
根据上一步读取的 IMA 模板名称长度读取模板名称,本处读取的名称为
ima-ng
,共6字节:00000000 00 0a 00 00 9d 4c 81 b9 db f2 b4 c5 27 17 7f 49 |.....L......'..I| 00000010 75 9d e9 8f dc 50 a2 f6 00 06 00 00 6d 69 2d 61 |u....P......mi-a| 00000020 67 6e |gn |
-
接下来会根据模板的不同采用不同的方案读取数据
-
对于模板名称为
ima
的类型,将首先读取模板哈希值,如果采用 SHA1 算法,将读取20字节的哈希值。然后读取4字节的field_len
(?)和该数值相对应长度的数据。 -
对于非
ima
的其他类型模板,将首先读取4字节的模板数据长度值,对于本示例,读取的长度为49字节(0x31)。至此读取过的全部内容为:00000000 00 0a 00 00 9d 4c 81 b9 db f2 b4 c5 27 17 7f 49 |.....L......'..I| 00000010 75 9d e9 8f dc 50 a2 f6 00 06 00 00 6d 69 2d 61 |u....P......mi-a| 00000020 67 6e 00 31 00 00 |gn.1.. |
进一步,将根据该长度读取模板特定数据。至此读取完后的全部内容为:
00000000 00 0a 00 00 9d 4c 81 b9 db f2 b4 c5 27 17 7f 49 |.....L......'..I| 00000010 75 9d e9 8f dc 50 a2 f6 00 06 00 00 6d 69 2d 61 |u....P......mi-a| 00000020 67 6e 00 31 00 00 00 1a 00 00 68 73 31 61 00 3a |gn.1......hs1a.:| 00000030 99 92 05 e7 2f 9f 3c 26 9a c8 61 55 cf e2 87 58 |..../.<&..aU...X| 00000040 98 cc 9b 30 00 0f 00 00 6f 62 74 6f 61 5f 67 67 |...0....obtoa_gg| 00000050 65 72 61 67 65 74 0a |eraget. |
该步骤读取的模板特定数据中,前四字节的 INT 值内容含义未知(00 1a 00 00),在实际解析时也未使用。而后面的内容可以对照本文章开头的ascii_runtime_measurement部分内容对照查看,分别为:
- "sha1" || 0x00 || ":" || 模板哈希值 || 文件路径名称长度(包含1字节换行符) || 文件路径
-