2 * This file is part of the OpenPTS project.
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.
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)
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.
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.
27 * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
29 * cleanup 2011-12-31 SM
31 * Emulate TPM to validate IML and PCR
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>
45 #include <openssl/sha.h>
55 int resetTpm(OPENPTS_TPM_CONTEXT *tctx, int drtm) {
58 DEBUG_TPM("tpm.c - RESET (POR)\n");
62 LOG(LOG_ERR, "ERROR TPM_CONTEXT is NULL");
66 for (i = 0; i < MAX_PCRNUM; i++) {
67 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
72 for (i = 17; i < 23; i++) {
73 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
74 if (drtm == 0) tctx->pcr[i][j] = 0xff;
75 else tctx->pcr[i][j] = 0x00;
79 DEBUG_TPM("tpm.c - RESET (POR)\n");
87 int resetTpmPcr(OPENPTS_TPM_CONTEXT *tctx, int index) {
90 DEBUG_TPM("resetTpmPcr - RESET just one PCR %d\n", index);
94 LOG(LOG_ERR, "ERROR TPM_CONTEXT is NULL");
98 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
99 tctx->pcr[index][j] = 0;
105 * check digest is Zero or not
108 * @return 1 if digest is Zero
110 int isZero(BYTE * digest) {
114 if (digest == NULL) {
115 LOG(LOG_ERR, "null input");
120 for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
121 if (digest[i] != 0 ) return 0;
131 void setFF(BYTE * digest) {
135 if (digest == NULL) {
136 LOG(LOG_ERR, "null input");
141 for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
147 * extend event to TPM
152 int extendTpm(OPENPTS_TPM_CONTEXT *tctx, TSS_PCR_EVENT *event) {
159 LOG(LOG_ERR, "TPM_CONTEXT is NULL\n");
163 LOG(LOG_ERR, "TSS_PCR_EVENT is NULL\n");
167 digest = event->rgbPcrValue;
168 if (digest == NULL) {
169 LOG(LOG_ERR, "event->rgbPcrValue is NULL\n");
173 index = event->ulPcrIndex;
174 if (index >= MAX_PCRNUM) {
175 LOG(LOG_ERR, "BAD PCR INDEX %d >= %d\n", index, MAX_PCRNUM);
176 return PTS_INTERNAL_ERROR;
180 LOG(LOG_ERR, "ERROR BAD PCR INDEX %d < 0\n", index);
181 return PTS_INTERNAL_ERROR;
184 if (index == 10) { // Linux-IML, 0000... -> FFFF...
185 if (isZero(digest) == 1) {
191 SHA1_Update(&ctx, &(tctx->pcr[index][0]), SHA1_DIGEST_SIZE);
192 SHA1_Update(&ctx, digest, SHA1_DIGEST_SIZE);
193 SHA1_Final(&tctx->pcr[index][0], &ctx);
195 if (isDebugFlagSet(DEBUG_TPM_FLAG)) {
197 DEBUG_TPM("\ttpm.c - extend pcr=%d digest=", index);
198 for (i = 0; i < SHA1_DIGEST_SIZE; i++) OUTPUT("%02x", digest[i]);
200 for (i = 0; i < SHA1_DIGEST_SIZE; i++) OUTPUT("%02x", tctx->pcr[index][i]);
208 * extend event to TPM (2)
214 int extendTpm2(OPENPTS_TPM_CONTEXT *tctx, int index, BYTE * digest) {
219 LOG(LOG_ERR, "TPM_CONTEXT is NULL\n");
222 if (digest == NULL) {
223 LOG(LOG_ERR, "null input\n");
227 if (index >= MAX_PCRNUM) {
228 LOG(LOG_ERR, "BAD pcr index, %d >= %d", index, MAX_PCRNUM);
229 return PTS_INTERNAL_ERROR;
233 if (index == 10) { // Linux-IML, 0000... -> FFFF...
234 if (isZero(digest) == 1) {
240 SHA1_Update(&ctx, &(tctx->pcr[index][0]), SHA1_DIGEST_SIZE);
241 SHA1_Update(&ctx, digest, SHA1_DIGEST_SIZE);
242 SHA1_Final(&tctx->pcr[index][0], &ctx);
244 if (isDebugFlagSet(DEBUG_TPM_FLAG)) {
246 DEBUG_TPM("tpm.c - extend pcr=%d digest=", index);
247 for (i = 0; i < SHA1_DIGEST_SIZE; i++) OUTPUT("%02x", digest[i]);
255 * check current PCR value with digest
261 int checkTpmPcr2(OPENPTS_TPM_CONTEXT *tctx, int index, BYTE * digest) {
266 LOG(LOG_ERR, "TPM_CONTEXT is NULL\n");
270 for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
271 if (tctx->pcr[index][i] != digest[i]) return PTS_INTERNAL_ERROR; // TODO
277 * print TPM PCRs to stdout
279 int printTpm(OPENPTS_TPM_CONTEXT *tctx) {
282 DEBUG_FSM("tpm.c - pprint pcrs\n");
286 LOG(LOG_ERR, "TPM_CONTEXT is NULL\n");
290 for (i = 0; i < MAX_PCRNUM; i++) {
291 OUTPUT("PCR[%2d] = ", i);
292 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
293 OUTPUT("%02x", tctx->pcr[i][j]);
304 int getTpmPcrValue(OPENPTS_TPM_CONTEXT *tpm, int index, BYTE *digest) {
307 DEBUG_CAL("getTpmPcrValue - pcr[%d]\n", index);
311 LOG(LOG_ERR, "null input");
314 if (digest == NULL) {
315 LOG(LOG_ERR, "null input");
318 if (index >= MAX_PCRNUM) {
319 LOG(LOG_ERR, "BAD PCR INDEX %d >= %d\n", index, MAX_PCRNUM);
320 return PTS_INTERNAL_ERROR;
323 LOG(LOG_ERR, "ERROR BAD PCR INDEX %d < 0\n", index);
324 return PTS_INTERNAL_ERROR;
328 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
329 digest[j]=tpm->pcr[index][j];
332 DEBUG_CAL("getTpmPcrValue - done\n");