1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2014 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker */
5*8617a60dSAndroid Build Coastguard Worker
6*8617a60dSAndroid Build Coastguard Worker #include <ctype.h>
7*8617a60dSAndroid Build Coastguard Worker #include <getopt.h>
8*8617a60dSAndroid Build Coastguard Worker #include <stdint.h>
9*8617a60dSAndroid Build Coastguard Worker #include <stdio.h>
10*8617a60dSAndroid Build Coastguard Worker #include <string.h>
11*8617a60dSAndroid Build Coastguard Worker
12*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
13*8617a60dSAndroid Build Coastguard Worker #include "2sha.h"
14*8617a60dSAndroid Build Coastguard Worker #include "2sysincludes.h"
15*8617a60dSAndroid Build Coastguard Worker #include "futility.h"
16*8617a60dSAndroid Build Coastguard Worker
17*8617a60dSAndroid Build Coastguard Worker static const char usage[] = "\n"
18*8617a60dSAndroid Build Coastguard Worker "Usage: " MYNAME " %s [OPTIONS] DIGEST [...]\n"
19*8617a60dSAndroid Build Coastguard Worker "\n"
20*8617a60dSAndroid Build Coastguard Worker "This simulates a TPM PCR extension, to determine the expected output\n"
21*8617a60dSAndroid Build Coastguard Worker "\n"
22*8617a60dSAndroid Build Coastguard Worker "Each DIGEST arg should be a hex string (spaces optional) of the\n"
23*8617a60dSAndroid Build Coastguard Worker "appropriate length. The PCR is extended with each digest in turn\n"
24*8617a60dSAndroid Build Coastguard Worker "and the new value displayed.\n"
25*8617a60dSAndroid Build Coastguard Worker "\n"
26*8617a60dSAndroid Build Coastguard Worker "Options:\n"
27*8617a60dSAndroid Build Coastguard Worker " -i Initialize the PCR with the first DIGEST argument\n"
28*8617a60dSAndroid Build Coastguard Worker " (the default is to start with all zeros)\n"
29*8617a60dSAndroid Build Coastguard Worker " -2 Use sha256 DIGESTS (the default is sha1)\n"
30*8617a60dSAndroid Build Coastguard Worker "\n"
31*8617a60dSAndroid Build Coastguard Worker "Examples:\n"
32*8617a60dSAndroid Build Coastguard Worker "\n"
33*8617a60dSAndroid Build Coastguard Worker " " MYNAME " %s b52791126f96a21a8ba4d511c6f25a1c1eb6dc9e\n"
34*8617a60dSAndroid Build Coastguard Worker " " MYNAME " %s "
35*8617a60dSAndroid Build Coastguard Worker "'b5 27 91 12 6f 96 a2 1a 8b a4 d5 11 c6 f2 5a 1c 1e b6 dc 9e'\n"
36*8617a60dSAndroid Build Coastguard Worker "\n";
37*8617a60dSAndroid Build Coastguard Worker
print_help(int argc,char * argv[])38*8617a60dSAndroid Build Coastguard Worker static void print_help(int argc, char *argv[])
39*8617a60dSAndroid Build Coastguard Worker {
40*8617a60dSAndroid Build Coastguard Worker printf(usage, argv[0], argv[0], argv[0]);
41*8617a60dSAndroid Build Coastguard Worker }
42*8617a60dSAndroid Build Coastguard Worker
print_digest(const uint8_t * buf,size_t len)43*8617a60dSAndroid Build Coastguard Worker static void print_digest(const uint8_t *buf, size_t len)
44*8617a60dSAndroid Build Coastguard Worker {
45*8617a60dSAndroid Build Coastguard Worker for (size_t i = 0; i < len; i++)
46*8617a60dSAndroid Build Coastguard Worker printf("%02x", buf[i]);
47*8617a60dSAndroid Build Coastguard Worker }
48*8617a60dSAndroid Build Coastguard Worker
49*8617a60dSAndroid Build Coastguard Worker enum {
50*8617a60dSAndroid Build Coastguard Worker OPT_HELP = 1000,
51*8617a60dSAndroid Build Coastguard Worker };
52*8617a60dSAndroid Build Coastguard Worker static const struct option long_opts[] = {
53*8617a60dSAndroid Build Coastguard Worker {"help", 0, 0, OPT_HELP},
54*8617a60dSAndroid Build Coastguard Worker {NULL, 0, 0, 0}
55*8617a60dSAndroid Build Coastguard Worker };
do_pcr(int argc,char * argv[])56*8617a60dSAndroid Build Coastguard Worker static int do_pcr(int argc, char *argv[])
57*8617a60dSAndroid Build Coastguard Worker {
58*8617a60dSAndroid Build Coastguard Worker uint8_t accum[VB2_MAX_DIGEST_SIZE * 2];
59*8617a60dSAndroid Build Coastguard Worker uint8_t pcr[VB2_MAX_DIGEST_SIZE] = {0};
60*8617a60dSAndroid Build Coastguard Worker int digest_alg = VB2_HASH_SHA1;
61*8617a60dSAndroid Build Coastguard Worker int opt_init = 0;
62*8617a60dSAndroid Build Coastguard Worker int errorcnt = 0;
63*8617a60dSAndroid Build Coastguard Worker int i;
64*8617a60dSAndroid Build Coastguard Worker
65*8617a60dSAndroid Build Coastguard Worker opterr = 0; /* quiet, you */
66*8617a60dSAndroid Build Coastguard Worker while ((i = getopt_long(argc, argv, ":i2", long_opts, NULL)) != -1) {
67*8617a60dSAndroid Build Coastguard Worker switch (i) {
68*8617a60dSAndroid Build Coastguard Worker case 'i':
69*8617a60dSAndroid Build Coastguard Worker opt_init = 1;
70*8617a60dSAndroid Build Coastguard Worker break;
71*8617a60dSAndroid Build Coastguard Worker case '2':
72*8617a60dSAndroid Build Coastguard Worker digest_alg = VB2_HASH_SHA256;
73*8617a60dSAndroid Build Coastguard Worker break;
74*8617a60dSAndroid Build Coastguard Worker case OPT_HELP:
75*8617a60dSAndroid Build Coastguard Worker print_help(argc, argv);
76*8617a60dSAndroid Build Coastguard Worker return !!errorcnt;
77*8617a60dSAndroid Build Coastguard Worker case '?':
78*8617a60dSAndroid Build Coastguard Worker if (optopt)
79*8617a60dSAndroid Build Coastguard Worker ERROR("Unrecognized option: -%c\n",
80*8617a60dSAndroid Build Coastguard Worker optopt);
81*8617a60dSAndroid Build Coastguard Worker else
82*8617a60dSAndroid Build Coastguard Worker ERROR("Unrecognized option\n");
83*8617a60dSAndroid Build Coastguard Worker errorcnt++;
84*8617a60dSAndroid Build Coastguard Worker break;
85*8617a60dSAndroid Build Coastguard Worker case ':':
86*8617a60dSAndroid Build Coastguard Worker ERROR("Missing argument to -%c\n", optopt);
87*8617a60dSAndroid Build Coastguard Worker errorcnt++;
88*8617a60dSAndroid Build Coastguard Worker break;
89*8617a60dSAndroid Build Coastguard Worker default:
90*8617a60dSAndroid Build Coastguard Worker FATAL("Unrecognized getopt output: %d\n", i);
91*8617a60dSAndroid Build Coastguard Worker }
92*8617a60dSAndroid Build Coastguard Worker }
93*8617a60dSAndroid Build Coastguard Worker
94*8617a60dSAndroid Build Coastguard Worker if (errorcnt) {
95*8617a60dSAndroid Build Coastguard Worker print_help(argc, argv);
96*8617a60dSAndroid Build Coastguard Worker return 1;
97*8617a60dSAndroid Build Coastguard Worker }
98*8617a60dSAndroid Build Coastguard Worker
99*8617a60dSAndroid Build Coastguard Worker if (argc - optind < 1 + opt_init) {
100*8617a60dSAndroid Build Coastguard Worker ERROR("You must extend at least one DIGEST\n");
101*8617a60dSAndroid Build Coastguard Worker print_help(argc, argv);
102*8617a60dSAndroid Build Coastguard Worker return 1;
103*8617a60dSAndroid Build Coastguard Worker }
104*8617a60dSAndroid Build Coastguard Worker
105*8617a60dSAndroid Build Coastguard Worker int digest_size = vb2_digest_size(digest_alg);
106*8617a60dSAndroid Build Coastguard Worker if (!digest_size) {
107*8617a60dSAndroid Build Coastguard Worker ERROR("Cannot determine digest size!\n");
108*8617a60dSAndroid Build Coastguard Worker return 1;
109*8617a60dSAndroid Build Coastguard Worker }
110*8617a60dSAndroid Build Coastguard Worker
111*8617a60dSAndroid Build Coastguard Worker if (opt_init) {
112*8617a60dSAndroid Build Coastguard Worker parse_digest_or_die(pcr, digest_size, argv[optind]);
113*8617a60dSAndroid Build Coastguard Worker optind++;
114*8617a60dSAndroid Build Coastguard Worker }
115*8617a60dSAndroid Build Coastguard Worker
116*8617a60dSAndroid Build Coastguard Worker printf("PCR: ");
117*8617a60dSAndroid Build Coastguard Worker print_digest(pcr, digest_size);
118*8617a60dSAndroid Build Coastguard Worker printf("\n");
119*8617a60dSAndroid Build Coastguard Worker
120*8617a60dSAndroid Build Coastguard Worker for (i = optind; i < argc; i++) {
121*8617a60dSAndroid Build Coastguard Worker memcpy(accum, pcr, sizeof(pcr));
122*8617a60dSAndroid Build Coastguard Worker parse_digest_or_die(accum + digest_size, digest_size, argv[i]);
123*8617a60dSAndroid Build Coastguard Worker
124*8617a60dSAndroid Build Coastguard Worker printf(" + ");
125*8617a60dSAndroid Build Coastguard Worker print_digest(accum + digest_size, digest_size);
126*8617a60dSAndroid Build Coastguard Worker printf("\n");
127*8617a60dSAndroid Build Coastguard Worker
128*8617a60dSAndroid Build Coastguard Worker struct vb2_hash hash;
129*8617a60dSAndroid Build Coastguard Worker if (VB2_SUCCESS != vb2_hash_calculate(false, accum,
130*8617a60dSAndroid Build Coastguard Worker digest_size * 2,
131*8617a60dSAndroid Build Coastguard Worker digest_alg, &hash)) {
132*8617a60dSAndroid Build Coastguard Worker ERROR("Cannot compute digest!\n");
133*8617a60dSAndroid Build Coastguard Worker return 1;
134*8617a60dSAndroid Build Coastguard Worker }
135*8617a60dSAndroid Build Coastguard Worker memcpy(pcr, hash.raw, digest_size);
136*8617a60dSAndroid Build Coastguard Worker
137*8617a60dSAndroid Build Coastguard Worker printf("PCR: ");
138*8617a60dSAndroid Build Coastguard Worker print_digest(pcr, digest_size);
139*8617a60dSAndroid Build Coastguard Worker printf("\n");
140*8617a60dSAndroid Build Coastguard Worker }
141*8617a60dSAndroid Build Coastguard Worker
142*8617a60dSAndroid Build Coastguard Worker return 0;
143*8617a60dSAndroid Build Coastguard Worker }
144*8617a60dSAndroid Build Coastguard Worker
145*8617a60dSAndroid Build Coastguard Worker DECLARE_FUTIL_COMMAND(pcr, do_pcr, VBOOT_VERSION_ALL,
146*8617a60dSAndroid Build Coastguard Worker "Simulate a TPM PCR extension operation");
147