OSDN Git Service

cleanup
[openpts/openpts.git] / src / tpm.c
1 /*
2  * This file is part of the OpenPTS project.
3  *
4  * The Initial Developer of the Original Code is International
5  * Business Machines Corporation. Portions created by IBM
6  * Corporation are Copyright (C) 2010 International Business
7  * Machines Corporation. All Rights Reserved.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the Common Public License as published by
11  * IBM Corporation; either version 1 of the License, or (at your option)
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * Common Public License for more details.
18  *
19  * You should have received a copy of the Common Public License
20  * along with this program; if not, a copy can be viewed at
21  * http://www.opensource.org/licenses/cpl1.0.php.
22  */
23
24 /**
25  * \file src/tpm.c
26  * \brief emulate TPM
27  * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
28  * @date 2010-04-01
29  * cleanup 2012-01-05 SM
30  *
31  *  Emulate TPM to validate IML and PCR
32  */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #include <tss/platform.h>
39 #include <tss/tss_defines.h>
40 #include <tss/tss_typedef.h>
41 #include <tss/tss_structs.h>
42 #include <tss/tss_error.h>
43 #include <tss/tspi.h>
44
45 #include <openssl/sha.h>
46
47 #include <openpts.h>
48
49 /* TPM functions -------------------------------------------------------------*/
50
51 /**
52  * reset TPM
53  */
54 int resetTpm(OPENPTS_TPM_CONTEXT *tctx, int drtm) {
55     int i, j;
56
57     DEBUG_TPM("tpm.c - RESET (POR)\n");
58
59     /* check */
60     if (tctx == NULL) {
61         LOG(LOG_ERR, "ERROR TPM_CONTEXT is NULL");
62         return -1;
63     }
64
65     for (i = 0; i < MAX_PCRNUM; i++) {
66         for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
67             tctx->pcr[i][j] = 0;
68         }
69     }
70     // no DRTM
71     for (i = 17; i < 23; i++) {
72         for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
73             if (drtm == 0) tctx->pcr[i][j] = 0xff;
74             else           tctx->pcr[i][j] = 0x00;
75         }
76     }
77
78     DEBUG_TPM("tpm.c - RESET (POR)\n");
79
80     return 0;
81 }
82
83 /**
84  * reset TPM PCR
85  */
86 int resetTpmPcr(OPENPTS_TPM_CONTEXT *tctx, int index) {
87     int j;
88
89     DEBUG_TPM("resetTpmPcr - RESET just one PCR %d\n", index);
90
91     /* check */
92     if (tctx == NULL) {
93         LOG(LOG_ERR, "ERROR TPM_CONTEXT is NULL");
94         return -1;
95     }
96
97     for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
98         tctx->pcr[index][j] = 0;
99     }
100     return 0;
101 }
102
103 /**
104  * check digest is Zero or not
105  *
106  * @param digest
107  * @return 1 if digest is Zero
108  */
109 int isZero(BYTE * digest) {
110     int i;
111
112     /* check */
113     if (digest == NULL) {
114         LOG(LOG_ERR, "null input");
115         return -1;
116     }
117
118     /* is zero? */
119     for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
120         if (digest[i] != 0 ) return 0;
121     }
122     return 1;
123 }
124
125 /**
126  * set digest to FF
127  *
128  * @param digest
129  */
130 void setFF(BYTE * digest) {
131     int i;
132
133     /* check */
134     if (digest == NULL) {
135         LOG(LOG_ERR, "null input");
136         return;
137     }
138
139     /* set FF... */
140     for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
141         digest[i] = 0xff;
142     }
143 }
144
145 /**
146  * extend event to TPM
147  *
148  * @param tctx
149  * @param event
150  */
151 int extendTpm(OPENPTS_TPM_CONTEXT *tctx, TSS_PCR_EVENT *event) {
152     SHA_CTX ctx;
153     int index;
154     BYTE * digest;
155
156     /* check */
157     if (tctx == NULL) {
158         LOG(LOG_ERR, "TPM_CONTEXT is NULL\n");
159         return PTS_FATAL;
160     }
161     if (event == NULL) {
162         LOG(LOG_ERR, "TSS_PCR_EVENT is NULL\n");
163         return PTS_FATAL;
164     }
165
166     digest = event->rgbPcrValue;
167     if (digest == NULL) {
168         LOG(LOG_ERR, "event->rgbPcrValue is NULL\n");
169         return PTS_FATAL;
170     }
171
172     index = event->ulPcrIndex;
173     if (index >= MAX_PCRNUM) {
174         LOG(LOG_ERR, "BAD PCR INDEX %d >= %d\n", index, MAX_PCRNUM);
175         return PTS_INTERNAL_ERROR;
176     }
177
178     if (index < 0) {
179         LOG(LOG_ERR, "ERROR BAD PCR INDEX %d < 0\n", index);
180         return PTS_INTERNAL_ERROR;
181     }
182
183     if (index == 10) {  // Linux-IML, 0000... -> FFFF...
184         if (isZero(digest) == 1) {
185             setFF(digest);
186         }
187     }
188
189     SHA1_Init(&ctx);
190     SHA1_Update(&ctx, &(tctx->pcr[index][0]), SHA1_DIGEST_SIZE);
191     SHA1_Update(&ctx, digest, SHA1_DIGEST_SIZE);
192     SHA1_Final(&tctx->pcr[index][0], &ctx);
193
194     if (isDebugFlagSet(DEBUG_TPM_FLAG)) {
195         int i;
196         DEBUG_TPM("\ttpm.c - extend pcr=%d digest=", index);
197         for (i = 0; i < SHA1_DIGEST_SIZE; i++) OUTPUT("%02x", digest[i]);
198         OUTPUT("  -> ");
199         for (i = 0; i < SHA1_DIGEST_SIZE; i++) OUTPUT("%02x", tctx->pcr[index][i]);
200         OUTPUT("\n");
201     }
202
203     return PTS_SUCCESS;
204 }
205
206 /**
207  * extend event to TPM (2)
208  *
209  * @param tctx
210  * @param index
211  * @param digest
212  */
213 int extendTpm2(OPENPTS_TPM_CONTEXT *tctx, int index, BYTE * digest) {
214     SHA_CTX ctx;
215
216     /* check */
217     if (tctx == NULL) {
218         LOG(LOG_ERR, "TPM_CONTEXT is NULL\n");
219         return PTS_FATAL;
220     }
221     if (digest == NULL) {
222         LOG(LOG_ERR, "null input\n");
223         return PTS_FATAL;
224     }
225
226     if (index >= MAX_PCRNUM) {
227         LOG(LOG_ERR, "BAD pcr index, %d >= %d", index, MAX_PCRNUM);
228         return PTS_INTERNAL_ERROR;
229     }
230
231     // TODO(munetoh)
232     if (index == 10) {  // Linux-IML, 0000... -> FFFF...
233         if (isZero(digest) == 1) {
234             setFF(digest);
235         }
236     }
237
238     SHA1_Init(&ctx);
239     SHA1_Update(&ctx, &(tctx->pcr[index][0]), SHA1_DIGEST_SIZE);
240     SHA1_Update(&ctx, digest, SHA1_DIGEST_SIZE);
241     SHA1_Final(&tctx->pcr[index][0], &ctx);
242
243     if (isDebugFlagSet(DEBUG_TPM_FLAG)) {
244         int i;
245         DEBUG_TPM("tpm.c - extend pcr=%d digest=", index);
246         for (i = 0; i < SHA1_DIGEST_SIZE; i++) OUTPUT("%02x", digest[i]);
247         OUTPUT("\n");
248     }
249
250     return PTS_SUCCESS;
251 }
252
253 /**
254  * check current PCR value with digest
255  *
256  * @param tctx
257  * @param index
258  * @param digest
259  */
260 int checkTpmPcr2(OPENPTS_TPM_CONTEXT *tctx, int index, BYTE * digest) {
261     int i;
262
263     /* check */
264     if (tctx == NULL) {
265         LOG(LOG_ERR, "TPM_CONTEXT is NULL\n");
266         return PTS_FATAL;
267     }
268
269     for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
270         if (tctx->pcr[index][i] != digest[i]) return PTS_INTERNAL_ERROR;  // TODO
271     }
272     return PTS_SUCCESS;
273 }
274
275 /**
276  * print TPM PCRs to stdout
277  */
278 int printTpm(OPENPTS_TPM_CONTEXT *tctx) {
279     int i, j;
280
281     DEBUG_FSM("tpm.c - pprint pcrs\n");
282
283     /* check */
284     if (tctx == NULL) {
285         LOG(LOG_ERR, "TPM_CONTEXT is NULL\n");
286         return PTS_FATAL;
287     }
288
289     for (i = 0; i < MAX_PCRNUM; i++) {
290         OUTPUT("PCR[%2d] = ", i);
291         for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
292             OUTPUT("%02x", tctx->pcr[i][j]);
293         }
294         OUTPUT("\n");
295     }
296
297     return PTS_SUCCESS;
298 }
299
300 /**
301  * get TPM PCR value
302  */
303 int getTpmPcrValue(OPENPTS_TPM_CONTEXT *tpm, int index, BYTE *digest) {
304     int j;
305
306     DEBUG_CAL("getTpmPcrValue - pcr[%d]\n", index);
307
308     /* check */
309     if (tpm == NULL) {
310         LOG(LOG_ERR, "null input");
311         return PTS_FATAL;
312     }
313     if (digest == NULL) {
314         LOG(LOG_ERR, "null input");
315         return PTS_FATAL;
316     }
317     if (index >= MAX_PCRNUM) {
318         LOG(LOG_ERR, "BAD PCR INDEX %d >= %d\n", index, MAX_PCRNUM);
319         return PTS_INTERNAL_ERROR;
320     }
321     if (index < 0) {
322         LOG(LOG_ERR, "ERROR BAD PCR INDEX %d < 0\n", index);
323         return PTS_INTERNAL_ERROR;
324     }
325
326     /* copy */
327     for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
328         digest[j]=tpm->pcr[index][j];
329     }
330
331     DEBUG_CAL("getTpmPcrValue - done\n");
332
333     return PTS_SUCCESS;
334 }