2 * ima-evm-utils - IMA/EVM support utilities
4 * Copyright (C) 2011 Nokia Corporation
5 * Copyright (C) 2011,2012,2013 Intel Corporation
6 * Copyright (C) 2013,2014 Samsung Electronics
9 * Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
10 * <dmitry.kasatkin@intel.com>
11 * <d.kasatkin@samsung.com>
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * version 2 as published by the Free Software Foundation.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 * As a special exception, the copyright holders give permission to link the
26 * code of portions of this program with the OpenSSL library under certain
27 * conditions as described in each individual source file and distribute
28 * linked combinations including the program with the OpenSSL library. You
29 * must comply with the GNU General Public License in all respects
30 * for all of the code used other than as permitted herein. If you modify
31 * file(s) with this exception, you may extend this exception to your
32 * version of the file(s), but you are not obligated to do so. If you do not
33 * wish to do so, delete this exception statement from your version. If you
34 * delete this exception statement from all source files in the program,
35 * then also delete it in the license file.
38 * IMA/EVM control program
41 #include <sys/types.h>
42 #include <sys/param.h>
44 #include <sys/ioctl.h>
52 #include <attr/xattr.h>
53 #include <linux/xattr.h>
58 #include <openssl/sha.h>
59 #include <openssl/pem.h>
60 #include <openssl/hmac.h>
61 #include <openssl/err.h>
62 #include <openssl/rsa.h>
68 static char *evm_default_xattrs[] = {
76 static char *evm_extra_smack_xattrs[] = {
80 XATTR_NAME_SMACKTRANSMUTE,
87 static char **evm_config_xattrnames = evm_default_xattrs;
91 int (*func)(struct command *cmd);
94 char *msg; /* extra info message */
100 static bool check_xattr;
105 static char *uuid_str;
106 static char *search_type;
107 static int recursive;
111 #define HMAC_FLAG_UUID 0x0001
112 #define HMAC_FLAG_UUID_SET 0x0002
113 static unsigned long hmac_flags = HMAC_FLAG_UUID;
115 typedef int (*find_cb_t)(const char *path);
116 static int find(const char *path, int dts, find_cb_t func);
118 #define REG_MASK (1 << DT_REG)
119 #define DIR_MASK (1 << DT_DIR)
120 #define LNK_MASK (1 << DT_LNK)
121 #define CHR_MASK (1 << DT_CHR)
122 #define BLK_MASK (1 << DT_BLK)
124 struct command cmds[];
125 static void print_usage(struct command *cmd);
127 static int bin2file(const char *file, const char *ext, const unsigned char *data, int len)
130 char name[strlen(file) + (ext ? strlen(ext) : 0) + 2];
134 sprintf(name, "%s.%s", file, ext);
136 sprintf(name, "%s", file);
138 log_info("Writing to %s\n", name);
140 fp = fopen(name, "w");
142 log_err("Failed to open: %s\n", name);
145 err = fwrite(data, len, 1, fp);
150 static unsigned char *file2bin(const char *file, const char *ext, int *size)
155 char name[strlen(file) + (ext ? strlen(ext) : 0) + 2];
158 sprintf(name, "%s.%s", file, ext);
160 sprintf(name, "%s", file);
162 log_info("Reading to %s\n", name);
164 len = get_filesize(name);
165 fp = fopen(name, "r");
167 log_err("Failed to open: %s\n", name);
171 if (!fread(data, len, 1, fp))
179 static int find_xattr(const char *list, int list_size, const char *xattr)
183 for (; list_size > 0; len++, list_size -= len, list += len) {
185 if (!strcmp(list, xattr))
191 static int hex_to_bin(char ch)
193 if ((ch >= '0') && (ch <= '9'))
196 if ((ch >= 'a') && (ch <= 'f'))
197 return ch - 'a' + 10;
201 static int hex2bin(uint8_t *dst, const char *src, size_t count)
209 hi = hex_to_bin(*src++);
210 lo = hex_to_bin(*src++);
212 if ((hi < 0) || (lo < 0))
215 *dst++ = (hi << 4) | lo;
220 #define hex_asc_lo(x) hex_asc[((x) & 0x0f)]
221 #define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4]
223 const char hex_asc[] = "0123456789abcdef";
225 /* this is faster than fprintf - makes sense? */
226 static void bin2hex(uint8_t *buf, size_t buflen, FILE *stream)
230 for (; buflen--; buf++) {
231 asciihex[0] = hex_asc_hi(*buf);
232 asciihex[1] = hex_asc_lo(*buf);
233 fwrite(asciihex, 2, 1, stream);
237 static int pack_uuid(const char *uuid_str, char *uuid)
242 for (i = 0; i < 16; ++i) {
243 if (!uuid_str[0] || !uuid_str[1]) {
244 log_err("wrong UUID format\n");
247 *to++ = (hex_to_bin(*uuid_str) << 4) |
248 (hex_to_bin(*(uuid_str + 1)));
255 if (*uuid_str != '-') {
256 log_err("wrong UUID format\n");
268 static int get_uuid(struct stat *st, char *uuid)
271 unsigned minor, major;
272 char path[PATH_MAX], _uuid[37];
276 if (hmac_flags & HMAC_FLAG_UUID_SET)
277 return pack_uuid(uuid_str, uuid);
280 major = (dev & 0xfff00) >> 8;
281 minor = (dev & 0xff) | ((dev >> 12) & 0xfff00);
283 log_debug("dev: %u:%u\n", major, minor);
284 sprintf(path, "blkid -s UUID -o value /dev/block/%u:%u", major, minor);
286 fp = popen(path, "r");
290 len = fread(_uuid, 1, sizeof(_uuid), fp);
292 if (len != sizeof(_uuid))
295 return pack_uuid(_uuid, uuid);
297 log_err("Failed to read UUID. Root access might require.\n");
301 static int calc_evm_hash(const char *file, unsigned char *hash)
305 uint32_t generation = 0;
309 char xattr_value[1024];
313 struct h_misc_64 hmac_misc;
316 if (lstat(file, &st)) {
317 log_err("Failed to stat: %s\n", file);
321 if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode)) {
322 /* we cannot at the momement to get generation of special files..
323 * kernel API does not support it */
324 int fd = open(file, 0);
327 log_err("Failed to open: %s\n", file);
330 if (ioctl(fd, FS_IOC_GETVERSION, &generation)) {
331 log_err("ioctl() failed\n");
337 log_info("generation: %u\n", generation);
339 list_size = llistxattr(file, list, sizeof(list));
341 log_err("llistxattr() failed\n");
345 err = EVP_DigestInit(&ctx, EVP_sha1());
347 log_err("EVP_DigestInit() failed\n");
351 for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
352 err = lgetxattr(file, *xattrname, xattr_value, sizeof(xattr_value));
354 log_info("no xattr: %s\n", *xattrname);
357 if (!find_xattr(list, list_size, *xattrname)) {
358 log_info("skipping xattr: %s\n", *xattrname);
361 /*log_debug("name: %s, value: %s, size: %d\n", *xattrname, xattr_value, err);*/
362 log_info("name: %s, size: %d\n", *xattrname, err);
363 log_debug_dump(xattr_value, err);
364 err = EVP_DigestUpdate(&ctx, xattr_value, err);
366 log_err("EVP_DigestUpdate() failed\n");
371 memset(&hmac_misc, 0, sizeof(hmac_misc));
374 struct h_misc *hmac = (struct h_misc *)&hmac_misc;
376 hmac_size = sizeof(*hmac);
377 hmac->ino = st.st_ino;
378 hmac->generation = generation;
379 hmac->uid = st.st_uid;
380 hmac->gid = st.st_gid;
381 hmac->mode = st.st_mode;
382 } else if (msize == 64) {
383 struct h_misc_64 *hmac = (struct h_misc_64 *)&hmac_misc;
385 hmac_size = sizeof(*hmac);
386 hmac->ino = st.st_ino;
387 hmac->generation = generation;
388 hmac->uid = st.st_uid;
389 hmac->gid = st.st_gid;
390 hmac->mode = st.st_mode;
392 struct h_misc_32 *hmac = (struct h_misc_32 *)&hmac_misc;
394 hmac_size = sizeof(*hmac);
395 hmac->ino = st.st_ino;
396 hmac->generation = generation;
397 hmac->uid = st.st_uid;
398 hmac->gid = st.st_gid;
399 hmac->mode = st.st_mode;
402 log_debug("hmac_misc (%d): ", hmac_size);
403 log_debug_dump(&hmac_misc, hmac_size);
405 err = EVP_DigestUpdate(&ctx, &hmac_misc, hmac_size);
407 log_err("EVP_DigestUpdate() failed\n");
411 if (hmac_flags & HMAC_FLAG_UUID) {
412 err = get_uuid(&st, uuid);
416 err = EVP_DigestUpdate(&ctx, (const unsigned char *)uuid, sizeof(uuid));
418 log_err("EVP_DigestUpdate() failed\n");
423 err = EVP_DigestFinal(&ctx, hash, &mdlen);
425 log_err("EVP_DigestFinal() failed\n");
432 static int sign_evm(const char *file, const char *key)
434 unsigned char hash[20];
435 unsigned char sig[1024];
438 len = calc_evm_hash(file, hash);
442 len = sign_hash("sha1", hash, len, key, sig + 1);
448 sig[0] = EVM_IMA_XATTR_DIGSIG;
450 if (sigdump || params.verbose >= LOG_INFO)
454 err = lsetxattr(file, "security.evm", sig, len, 0);
456 log_err("setxattr failed: %s\n", file);
464 static int hash_ima(const char *file)
466 unsigned char hash[66]; /* MAX hash size + 2 */
467 int len, err, offset;
468 int algo = get_hash_algo(params.hash_algo);
470 if (algo > PKEY_HASH_SHA1) {
471 hash[0] = IMA_XATTR_DIGEST_NG;
475 hash[0] = IMA_XATTR_DIGEST;
479 len = ima_calc_hash(file, hash + offset);
485 if (params.verbose >= LOG_INFO)
488 if (sigdump || params.verbose >= LOG_INFO)
492 err = lsetxattr(file, "security.ima", hash, len, 0);
494 log_err("setxattr failed: %s\n", file);
502 static int cmd_hash_ima(struct command *cmd)
504 char *file = g_argv[optind++];
507 log_err("Parameters missing\n");
512 return hash_ima(file);
515 static int sign_ima(const char *file, const char *key)
517 unsigned char hash[64];
518 unsigned char sig[1024];
521 len = ima_calc_hash(file, hash);
525 len = sign_hash(params.hash_algo, hash, len, key, sig + 1);
531 sig[0] = EVM_IMA_XATTR_DIGSIG;
533 if (sigdump || params.verbose >= LOG_INFO)
537 bin2file(file, "sig", sig, len);
540 err = lsetxattr(file, "security.ima", sig, len, 0);
542 log_err("setxattr failed: %s\n", file);
550 static int get_file_type(const char *path, const char *search_type)
555 for (i = 0; search_type[i]; i++) {
556 switch (search_type[i]) {
558 dts |= REG_MASK; break;
560 dts |= DIR_MASK; break;
562 dts |= BLK_MASK | CHR_MASK | LNK_MASK; break;
564 check_xattr = true; break;
566 /* stay within the same filesystem*/
567 err = lstat(path, &st);
569 log_err("Failed to stat: %s\n", path);
572 fs_dev = st.st_dev; /* filesystem to start from */
580 static int sign_ima_file(const char *file)
584 key = params.keyfile ? : "/etc/keys/privkey_evm.pem";
586 return sign_ima(file, key);
589 static int cmd_sign_ima(struct command *cmd)
591 char *file = g_argv[optind++];
592 int err, dts = REG_MASK; /* only regular files by default */
595 log_err("Parameters missing\n");
602 dts = get_file_type(file, search_type);
606 err = find(file, dts, sign_ima_file);
608 err = sign_ima_file(file);
614 static int cmd_sign_hash(struct command *cmd)
616 char *key, *token, *line = NULL;
620 unsigned char hash[64];
621 unsigned char sig[1024] = "\x03";
624 key = params.keyfile ? : "/etc/keys/privkey_evm.pem";
626 /* support reading hash (eg. output of shasum) */
627 while ((len = getline(&line, &line_len, stdin)) > 0) {
628 /* remove end of line */
629 if (line[len - 1] == '\n')
632 /* find the end of the hash */
633 token = strpbrk(line, ", \t");
634 hashlen = token ? token - line : strlen(line);
636 hex2bin(hash, line, hashlen);
637 siglen = sign_hash(params.hash_algo, hash, hashlen/2,
642 fwrite(line, len, 1, stdout);
643 fprintf(stdout, " ");
644 bin2hex(sig, siglen + 1, stdout);
645 fprintf(stdout, "\n");
649 log_err("Parameters missing\n");
657 static int sign_evm_path(const char *file)
662 key = params.keyfile ? : "/etc/keys/privkey_evm.pem";
665 err = sign_ima(file, key);
671 err = hash_ima(file);
676 return sign_evm(file, key);
679 static int cmd_sign_evm(struct command *cmd)
681 char *path = g_argv[optind++];
682 int err, dts = REG_MASK; /* only regular files by default */
685 log_err("Parameters missing\n");
692 dts = get_file_type(path, search_type);
696 err = find(path, dts, sign_evm_path);
698 err = sign_evm_path(path);
704 static int verify_evm(const char *file)
706 unsigned char hash[20];
707 unsigned char sig[1024];
710 len = calc_evm_hash(file, hash);
714 len = lgetxattr(file, "security.evm", sig, sizeof(sig));
716 log_err("getxattr failed: %s\n", file);
720 if (sig[0] != 0x03) {
721 log_err("security.evm has no signature\n");
725 return verify_hash(hash, sizeof(hash), sig + 1, len - 1);
728 static int cmd_verify_evm(struct command *cmd)
730 char *file = g_argv[optind++];
733 log_err("Parameters missing\n");
738 return verify_evm(file);
741 static int verify_ima(const char *file)
743 unsigned char sig[1024];
747 len = lgetxattr(file, "security.ima", sig, sizeof(sig));
749 log_err("getxattr failed: %s\n", file);
755 void *tmp = file2bin(file, "sig", &len);
757 memcpy(sig, tmp, len);
761 return ima_verify_signature(file, sig, len);
764 static int cmd_verify_ima(struct command *cmd)
766 char *file = g_argv[optind++];
769 log_err("Parameters missing\n");
774 return verify_ima(file);
777 static int cmd_import(struct command *cmd)
779 char *inkey, *ring = NULL;
780 unsigned char _pub[1024], *pub = _pub;
781 int id, len, err = 0;
786 inkey = g_argv[optind++];
788 inkey = params.x509 ? "/etc/keys/x509_evm.der" :
789 "/etc/keys/pubkey_evm.pem";
791 ring = g_argv[optind++];
793 id = KEY_SPEC_USER_KEYRING; /* default keyring */
796 if (ring[0] != '@') {
799 if (ring[0] == '0' && ring[1] == 'x')
801 id = strtoul(ring, NULL, base);
803 if (strcmp(ring, "@t") == 0)
805 else if (strcmp(ring, "@p") == 0)
807 else if (strcmp(ring, "@s") == 0)
809 else if (strcmp(ring, "@u") == 0)
811 else if (strcmp(ring, "@us") == 0)
813 else if (strcmp(ring, "@g") == 0)
818 key = read_pub_key(inkey, params.x509);
823 pub = file2bin(inkey, NULL, &len);
826 calc_keyid_v2((uint32_t *)keyid, name, key);
828 len = key2bin(key, pub);
829 calc_keyid_v1(keyid, name, pub, len);
832 log_info("Importing public key %s from file %s into keyring %d\n", name, inkey, id);
834 id = add_key(params.x509 ? "asymmetric" : "user", params.x509 ? NULL : name, pub, len, id);
836 log_err("add_key failed\n");
839 log_info("keyid: %d\n", id);
849 #define MAX_KEY_SIZE 128
851 static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *hash)
855 uint32_t generation = 0;
859 unsigned char xattr_value[1024];
862 unsigned char evmkey[MAX_KEY_SIZE];
865 struct h_misc_64 hmac_misc;
868 key = file2bin(keyfile, NULL, &keylen);
870 log_err("Failed to read a key: %s\n", keyfile);
874 if (keylen > sizeof(evmkey)) {
875 log_err("key is too long: %d\n", keylen);
879 /* EVM key is 128 bytes */
880 memcpy(evmkey, key, keylen);
881 memset(evmkey + keylen, 0, sizeof(evmkey) - keylen);
883 if (lstat(file, &st)) {
884 log_err("Failed to stat: %s\n", file);
888 if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode)) {
889 /* we cannot at the momement to get generation of special files..
890 * kernel API does not support it */
891 int fd = open(file, 0);
894 log_err("Failed to open %s\n", file);
897 if (ioctl(fd, FS_IOC_GETVERSION, &generation)) {
898 log_err("ioctl() failed\n");
904 log_info("generation: %u\n", generation);
906 list_size = llistxattr(file, list, sizeof(list));
907 if (list_size <= 0) {
908 log_err("llistxattr() failed: %s\n", file);
912 err = !HMAC_Init(&ctx, evmkey, sizeof(evmkey), EVP_sha1());
914 log_err("HMAC_Init() failed\n");
918 for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
919 err = lgetxattr(file, *xattrname, xattr_value, sizeof(xattr_value));
921 log_info("no xattr: %s\n", *xattrname);
924 if (!find_xattr(list, list_size, *xattrname)) {
925 log_info("skipping xattr: %s\n", *xattrname);
928 /*log_debug("name: %s, value: %s, size: %d\n", *xattrname, xattr_value, err);*/
929 log_info("name: %s, size: %d\n", *xattrname, err);
930 log_debug_dump(xattr_value, err);
931 err = !HMAC_Update(&ctx, xattr_value, err);
933 log_err("HMAC_Update() failed\n");
934 goto out_ctx_cleanup;
938 memset(&hmac_misc, 0, sizeof(hmac_misc));
941 struct h_misc *hmac = (struct h_misc *)&hmac_misc;
943 hmac_size = sizeof(*hmac);
944 hmac->ino = st.st_ino;
945 hmac->generation = generation;
946 hmac->uid = st.st_uid;
947 hmac->gid = st.st_gid;
948 hmac->mode = st.st_mode;
949 } else if (msize == 64) {
950 struct h_misc_64 *hmac = (struct h_misc_64 *)&hmac_misc;
952 hmac_size = sizeof(*hmac);
953 hmac->ino = st.st_ino;
954 hmac->generation = generation;
955 hmac->uid = st.st_uid;
956 hmac->gid = st.st_gid;
957 hmac->mode = st.st_mode;
959 struct h_misc_32 *hmac = (struct h_misc_32 *)&hmac_misc;
961 hmac_size = sizeof(*hmac);
962 hmac->ino = st.st_ino;
963 hmac->generation = generation;
964 hmac->uid = st.st_uid;
965 hmac->gid = st.st_gid;
966 hmac->mode = st.st_mode;
969 log_debug("hmac_misc (%d): ", hmac_size);
970 log_debug_dump(&hmac_misc, hmac_size);
972 err = !HMAC_Update(&ctx, (const unsigned char *)&hmac_misc, hmac_size);
974 log_err("HMAC_Update() failed\n");
975 goto out_ctx_cleanup;
977 err = !HMAC_Final(&ctx, hash, &mdlen);
979 log_err("HMAC_Final() failed\n");
981 HMAC_CTX_cleanup(&ctx);
987 static int hmac_evm(const char *file, const char *key)
989 unsigned char hash[20];
990 unsigned char sig[1024];
993 len = calc_evm_hmac(file, key, hash);
999 memcpy(sig + 1, hash, len);
1002 sig[0] = EVM_XATTR_HMAC;
1003 err = lsetxattr(file, "security.evm", sig, len + 1, 0);
1005 log_err("setxattr failed: %s\n", file);
1013 static int cmd_hmac_evm(struct command *cmd)
1015 char *key, *file = g_argv[optind++];
1019 log_err("Parameters missing\n");
1024 key = params.keyfile ? : "/etc/keys/privkey_evm.pem";
1027 err = sign_ima(file, key);
1033 err = hash_ima(file);
1038 return hmac_evm(file, "/etc/keys/evm-key-plain");
1041 static int ima_fix(const char *path)
1043 int fd, size, len, ima = 0, evm = 0;
1044 char buf[1024], *list = buf;
1046 log_info("%s\n", path);
1049 /* re-measuring takes a time
1050 * in some cases we can skip labeling if xattrs exists
1052 size = llistxattr(path, list, sizeof(buf));
1054 log_errno("Failed to read xattrs (llistxattr): %s\n", path);
1057 for (; size > 0; len++, size -= len, list += len) {
1059 if (!strcmp(list, "security.ima"))
1061 else if (!strcmp(list, "security.evm"))
1068 fd = open(path, O_RDONLY);
1070 log_errno("Failed to open file: %s", path);
1079 static int find(const char *path, int dts, find_cb_t func)
1086 int err = lstat(path, &st);
1089 log_err("Failed to stat: %s\n", path);
1092 if (st.st_dev != fs_dev)
1096 dir = opendir(path);
1098 log_err("Failed to open directory %s\n", path);
1102 if (fchdir(dirfd(dir))) {
1103 log_err("Failed to chdir %s\n", path);
1107 while ((de = readdir(dir))) {
1108 if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, "."))
1110 log_debug("path: %s, type: %u\n", de->d_name, de->d_type);
1111 if (de->d_type == DT_DIR)
1112 find(de->d_name, dts, func);
1113 else if (dts & (1 << de->d_type))
1118 log_err("Failed to chdir: %s\n", path);
1130 static int cmd_ima_fix(struct command *cmd)
1132 char *path = g_argv[optind++];
1133 int err, dts = REG_MASK; /* only regular files by default */
1136 log_err("Parameters missing\n");
1143 dts = get_file_type(path, search_type);
1147 err = find(path, dts, ima_fix);
1149 err = ima_fix(path);
1156 static char *pcrs = "/sys/class/misc/tpm0/device/pcrs";
1158 static int tpm_pcr_read(int idx, uint8_t *pcr, int len)
1161 char *p, pcr_str[7], buf[70]; /* length of the TPM string */
1163 sprintf(pcr_str, "PCR-%d", idx);
1165 fp = fopen(pcrs, "r");
1167 log_err("Unable to open %s\n", pcrs);
1172 p = fgets(buf, sizeof(buf), fp);
1175 if (!strncmp(p, pcr_str, 6)) {
1176 hex2bin(pcr, p + 7, len);
1184 #define TCG_EVENT_NAME_LEN_MAX 255
1186 struct template_entry {
1189 uint8_t digest[SHA_DIGEST_LENGTH];
1192 char name[TCG_EVENT_NAME_LEN_MAX + 1];
1195 int template_buf_len;
1198 static uint8_t zero[SHA_DIGEST_LENGTH];
1199 static uint8_t fox[SHA_DIGEST_LENGTH];
1203 void ima_extend_pcr(uint8_t *pcr, uint8_t *digest, int length)
1208 SHA1_Update(&ctx, pcr, length);
1209 if (validate && !memcmp(digest, zero, length))
1210 SHA1_Update(&ctx, fox, length);
1212 SHA1_Update(&ctx, digest, length);
1213 SHA1_Final(pcr, &ctx);
1216 static int ima_verify_tamplate_hash(struct template_entry *entry)
1218 uint8_t digest[SHA_DIGEST_LENGTH];
1220 if (!memcmp(zero, entry->header.digest, sizeof(zero)))
1223 SHA1(entry->template, entry->template_len, digest);
1225 if (memcmp(digest, entry->header.digest, sizeof(digest))) {
1226 log_err("template hash error\n");
1233 void ima_show(struct template_entry *entry)
1235 log_debug("ima, digest: ");
1236 log_debug_dump(entry->header.digest, sizeof(entry->header.digest));
1239 void ima_ng_show(struct template_entry *entry)
1241 uint8_t *fieldp = entry->template;
1243 int total_len = entry->template_len, digest_len, len, sig_len;
1244 uint8_t *digest, *sig = NULL;
1247 /* get binary digest */
1248 field_len = *(uint8_t *)fieldp;
1249 fieldp += sizeof(field_len);
1250 total_len -= sizeof(field_len);
1252 algo = (char *)fieldp;
1253 len = strlen(algo) + 1;
1254 digest_len = field_len - len;
1255 digest = fieldp + len;
1257 /* move to next field */
1258 fieldp += field_len;
1259 total_len -= field_len;
1262 field_len = *(uint8_t *)fieldp;
1263 fieldp += sizeof(field_len);
1264 total_len -= sizeof(field_len);
1266 path = (char *)fieldp;
1268 /* move to next field */
1269 fieldp += field_len;
1270 total_len -= field_len;
1272 if (!strcmp(entry->name, "ima-sig")) {
1274 field_len = *(uint8_t *)fieldp;
1275 fieldp += sizeof(field_len);
1276 total_len -= sizeof(field_len);
1280 sig_len = field_len;
1282 /* move to next field */
1283 fieldp += field_len;
1284 total_len -= field_len;
1288 /* ascii_runtime_measurements */
1289 log_info("%d ", entry->header.pcr);
1290 log_dump_n(entry->header.digest, sizeof(entry->header.digest));
1291 log_info(" %s %s", entry->name, algo);
1292 log_dump_n(digest, digest_len);
1293 log_info(" %s", path);
1297 log_dump(sig, sig_len);
1298 ima_verify_signature(path, sig, sig_len);
1303 log_err("Remain unprocessed data: %d\n", total_len);
1306 static int ima_measurement(const char *file)
1308 uint8_t pcr[SHA_DIGEST_LENGTH] = {0,};
1309 uint8_t pcr10[SHA_DIGEST_LENGTH];
1310 struct template_entry entry = { .template = 0 };
1314 memset(fox, 0xff, SHA_DIGEST_LENGTH);
1316 log_debug("Initial PCR value: ");
1317 log_debug_dump(pcr, sizeof(pcr));
1319 fp = fopen(file, "rb");
1321 log_err("Failed to open measurement file: %s\n", file);
1325 while (fread(&entry.header, sizeof(entry.header), 1, fp)) {
1326 ima_extend_pcr(pcr, entry.header.digest, SHA_DIGEST_LENGTH);
1328 if (!fread(entry.name, entry.header.name_len, 1, fp)) {
1329 log_err("Unable to read template name\n");
1333 entry.name[entry.header.name_len] = '\0';
1335 if (!fread(&entry.template_len, sizeof(entry.template_len), 1, fp)) {
1336 log_err("Unable to read template length\n");
1340 if (entry.template_buf_len < entry.template_len) {
1341 free(entry.template);
1342 entry.template_buf_len = entry.template_len;
1343 entry.template = malloc(entry.template_len);
1346 if (!fread(entry.template, entry.template_len, 1, fp)) {
1347 log_err("Unable to read template\n");
1352 ima_verify_tamplate_hash(&entry);
1354 if (!strcmp(entry.name, "ima"))
1357 ima_ng_show(&entry);
1360 tpm_pcr_read(10, pcr10, sizeof(pcr10));
1362 log_info("PCRAgg: ");
1363 log_dump(pcr, sizeof(pcr));
1365 log_info("PCR-10: ");
1366 log_dump(pcr10, sizeof(pcr10));
1368 if (memcmp(pcr, pcr10, sizeof(pcr))) {
1369 log_err("PCRAgg does not match PCR-10\n");
1380 static int cmd_ima_measurement(struct command *cmd)
1382 char *file = g_argv[optind++];
1385 log_err("Parameters missing\n");
1390 return ima_measurement(file);
1393 static void print_usage(struct command *cmd)
1395 printf("usage: %s %s\n", cmd->name, cmd->arg ? cmd->arg : "");
1398 static void print_full_usage(struct command *cmd)
1401 printf("usage: %s %s\n", cmd->name, cmd->arg ? cmd->arg : "");
1403 printf("%s", cmd->msg);
1406 static int print_command_usage(struct command *cmds, char *command)
1408 struct command *cmd;
1410 for (cmd = cmds; cmd->name; cmd++) {
1411 if (strcmp(cmd->name, command) == 0) {
1412 print_full_usage(cmd);
1416 printf("invalid command: %s\n", command);
1420 static void print_all_usage(struct command *cmds)
1422 struct command *cmd;
1424 printf("commands:\n");
1426 for (cmd = cmds; cmd->name; cmd++) {
1428 printf(" %s %s\n", cmd->name, cmd->arg);
1430 printf(" %s", cmd->msg);
1434 static int call_command(struct command *cmds, char *command)
1436 struct command *cmd;
1438 for (cmd = cmds; cmd->name; cmd++) {
1439 if (strcasecmp(cmd->name, command) == 0)
1440 return cmd->func(cmd);
1442 printf("Invalid command: %s\n", command);
1446 static int cmd_help(struct command *cmd)
1448 if (!g_argv[optind]) {
1452 return print_command_usage(cmds, g_argv[optind]);
1455 static void usage(void)
1457 printf("Usage: evmctl [-v] <command> [OPTIONS]\n");
1459 print_all_usage(cmds);
1463 " -a, --hashalgo sha1 (default), sha224, sha256, sha384, sha512\n"
1464 " -s, --imasig make IMA signature\n"
1465 " -d, --imahash make IMA hash\n"
1466 " -f, --sigfile store IMA signature in .sig file instead of xattr\n"
1467 " --rsa use RSA key type and signing scheme v1\n"
1468 " -k, --key path to signing key (default: /etc/keys/{privkey,pubkey}_evm.pem)\n"
1469 " -p, --pass password for encrypted signing key\n"
1470 " -r, --recursive recurse into directories (sign)\n"
1471 " -t, --type file types to fix 'fdsxm' (f: file, d: directory, s: block/char/symlink)\n"
1472 " x - skip fixing if both ima and evm xattrs exist (use with caution)\n"
1473 " m - stay on the same filesystem (like 'find -xdev')\n"
1474 " -n print result to stdout instead of setting xattr\n"
1475 " -u, --uuid use custom FS UUID for EVM (unspecified: from FS, empty: do not use)\n"
1476 " --smack use extra SMACK xattrs for EVM\n"
1477 " --m32 force EVM hmac/signature for 32 bit target system\n"
1478 " --m64 force EVM hmac/signature for 64 bit target system\n"
1479 " -v increase verbosity level\n"
1480 " -h, --help display this help and exit\n"
1484 struct command cmds[] = {
1485 {"--version", NULL, 0, ""},
1486 {"help", cmd_help, 0, "<command>"},
1487 {"import", cmd_import, 0, "[--rsa] pubkey keyring", "Import public key into the keyring.\n"},
1488 {"sign", cmd_sign_evm, 0, "[-r] [--imahash | --imasig ] [--key key] [--pass password] file", "Sign file metadata.\n"},
1489 {"verify", cmd_verify_evm, 0, "file", "Verify EVM signature (for debugging).\n"},
1490 {"ima_sign", cmd_sign_ima, 0, "[--sigfile] [--key key] [--pass password] file", "Make file content signature.\n"},
1491 {"ima_verify", cmd_verify_ima, 0, "file", "Verify IMA signature (for debugging).\n"},
1492 {"ima_hash", cmd_hash_ima, 0, "file", "Make file content hash.\n"},
1493 {"ima_measurement", cmd_ima_measurement, 0, "file", "Verify measurement list (experimental).\n"},
1494 {"ima_fix", cmd_ima_fix, 0, "[-t fdsxm] path", "Recursively fix IMA/EVM xattrs in fix mode.\n"},
1495 {"sign_hash", cmd_sign_hash, 0, "[--key key] [--pass password]", "Sign hashes from shaXsum output.\n"},
1497 {"hmac", cmd_hmac_evm, 0, "[--imahash | --imasig ] file", "Sign file metadata with HMAC using symmetric key (for testing purpose).\n"},
1502 static struct option opts[] = {
1503 {"help", 0, 0, 'h'},
1504 {"imasig", 0, 0, 's'},
1505 {"imahash", 0, 0, 'd'},
1506 {"hashalgo", 1, 0, 'a'},
1507 {"pass", 1, 0, 'p'},
1508 {"sigfile", 0, 0, 'f'},
1509 {"uuid", 2, 0, 'u'},
1512 {"type", 1, 0, 't'},
1513 {"recursive", 0, 0, 'r'},
1516 {"smack", 0, 0, 256},
1517 {"version", 0, 0, 257},
1522 int main(int argc, char *argv[])
1524 int err = 0, c, lind;
1530 c = getopt_long(argc, argv, "hvnsda:p:fu::k:t:r", opts, &lind);
1549 /* do not set Extended Attributes... just print signature */
1554 params.hash_algo = optarg;
1557 params.keypass = optarg;
1566 hmac_flags |= HMAC_FLAG_UUID_SET;
1568 hmac_flags &= ~HMAC_FLAG_UUID;
1574 params.keyfile = optarg;
1577 search_type = optarg;
1589 evm_config_xattrnames = evm_extra_smack_xattrs;
1592 printf("evmctl %s\n", VERSION);
1599 log_err("getopt() returned: %d (%c)\n", c, c);
1603 OpenSSL_add_all_algorithms();
1604 ERR_load_crypto_strings();
1606 if (argv[optind] == NULL)
1609 err = call_command(cmds, argv[optind++]);
1612 unsigned long error;
1615 log_err("errno: %s (%d)\n", strerror(errno), errno);
1617 error = ERR_get_error();
1620 log_err("%s\n", ERR_error_string(error, NULL));