|
From: Roberto S. <rob...@po...> - 2010-04-20 16:32:46
|
Hi all i modified the ima_measure utility to work with the patched version of IMA (the patch has been sent in the email with subject: "[RFC][PATCH V2][1/1] ima: extending the format of the measurement list"). I added a new parameter to specify the format that ima_measure will use to parse the measurements list: "-r, --ima_report_format = ima | ima-ng". Further, the management of parameters passed through the command line has been improved. More details can be seen by executing the command "./ima_measure -h". This patch applies on the package "ltp-full-20100331.tgz" downloadable at the url: http://sourceforge.net/projects/ltp/. To use the modified version of ima_measure, these command must be performed: 1) Save the patch included in this mail in a file ima_measure_patch.diff 2) Decompress the ltp package: tar zxf ltp-full-20100331.tgz 3) Enter the directory ltp-full-20100331 4) Apply the patch: cat ../ima_measure_patch.diff | patch -p1 -------------- ima_measure_patch.diff -------------- --- ltp-full-20100331/testcases/kernel/security/integrity/ima/src/ima_measure.c.orig 2010-04-20 18:10:10.588090056 +0200 +++ ltp-full-20100331/testcases/kernel/security/integrity/ima/src/ima_measure.c 2010-04-20 18:15:12.996783044 +0200 @@ -1,9 +1,12 @@ /* * Copyright (c) International Business Machines Corp., 2008 + * Copyright (C) 2009-2010 Politecnico di Torino, Italy, + * TORSEC group -- http://security.polito.it * * Authors: * Reiner Sailer <sa...@wa...> * Mimi Zohar <zo...@us...> + * Roberto Sassu <rob...@po...> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -22,6 +25,7 @@ #include <fcntl.h> #include <string.h> #include <unistd.h> +#include <getopt.h> //#include "config.h" #include "test.h" #if HAVE_OPENSSL_SHA_H @@ -29,6 +33,14 @@ #endif #define TCG_EVENT_NAME_LEN_MAX 255 +#define IMA_LABEL_LEN_MAX 127 + +#define IMA_REPORT_FORMAT_CURRENT 0 +#define IMA_REPORT_FORMAT_CURRENT_LEN offsetof(struct ima_template_data, subj_label) +#define IMA_REPORT_FORMAT_NG 1 +#define IMA_REPORT_FORMAT_NG_LEN sizeof(struct ima_template_data) + +#define IMA_BINARY_RUNTIME_MEASUREMENTS_PATH "/sys/kernel/security/ima/binary_runtime_measurements" char *TCID = "ima_measure"; int TST_TOTAL = 1; @@ -41,6 +53,17 @@ int TST_TOTAL = 1; static u_int8_t zero[SHA_DIGEST_LENGTH]; static u_int8_t fox[SHA_DIGEST_LENGTH]; +static int verbose = 0; +static int validate = 0; +static int verify = 0; +static int format = 0; + +typedef struct ima_template_data { + u_int8_t digest[SHA_DIGEST_LENGTH]; + char filename[TCG_EVENT_NAME_LEN_MAX + 1]; + char subj_label[IMA_LABEL_LEN_MAX + 1]; + char obj_label[IMA_LABEL_LEN_MAX + 1]; +} ima_template_data; struct event { struct { @@ -49,11 +72,10 @@ struct event { u_int32_t name_len; } header; char name[TCG_EVENT_NAME_LEN_MAX + 1]; - struct { - u_int8_t digest[SHA_DIGEST_LENGTH]; - char filename[TCG_EVENT_NAME_LEN_MAX + 1]; - } ima_data; + struct ima_template_data ima_data; int filename_len; + int subj_label_len; + int obj_label_len; }; static void display_sha1_digest(u_int8_t *digest) @@ -67,14 +89,22 @@ static void display_sha1_digest(u_int8_t /* * Calculate the sha1 hash of data */ -static void calc_digest(u_int8_t *digest, int len, void *data ) +static void calc_digest(u_int8_t *digest, void *data ) { SHA_CTX c; /* Calc template hash for an ima entry */ memset(digest, 0, sizeof *digest); SHA1_Init(&c); - SHA1_Update(&c, data, len); + + SHA1_Update(&c, (u_int8_t *) data, IMA_REPORT_FORMAT_CURRENT_LEN); + if(format == IMA_REPORT_FORMAT_CURRENT) + goto calc_digest_final; + + SHA1_Update(&c, data + IMA_REPORT_FORMAT_CURRENT_LEN, + IMA_REPORT_FORMAT_NG_LEN - IMA_REPORT_FORMAT_CURRENT_LEN); + +calc_digest_final: SHA1_Final(digest, &c); } @@ -87,8 +117,7 @@ static int verify_template_hash(struct e u_int8_t digest[SHA_DIGEST_LENGTH]; memset(digest, 0, sizeof digest); - calc_digest(digest, sizeof template->ima_data, - &template->ima_data); + calc_digest(digest, &template->ima_data); rc = memcmp(digest, template->header.digest, sizeof digest); return rc != 0 ? 1 : 0; } @@ -101,32 +130,83 @@ static int verify_template_hash(struct e * ima_measurements.c - calculate the SHA1 aggregate-pcr value based * on the IMA runtime binary measurements. * - * format: ima_measurement [--validate] [--verify] [--verbose] + * format: ima_measurement [ -xyv ] [--ima_report_format = ima | ima-ng] * - * --validate: forces validation of the aggregrate pcr value - * for an invalidated PCR. Replace all entries in the - * runtime binary measurement list with 0x00 hash values, - * which indicate the PCR was invalidated, either for - * "a time of measure, time of use"(ToMToU) error, or a - * file open for read was already open for write, with - * 0xFF's hash value, when calculating the aggregate - * pcr value. - * - * --verify: for all IMA template entries in the runtime binary - * measurement list, calculate the template hash value - * and compare it with the actual template hash value. - * Return the number of incorrect hash measurements. + * -x, --validate: forces validation of the aggregrate pcr value + * for an invalidated PCR. Replace all entries in the + * runtime binary measurement list with 0x00 hash values, + * which indicate the PCR was invalidated, either for + * "a time of measure, time of use"(ToMToU) error, or a + * file open for read was already open for write, with + * 0xFF's hash value, when calculating the aggregate + * pcr value. * - * --verbose: For all entries in the runtime binary measurement - * list, display the template information. + * -y, --verify: for all IMA template entries in the runtime binary + * measurement list, calculate the template hash value + * and compare it with the actual template hash value. + * Return the number of incorrect hash measurements. + * + * -v, --verbose: For all entries in the runtime binary measurement + * list, display the template information. + * + * -r, --ima_report_format = ima | ima-ng + * Select the format of the measurement list displayed + * through the securityfs filesystem. The first value + * means the actual format is kept; the second one adds + * to each item of the list the subject and object MAC + * labels, if existent. * * template info: list #, PCR-register #, template hash, template name - * IMA info: IMA hash, filename hint + * IMA info: IMA hash, filename hint [, subject_label, object_label ] * * Ouput: displays the aggregate-pcr value * Return code: if verification enabled, returns number of verification * errors. */ + +struct option opts[] = { + {"validate", no_argument, 0, 'x'}, + {"verify", no_argument, 0, 'y'}, + {"verbose", no_argument, 0, 'v'}, + {"ima_report_format", required_argument, 0, 'r'}, + {"ima_pathname", required_argument, 0, 'f'}, +}; + +void +usage(char *argv0) +{ + fprintf(stderr, "%s: calculate the SHA1 aggregate-pcr value based " + "on the IMA runtime binary measurements\n" + "Usage: %s [options]\n" + "Options:\n" + "\t-x,--validate\tforces validation of the aggregrate pcr value\n" + "\t\t\tor an invalidated PCR. Replace all entries in the\n" + "\t\t\truntime binary measurement list with 0x00 hash values,\n" + "\t\t\twhich indicate the PCR was invalidated, either for\n" + "\t\t\t\"a time of measure, time of use\"(ToMToU) error, or a\n" + "\t\t\tfile open for read was already open for write, with\n" + "\t\t\t0xFF's hash value, when calculating the aggregate\n" + "\t\t\tpcr value.\n" + "\t-y,--verify\tfor all IMA template entries in the runtime binary\n" + "\t\t\tmeasurement list, calculate the template hash value\n" + "\t\t\tand compare it with the actual template hash value.\n" + "\t\t\tReturn the number of incorrect hash measurements.\n" + "\t-v,--verbose\tfor all entries in the runtime binary measurement\n" + "\t\t\tlist, display the template information.\n" + "\t-r,--ima_report_format = ima | ima-ng\n" + "\t\t\tselect the format of the measurement list displayed\n" + "\t\t\tthrough the securityfs filesystem. The first value\n" + "\t\t\tmeans the actual format is kept; the second one adds\n" + "\t\t\tto each item of the list the subject and object MAC\n" + "\t\t\tlabels, if existent.\n" + "\t-f,--ima_pathname = pathname\n" + "\t\t\tspecify the path of the \"binary_runtime_measurements\"\n" + "\t\t\tfile from which the list of measurements is obtained\n" + "\t-h,--help\tdisplay this message.\n", + argv0, argv0); + exit(-1); +} + int main(int argc, char *argv[]) { @@ -135,31 +215,51 @@ main(int argc, char *argv[]) FILE *fp; struct event template; u_int8_t pcr[SHA_DIGEST_LENGTH]; - int i, count = 0, len; - - int verbose = 0; - int validate = 0; - int verify = 0; - - if (argc < 2) { - printf("format: %s binary_runtime_measurements" \ - " [--validate] [--verbose] [--verify]\n", argv[0]); - return 1; + int count = 0; + char c; + char *path = NULL; + + while ((c = getopt_long(argc, argv, "hxyvr:f:", opts, 0)) != -1) { + switch (c) { + case 'x': + validate = 1; + break; + case 'v': + verbose = 1; + break; + case 'y': + verify = 1; + break; + case 'r': + if(strncmp(optarg, "ima-ng", 6) == 0) + format = IMA_REPORT_FORMAT_NG; + break; + case 'f': + path = strdup(optarg); + break; + case 'h': + usage(argv[0]);; + break; + default: + printf("Bad option %c\n", c); + usage(argv[0]); + return -1; + } } - - for (i = 2; i < argc; i++) { - if (strncmp(argv[i], "--validate", 8) == 0) - validate = 1; - if (strncmp(argv[i], "--verbose", 7) == 0) - verbose = 1; - if (strncmp(argv[i], "--verify", 6) == 0) - verify = 1; + + if(!path) { + path = strdup(IMA_BINARY_RUNTIME_MEASUREMENTS_PATH); + if(!path) { + perror("Out of memory\n"); + return 1; + } } - fp = fopen(argv[1], "r"); + fp = fopen(path, "r"); if (!fp) { printf("fn: %s\n", argv[1]); perror("Unable to open file\n"); + free(path); return 1; } memset(pcr, 0, SHA_DIGEST_LENGTH); /* initial PCR content 0..0 */ @@ -187,6 +287,7 @@ main(int argc, char *argv[]) if (template.header.name_len > TCG_EVENT_NAME_LEN_MAX) { printf("%d ERROR: event name too long!\n", template.header.name_len); + free(path); exit(1); } memset(template.name, 0, sizeof template.name); @@ -201,7 +302,20 @@ main(int argc, char *argv[]) fread(&template.filename_len, sizeof template.filename_len, 1, fp); fread(template.ima_data.filename, template.filename_len, 1, fp); - print_info(" %s\n", template.ima_data.filename); + print_info(" %s", template.ima_data.filename); + + if (format != IMA_REPORT_FORMAT_CURRENT) { + fread(&template.subj_label_len, + sizeof template.filename_len, 1, fp); + fread(template.ima_data.subj_label, template.subj_label_len, 1, fp); + print_info(" %s", template.ima_data.subj_label); + + fread(&template.obj_label_len, + sizeof template.obj_label_len, 1, fp); + fread(template.ima_data.obj_label, template.obj_label_len, 1, fp); + print_info(" %s", template.ima_data.obj_label); + } + print_info("\n"); if (verify) if (verify_template_hash(&template) != 0) { @@ -210,9 +324,11 @@ main(int argc, char *argv[]) } fclose(fp); + free(path); verbose=1; print_info("PCRAggr (re-calculated):"); display_sha1_digest(pcr); + print_info("\n"); #else tst_resm(TCONF, "System doesn't have openssl/sha.h"); #endif |