Added TPM command to read space permissions, and a correctness test.
Review URL: http://codereview.chromium.org/2719006
diff --git a/src/testsuite/Makefile b/src/testsuite/Makefile
index e63b61b..da0c258 100644
--- a/src/testsuite/Makefile
+++ b/src/testsuite/Makefile
@@ -34,6 +34,7 @@
tpmtest_lock \
tpmtest_readonly \
tpmtest_redefine \
+ tpmtest_spaceperm \
tpmtest_writelimit \
all: $(TESTS)
diff --git a/src/testsuite/spaceperm.c b/src/testsuite/spaceperm.c
new file mode 100644
index 0000000..38a68cd
--- /dev/null
+++ b/src/testsuite/spaceperm.c
@@ -0,0 +1,47 @@
+/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Test of space permissions retrieval. The spaces 0xcafe and 0xcaff must have
+ * already been defined (by running, for instance, the "redefine" test).
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <tss/tcs.h>
+
+#include "tlcl.h"
+
+#define INDEX0 0xcafe
+#define INDEX1 0xcaff
+
+int main(int argc, char** argv) {
+ uint32_t perm;
+ uint32_t perm_pp_gl = TPM_NV_PER_PPWRITE | TPM_NV_PER_GLOBALLOCK;
+ uint32_t perm_pp = TPM_NV_PER_PPWRITE;
+ uint32_t result;
+
+ TlclLibInit();
+
+#if !USE_TPM_EMULATOR
+ TlclStartup();
+ TlclContinueSelfTest();
+#endif
+
+ TlclAssertPhysicalPresence();
+
+ result = TlclGetPermissions(INDEX0, &perm);
+ assert(result == TPM_SUCCESS);
+ printf("permissions for INDEX0 = 0x%x\n", perm);
+ assert((perm & perm_pp_gl) == perm_pp_gl);
+
+ result = TlclGetPermissions(INDEX1, &perm);
+ assert(result == TPM_SUCCESS);
+ printf("permissions for INDEX1 = 0x%x\n", perm);
+ assert((perm & perm_pp) == perm_pp);
+
+ printf("Test completed successfully\n");
+ exit(0);
+}
diff --git a/src/tlcl/generator.c b/src/tlcl/generator.c
index 4a9e89d..f5ad7ad 100644
--- a/src/tlcl/generator.c
+++ b/src/tlcl/generator.c
@@ -252,14 +252,14 @@
return cmd;
}
-Command* BuildGetCapabilityCommand(void) {
+Command* BuildGetFlagsCommand(void) {
int size = (kTpmRequestHeaderLength +
sizeof(TPM_CAPABILITY_AREA) + /* capArea */
sizeof(uint32_t) + /* subCapSize */
- sizeof(uint32_t)); /* subCap */
+ sizeof(uint32_t)); /* subCap */
Command* cmd = newCommand(TPM_ORD_GetCapability, size);
- cmd->name = "tpm_getcapability_cmd";
+ cmd->name = "tpm_getflags_cmd";
AddInitializedField(cmd, kTpmRequestHeaderLength,
sizeof(TPM_CAPABILITY_AREA), TPM_CAP_FLAG);
AddInitializedField(cmd, kTpmRequestHeaderLength +
@@ -271,6 +271,24 @@
return cmd;
}
+Command* BuildGetPermissionsCommand(void) {
+ int size = (kTpmRequestHeaderLength +
+ sizeof(TPM_CAPABILITY_AREA) + /* capArea */
+ sizeof(uint32_t) + /* subCapSize */
+ sizeof(uint32_t)); /* subCap */
+
+ Command* cmd = newCommand(TPM_ORD_GetCapability, size);
+ cmd->name = "tpm_getpermissions_cmd";
+ AddInitializedField(cmd, kTpmRequestHeaderLength,
+ sizeof(TPM_CAPABILITY_AREA), TPM_CAP_NV_INDEX);
+ AddInitializedField(cmd, kTpmRequestHeaderLength +
+ sizeof(TPM_CAPABILITY_AREA),
+ sizeof(uint32_t), sizeof(uint32_t));
+ AddVisibleField(cmd, "index", kTpmRequestHeaderLength +
+ sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t));
+ return cmd;
+}
+
/* Output the fields of a structure.
*/
void OutputFields(Field* fld) {
@@ -379,7 +397,8 @@
BuildForceClearCommand,
BuildPhysicalEnableCommand,
BuildPhysicalSetDeactivatedCommand,
- BuildGetCapabilityCommand,
+ BuildGetFlagsCommand,
+ BuildGetPermissionsCommand,
BuildExtendCommand,
};
@@ -412,6 +431,10 @@
printf("/* This file is automatically generated */\n\n");
OutputCommands(commands);
printf("const int kWriteInfoLength = %d;\n", (int) sizeof(TPM_WRITE_INFO));
+ printf("const int kNvDataPublicPermissionsOffset = %d;\n",
+ (int) (offsetof(TPM_NV_DATA_PUBLIC, permission) +
+ 2 * PCR_SELECTION_FIX +
+ offsetof(TPM_NV_ATTRIBUTES, attributes)));
FreeCommands(commands);
return 0;
diff --git a/src/tlcl/tlcl.c b/src/tlcl/tlcl.c
index 524cf2e..4ef5e40 100644
--- a/src/tlcl/tlcl.c
+++ b/src/tlcl/tlcl.c
@@ -350,7 +350,7 @@
uint32_t result;
uint32_t size;
- SendReceive(tpm_getcapability_cmd.buffer, response, sizeof(response));
+ SendReceive(tpm_getflags_cmd.buffer, response, sizeof(response));
result = TpmReturnCode(response);
if (result != TPM_SUCCESS) {
return result;
@@ -377,3 +377,20 @@
memcpy(out_digest, response + kTpmResponseHeaderLength, kPcrDigestLength);
return TpmReturnCode(response);
}
+
+uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions) {
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ uint8_t* nvdata;
+ uint32_t result;
+ uint32_t size;
+
+ ToTpmUint32(tpm_getpermissions_cmd.index, index);
+ SendReceive(tpm_getpermissions_cmd.buffer, response, sizeof(response));
+ result = TpmReturnCode(response);
+ if (result != TPM_SUCCESS) {
+ return result;
+ }
+ nvdata = response + kTpmResponseHeaderLength + sizeof(size);
+ FromTpmUint32(nvdata + kNvDataPublicPermissionsOffset, permissions);
+ return result;
+}
diff --git a/src/tlcl/tlcl.h b/src/tlcl/tlcl.h
index 6bbec5c..e170cb8 100644
--- a/src/tlcl/tlcl.h
+++ b/src/tlcl/tlcl.h
@@ -149,4 +149,8 @@
*/
uint32_t TlclExtend(int pcr_num, uint8_t* in_digest, uint8_t* out_digest);
+/* Gets the permission bits for the NVRAM space with |index|.
+ */
+uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions);
+
#endif /* TPM_LITE_TLCL_H_ */