1 /*
2 * Copyright (c) International Business Machines Corp., 2009
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2 of the
10 * License.
11 *
12 * File: ima_boot_aggregate.c
13 *
14 * Calculate a SHA1 boot aggregate value based on the TPM
15 * binary_bios_measurements.
16 *
17 * Requires openssl; compile with -lcrypto option
18 */
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include "config.h"
27 #include "test.h"
28 #if HAVE_OPENSSL_SHA_H
29 #include <openssl/sha.h>
30 #endif
31
32 #define MAX_EVENT_SIZE 500
33 #define EVENT_HEADER_SIZE 32
34 #define MAX_EVENT_DATA_SIZE (MAX_EVENT_SIZE - EVENT_HEADER_SIZE)
35 #define NUM_PCRS 8 /* PCR registers 0-7 in boot aggregate */
36
37 char *TCID = "ima_boot_aggregate";
38 int TST_TOTAL = 1;
39
display_sha1_digest(unsigned char * pcr)40 static void display_sha1_digest(unsigned char *pcr)
41 {
42 int i;
43
44 for (i = 0; i < 20; i++)
45 printf("%02x", *(pcr + i) & 0xff);
46 printf("\n");
47 }
48
main(int argc,char * argv[])49 int main(int argc, char *argv[])
50 {
51 #if HAVE_OPENSSL_SHA_H
52 unsigned char boot_aggregate[SHA_DIGEST_LENGTH];
53 struct {
54 struct {
55 u_int32_t pcr;
56 int type;
57 unsigned char digest[SHA_DIGEST_LENGTH];
58 u_int16_t len;
59 } header;
60 unsigned char data[MAX_EVENT_DATA_SIZE];
61 } event;
62 struct {
63 unsigned char digest[SHA_DIGEST_LENGTH];
64 } pcr[NUM_PCRS];
65 FILE *fp;
66 int i;
67 int debug = 0;
68 SHA_CTX c;
69
70 if (argc != 2) {
71 printf("format: %s binary_bios_measurement file\n", argv[0]);
72 return 1;
73 }
74 fp = fopen(argv[1], "r");
75 if (!fp) {
76 perror("unable to open pcr file\n");
77 return 1;
78 }
79
80 /* Initialize psuedo PCR registers 0 - 7 */
81 for (i = 0; i < NUM_PCRS; i++)
82 memset(&pcr[i].digest, 0, SHA_DIGEST_LENGTH);
83
84 /* Extend the pseudo PCRs with the event digest */
85 while (fread(&event, sizeof(event.header), 1, fp)) {
86 if (debug) {
87 printf("%03u ", event.header.pcr);
88 display_sha1_digest(event.header.digest);
89 }
90 SHA1_Init(&c);
91 SHA1_Update(&c, pcr[event.header.pcr].digest, 20);
92 SHA1_Update(&c, event.header.digest, 20);
93 SHA1_Final(pcr[event.header.pcr].digest, &c);
94 if (event.header.len > MAX_EVENT_DATA_SIZE) {
95 printf("Error event too long");
96 break;
97 }
98 fread(event.data, event.header.len, 1, fp);
99 }
100 fclose(fp);
101
102 /* Extend the boot aggregate with the pseudo PCR digest values */
103 memset(&boot_aggregate, 0, SHA_DIGEST_LENGTH);
104 SHA1_Init(&c);
105 for (i = 0; i < NUM_PCRS; i++) {
106 if (debug) {
107 printf("PCR-%2.2x: ", i);
108 display_sha1_digest(pcr[i].digest);
109 }
110 SHA1_Update(&c, pcr[i].digest, 20);
111 }
112 SHA1_Final(boot_aggregate, &c);
113
114 printf("boot_aggregate:");
115 display_sha1_digest(boot_aggregate);
116 #else
117 tst_resm(TCONF, "System doesn't have openssl/sha.h");
118 #endif
119 tst_exit();
120 }
121