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#include <stdio.h> 18#include <stdlib.h> 19#include <sys/types.h> 20#include <sys/stat.h> 21#include <fcntl.h> 22#include <string.h> 23#include <unistd.h> 24 25#include "config.h" 26#include "test.h" 27 28char *TCID = "ima_boot_aggregate"; 29 30#if HAVE_LIBCRYPTO 31#include <openssl/sha.h> 32 33#define MAX_EVENT_SIZE 500 34#define EVENT_HEADER_SIZE 32 35#define MAX_EVENT_DATA_SIZE (MAX_EVENT_SIZE - EVENT_HEADER_SIZE) 36#define NUM_PCRS 8 /* PCR registers 0-7 in boot aggregate */ 37 38int TST_TOTAL = 1; 39 40static 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 49int main(int argc, char *argv[]) 50{ 51 unsigned char boot_aggregate[SHA_DIGEST_LENGTH]; 52 struct { 53 struct { 54 u_int32_t pcr; 55 int type; 56 unsigned char digest[SHA_DIGEST_LENGTH]; 57 u_int16_t len; 58 } header; 59 unsigned char data[MAX_EVENT_DATA_SIZE]; 60 } event; 61 struct { 62 unsigned char digest[SHA_DIGEST_LENGTH]; 63 } pcr[NUM_PCRS]; 64 FILE *fp; 65 int i; 66 int debug = 0; 67 SHA_CTX c; 68 69 if (argc != 2) { 70 printf("format: %s binary_bios_measurement file\n", argv[0]); 71 return 1; 72 } 73 fp = fopen(argv[1], "r"); 74 if (!fp) { 75 perror("unable to open pcr file\n"); 76 return 1; 77 } 78 79 /* Initialize psuedo PCR registers 0 - 7 */ 80 for (i = 0; i < NUM_PCRS; i++) 81 memset(&pcr[i].digest, 0, SHA_DIGEST_LENGTH); 82 83 /* Extend the pseudo PCRs with the event digest */ 84 while (fread(&event, sizeof(event.header), 1, fp)) { 85 if (debug) { 86 printf("%03u ", event.header.pcr); 87 display_sha1_digest(event.header.digest); 88 } 89 SHA1_Init(&c); 90 SHA1_Update(&c, pcr[event.header.pcr].digest, 20); 91 SHA1_Update(&c, event.header.digest, 20); 92 SHA1_Final(pcr[event.header.pcr].digest, &c); 93 if (event.header.len > MAX_EVENT_DATA_SIZE) { 94 printf("Error event too long"); 95 break; 96 } 97 fread(event.data, event.header.len, 1, fp); 98 } 99 fclose(fp); 100 101 /* Extend the boot aggregate with the pseudo PCR digest values */ 102 memset(&boot_aggregate, 0, SHA_DIGEST_LENGTH); 103 SHA1_Init(&c); 104 for (i = 0; i < NUM_PCRS; i++) { 105 if (debug) { 106 printf("PCR-%2.2x: ", i); 107 display_sha1_digest(pcr[i].digest); 108 } 109 SHA1_Update(&c, pcr[i].digest, 20); 110 } 111 SHA1_Final(boot_aggregate, &c); 112 113 printf("boot_aggregate:"); 114 display_sha1_digest(boot_aggregate); 115 tst_exit(); 116} 117 118#else 119int main(void) 120{ 121 tst_brkm(TCONF, NULL, "test requires libcrypto and openssl development packages"); 122} 123#endif 124