Skip to content

Commit 31262d0

Browse files
committed
Merge pull request #4 from srajiv/nvdefine-pcrs
tpm_nvdefinespace: add support for PCR sealing
2 parents db30c63 + 3b8c048 commit 31262d0

File tree

1 file changed

+193
-4
lines changed

1 file changed

+193
-4
lines changed

‎src/tpm_mgmt/tpm_nvdefine.c

Lines changed: 193 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
* http://www.opensource.org/licenses/cpl1.0.php.
2020
*/
2121

22+
#include <stdio.h>
23+
#include <errno.h>
2224
#include <limits.h>
2325

2426
#include "tpm_tspi.h"
@@ -36,6 +38,11 @@ static const char *datapass;
3638
static BOOL dataWellKnown;
3739
static BOOL askDataPass;
3840
static int end;
41+
static UINT32 selectedPcrsRead[24];
42+
static UINT32 selectedPcrsWrite[24];
43+
static UINT32 selectedPcrsReadLen = 0;
44+
static UINT32 selectedPcrsWriteLen = 0;
45+
static const char *filename;
3946

4047
TSS_HCONTEXT hContext = 0;
4148

@@ -101,6 +108,24 @@ static int parse(const int aOpt, const char *aArg)
101108
useUnicode = TRUE;
102109
break;
103110

111+
case 'r':
112+
if (aArg && atoi(aArg) >= 0 && atoi(aArg) < 24) {
113+
selectedPcrsRead[selectedPcrsReadLen++] = atoi(aArg);
114+
} else
115+
return -1;
116+
break;
117+
118+
case 'w':
119+
if (aArg && atoi(aArg) >= 0 && atoi(aArg) < 24) {
120+
selectedPcrsWrite[selectedPcrsWriteLen++] = atoi(aArg);
121+
} else
122+
return -1;
123+
break;
124+
125+
case 'f':
126+
filename = aArg;
127+
break;
128+
104129
default:
105130
return -1;
106131
}
@@ -123,12 +148,92 @@ static void help(const char* aCmd)
123148
logNVIndexCmdOption();
124149
logCmdOption("-s, --size",
125150
_("Size of the NVRAM area"));
151+
logCmdOption("-r, --rpcrs",
152+
_("PCRs to seal the NVRAM area to for reading (use multiple times)"));
153+
logCmdOption("-w, --wpcrs",
154+
_("PCRs to seal the NVRAM area to for writing (use multiple times)"));
155+
logCmdOption("-f, --filename",
156+
_("File containing PCR info for the NVRAM area"));
157+
126158
logCmdOption("-p, --permissions",
127159
_("Permissions of the NVRAM area"));
128-
129160
displayStringsAndValues(permvalues, " ");
130161
}
131162

163+
void logInvalidPcrInfoFile()
164+
{
165+
logError(_("Invalid PCR info file. Format is:\n"
166+
"[r/w] [PCR IDX] [SHA-1 ascii]\n\nExample:\n"
167+
"r 9 00112233445566778899AABBCCDDEEFF00112233"));
168+
}
169+
170+
int
171+
parseNVPermsFile(FILE *f, TSS_HCONTEXT *hContext, TSS_HNVSTORE *nvObject,
172+
TSS_HPCRS *hPcrsRead, TSS_HPCRS *hPcrsWrite)
173+
{
174+
UINT32 pcrSize;
175+
char rw;
176+
unsigned int pcr, n;
177+
char hash_ascii[65], hash_bin[32], save;
178+
int rc = -1;
179+
180+
while (!feof(f)) {
181+
errno = 0;
182+
n = fscanf(f, "%c %u %s\n", &rw, &pcr, hash_ascii);
183+
if (n != 3) {
184+
logInvalidPcrInfoFile();
185+
goto out;
186+
} else if (errno != 0) {
187+
perror("fscanf");
188+
goto out;
189+
}
190+
191+
if (rw != 'r' && rw != 'w') {
192+
logInvalidPcrInfoFile();
193+
goto out;
194+
}
195+
196+
if (pcr > 15) {
197+
logError(_("Cannot seal NVRAM area to PCR > 15\n"));
198+
goto out;
199+
}
200+
201+
for (n = 0; n < strlen(hash_ascii); n += 2) {
202+
save = hash_ascii[n + 2];
203+
hash_ascii[n + 2] = '\0';
204+
hash_bin[n/2] = strtoul(&hash_ascii[n], NULL, 16);
205+
hash_ascii[n + 2] = save;
206+
}
207+
pcrSize = n/2;
208+
209+
if (rw == 'r') {
210+
if (*hPcrsRead == NULL_HPCRS)
211+
if (contextCreateObject(*hContext, TSS_OBJECT_TYPE_PCRS,
212+
TSS_PCRS_STRUCT_INFO_SHORT,
213+
hPcrsRead) != TSS_SUCCESS)
214+
goto out;
215+
216+
if (pcrcompositeSetPcrValue(*hPcrsRead, pcr, pcrSize, (BYTE *)hash_bin)
217+
!= TSS_SUCCESS)
218+
goto out;
219+
} else {
220+
if (*hPcrsWrite == NULL_HPCRS)
221+
if (contextCreateObject(*hContext, TSS_OBJECT_TYPE_PCRS,
222+
TSS_PCRS_STRUCT_INFO_SHORT,
223+
hPcrsWrite) != TSS_SUCCESS)
224+
goto out;
225+
226+
if (pcrcompositeSetPcrValue(*hPcrsWrite, pcr, pcrSize, (BYTE *)hash_bin)
227+
!= TSS_SUCCESS)
228+
goto out;
229+
}
230+
}
231+
232+
rc = 0;
233+
out:
234+
return rc;
235+
}
236+
132237
int main(int argc, char **argv)
133238
{
134239
TSS_HTPM hTpm;
@@ -139,22 +244,29 @@ int main(int argc, char **argv)
139244
BYTE well_known_secret[] = TSS_WELL_KNOWN_SECRET;
140245
int opswd_len = -1;
141246
int dpswd_len = -1;
247+
TSS_HPCRS hPcrsRead = 0, hPcrsWrite = 0;
142248
struct option hOpts[] = {
143249
{"index" , required_argument, NULL, 'i'},
144250
{"size" , required_argument, NULL, 's'},
145251
{"permissions" , required_argument, NULL, 'p'},
252+
{"rpcrs" , required_argument, NULL, 'r'},
253+
{"wpcrs" , required_argument, NULL, 'w'},
254+
{"filename" , required_argument, NULL, 'f'},
146255
{"pwdo" , optional_argument, NULL, 'o'},
147256
{"pwda" , optional_argument, NULL, 'a'},
148257
{"use-unicode" , no_argument, NULL, 'u'},
149258
{"data-well-known" , no_argument, NULL, 'z'},
150259
{"owner-well-known", no_argument, NULL, 'y'},
151260
{NULL , no_argument, NULL, 0},
152261
};
262+
TSS_FLAG initFlag = TSS_PCRS_STRUCT_INFO_SHORT;
263+
UINT32 localityValue = TPM_LOC_ZERO | TPM_LOC_ONE | TPM_LOC_TWO |
264+
TPM_LOC_THREE | TPM_LOC_FOUR;
153265

154266
initIntlSys();
155267

156268
if (genericOptHandler
157-
(argc, argv, "i:s:p:o:a:yzu", hOpts,
269+
(argc, argv, "i:s:p:o:a:r:w:f:yzu", hOpts,
158270
sizeof(hOpts) / sizeof(struct option), parse, help) != 0)
159271
goto out;
160272

@@ -269,8 +381,85 @@ int main(int argc, char **argv)
269381
nvsize) != TSS_SUCCESS)
270382
goto out_close_obj;
271383

272-
if (NVDefineSpace(nvObject, (TSS_HPCRS)0, (TSS_HPCRS)0) !=
273-
TSS_SUCCESS)
384+
if (selectedPcrsReadLen) {
385+
UINT32 pcrSize;
386+
BYTE *pcrValue;
387+
UINT32 i;
388+
389+
for (i = 0; i < selectedPcrsReadLen; i++) {
390+
if (selectedPcrsRead[i] > 15) {
391+
logError(_("Cannot seal NVRAM area to PCR > 15\n"));
392+
goto out_close;
393+
}
394+
}
395+
396+
if (contextCreateObject(hContext, TSS_OBJECT_TYPE_PCRS, initFlag,
397+
&hPcrsRead) != TSS_SUCCESS)
398+
goto out_close;
399+
400+
for (i = 0; i < selectedPcrsReadLen; i++) {
401+
if (tpmPcrRead(hTpm, selectedPcrsRead[i], &pcrSize, &pcrValue) !=
402+
TSS_SUCCESS)
403+
goto out_close;
404+
405+
if (pcrcompositeSetPcrValue(hPcrsRead, selectedPcrsRead[i],
406+
pcrSize, pcrValue)
407+
!= TSS_SUCCESS)
408+
goto out_close;
409+
}
410+
}
411+
412+
if (selectedPcrsWriteLen) {
413+
UINT32 pcrSize;
414+
BYTE *pcrValue;
415+
UINT32 i;
416+
417+
for (i = 0; i < selectedPcrsWriteLen; i++) {
418+
if (selectedPcrsWrite[i] > 15) {
419+
logError(_("Cannot seal NVRAM area to PCR > 15\n"));
420+
goto out_close;
421+
}
422+
}
423+
424+
if (contextCreateObject(hContext, TSS_OBJECT_TYPE_PCRS, initFlag,
425+
&hPcrsWrite) != TSS_SUCCESS)
426+
goto out_close;
427+
428+
for (i = 0; i < selectedPcrsWriteLen; i++) {
429+
if (tpmPcrRead(hTpm, selectedPcrsWrite[i], &pcrSize, &pcrValue) !=
430+
TSS_SUCCESS)
431+
goto out_close;
432+
433+
if (pcrcompositeSetPcrValue(hPcrsWrite, selectedPcrsWrite[i],
434+
pcrSize, pcrValue)
435+
!= TSS_SUCCESS)
436+
goto out_close;
437+
}
438+
}
439+
440+
if (filename) {
441+
FILE *f;
442+
443+
f = fopen(filename, "r");
444+
if (!f) {
445+
logError(_("Could not access file '%s'\n"), filename);
446+
goto out_close_obj;
447+
}
448+
449+
if (parseNVPermsFile(f, &hContext, &nvObject, &hPcrsRead, &hPcrsWrite)
450+
!= TSS_SUCCESS)
451+
goto out_close_obj;
452+
}
453+
454+
if (hPcrsRead)
455+
if (pcrcompositeSetPcrLocality(hPcrsRead, localityValue) != TSS_SUCCESS)
456+
goto out_close;
457+
458+
if (hPcrsWrite)
459+
if (pcrcompositeSetPcrLocality(hPcrsWrite, localityValue) != TSS_SUCCESS)
460+
goto out_close;
461+
462+
if (NVDefineSpace(nvObject, hPcrsRead, hPcrsWrite) != TSS_SUCCESS)
274463
goto out_close;
275464

276465
logMsg(_("Successfully created NVRAM area at index 0x%x (%u).\n"),

0 commit comments

Comments
 (0)