| /* |
| * Copyright (c) International Business Machines Corp., 2009 |
| * |
| * Authors: |
| * Mimi Zohar <zohar@us.ibm.com> |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License as |
| * published by the Free Software Foundation, version 2 of the |
| * License. |
| * |
| * File: ima_boot_aggregate.c |
| * |
| * Calculate a SHA1 boot aggregate value based on the TPM |
| * binary_bios_measurements. |
| * |
| * Requires openssl; compile with -lcrypto option |
| */ |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include "config.h" |
| #include "test.h" |
| #if HAVE_OPENSSL_SHA_H |
| #include <openssl/sha.h> |
| #endif |
| |
| #define MAX_EVENT_SIZE 500 |
| #define EVENT_HEADER_SIZE 32 |
| #define MAX_EVENT_DATA_SIZE (MAX_EVENT_SIZE - EVENT_HEADER_SIZE) |
| #define NUM_PCRS 8 /* PCR registers 0-7 in boot aggregate */ |
| |
| char *TCID = "ima_boot_aggregate"; |
| int TST_TOTAL = 1; |
| |
| static void display_sha1_digest(unsigned char *pcr) |
| { |
| int i; |
| |
| for (i = 0; i < 20; i++) |
| printf("%02x", *(pcr + i) & 0xff); |
| printf("\n"); |
| } |
| |
| int |
| main(int argc, char *argv[]) |
| { |
| #if HAVE_OPENSSL_SHA_H |
| unsigned char boot_aggregate[SHA_DIGEST_LENGTH]; |
| struct { |
| struct { |
| u_int32_t pcr; |
| int type; |
| unsigned char digest[SHA_DIGEST_LENGTH]; |
| u_int16_t len; |
| } header; |
| unsigned char data[MAX_EVENT_DATA_SIZE]; |
| } event; |
| struct { |
| unsigned char digest[SHA_DIGEST_LENGTH]; |
| } pcr[NUM_PCRS]; |
| FILE *fp; |
| int i; |
| int debug = 0; |
| SHA_CTX c; |
| |
| if (argc != 2) { |
| printf("format: %s binary_bios_measurement file\n", argv[0]); |
| return 1; |
| } |
| fp = fopen(argv[1], "r"); |
| if (!fp) { |
| perror("unable to open pcr file\n"); |
| return 1; |
| } |
| |
| /* Initialize psuedo PCR registers 0 - 7 */ |
| for (i = 0; i < NUM_PCRS; i++) |
| memset(&pcr[i].digest, 0, SHA_DIGEST_LENGTH); |
| |
| /* Extend the pseudo PCRs with the event digest */ |
| while (fread(&event, sizeof(event.header), 1, fp)) { |
| if (debug) { |
| printf("%03u ", event.header.pcr); |
| display_sha1_digest(event.header.digest); |
| } |
| SHA1_Init(&c); |
| SHA1_Update(&c, pcr[event.header.pcr].digest, 20); |
| SHA1_Update(&c, event.header.digest, 20); |
| SHA1_Final(pcr[event.header.pcr].digest, &c); |
| if (event.header.len > MAX_EVENT_DATA_SIZE) { |
| printf("Error event too long"); |
| break; |
| } |
| fread(event.data, event.header.len, 1, fp); |
| } |
| fclose(fp); |
| |
| /* Extend the boot aggregate with the pseudo PCR digest values */ |
| memset(&boot_aggregate, 0, SHA_DIGEST_LENGTH); |
| SHA1_Init(&c); |
| for (i = 0; i < NUM_PCRS; i++) { |
| if (debug) { |
| printf("PCR-%2.2x: ", i); |
| display_sha1_digest(pcr[i].digest); |
| } |
| SHA1_Update(&c, pcr[i].digest, 20); |
| } |
| SHA1_Final(boot_aggregate, &c); |
| |
| printf("boot_aggregate:"); |
| display_sha1_digest(boot_aggregate); |
| #else |
| tst_resm(TCONF, "System doesn't have openssl/sha.h"); |
| #endif |
| tst_exit(); |
| } |