Stefan Berger [Sat, 17 Feb 2018 02:19:11 +0000 (21:19 -0500)]
tpm2: extract header init and check from SWAP functions
Extract the initialization of the header fom the SWAP functions
and initialize the header by the appropriat callers of the SWAP
functions.
Version and magic can be 0 when first read after NVRAM was
initialized. So we initialize it then.
Add skeleton code where the upgrade of the data structure would
have to happen later on.
Refuse to accept newer versions of structures than what is supported
at the moment. In particular, return error codes in case the blobs
that were read are not supported.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Fri, 9 Feb 2018 18:11:29 +0000 (13:11 -0500)]
tpm2: Enforce version of volatile state blob
Enforce the version of the volatile state blob. Do not accept a more
recent version than what we support at this point, so downgrading of
state is prevented this way.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Tue, 14 Nov 2017 00:28:12 +0000 (19:28 -0500)]
tpm2: NVRAM file does exist if we get TPM_DECRYPT_ERROR
In case the NVRAM file cannot be decrypted we get a TPM_DECRYPT_ERROR
error which also indicates that the file exists. So do not return FALSE
in this case, which would delete the existing file and start over with
a blank file.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Sat, 11 Nov 2017 04:02:28 +0000 (23:02 -0500)]
tpm2: Handle failures better
The current TpmFail() implementation invokes longjmp() at the end
and crashes with a segmentation fault if setjmp() wasn't called before.
To avoid this we implement TpmSetFailureMode() that logs the failure and
sets the TPM into failure mode. Since NVRAM may set failure mode before
the CryptInit() is called, we need to make sure we don't reset the failure
mode variable in case CryptInit() succeeds. In this case we now call the
FAIL_NOCMD() macro.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Wed, 1 Nov 2017 00:29:18 +0000 (20:29 -0400)]
tpm2: Create real random numbers to get different keys
Do not use rand() for creating random numbers since this only
creates pseudo random numbers and the keys always end up being
the same since it wasn't seeded, either.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Thu, 12 Oct 2017 01:14:16 +0000 (21:14 -0400)]
tpm2: Make compileable on OpenBSD
Make TPM 2 code compileable on OpenBSD where we have an older version
of gcc with missing builtin swap functions and where endianes #defines
area also different.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Mon, 25 Sep 2017 21:44:36 +0000 (17:44 -0400)]
Port TPM 2 to OpenSSL 1.1
Port the TPM 2 code to OpenSSL 1.1 by accessing the OpenSSL BIGNUM
only via its public functions. To get there it is necessary to
implement the Bn2bin() function that converts the TPM internal
representation of a bigNum to an array of unsigned chars that can
then be passed to the OpenSSL BN_bin2bn() function.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Thu, 5 Oct 2017 13:33:38 +0000 (09:33 -0400)]
tpm2: Add padding to structs for 32bit arch alignments
Some data structures need padding bytes to align the data
structures on 32bit machines to resemble the alignment on
64bit machines. Without it we wouldn't be able to resume
the state on a 32bit machine written by a 64bit machine.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Mon, 24 Jul 2017 22:36:07 +0000 (18:36 -0400)]
tpm2: fix marshalling/unmarshalling of BOOL for big endian
BOOL is an int and therefore we cannot just write out the
single byte at the address of the BOOL. On big endian systems
the BOOL value is at offset 3. So we implement functions for
marshalling and unmarshalling of a BOOL as a single byte and
do the conversion with the 'int' there.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Thu, 6 Apr 2017 15:19:01 +0000 (11:19 -0400)]
tpm2: Prepend header to NVRAM written structs and roundup their sizes
Round up the sizes of the structures written into NVRAM so we
have some space in front of them.
Prepend a heaer in front of the structure written into NVRAM. Initialize
them with a version number and a magic. The version number should
theoretically allow us to read TPM 2 state of different revisions.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Wed, 21 Dec 2016 21:26:19 +0000 (16:26 -0500)]
Integrate the TPM 2 into the library; do not compile with TPM 2 yet
Introduce --with-tpm2 for ./configure to enable building with
TPM 2 functionality. Delay the building of TPM 2 code until more
patches are applied and the vTPM state that's created has a chance
of being backwards compatible.
Extend the libtpms API to allow user to choose version of TPM.
Missing functionality at this point:
- TPM 2 needs to be extended to serialize and deserialize its volatile state
- Handling of the establishment bit
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
tpm12/tpm_init.c:666:9: error: variable 'tag' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized]
if (rc == 0) {
^~~~~~~
tpm12/tpm_init.c:746:9: note: uninitialized use occurs here
if (tag == TPM_TAG_STCLEAR_DATA) {
^~~
tpm12/tpm_init.c:666:5: note: remove the 'if' if its condition is always true
if (rc == 0) {
^~~~~~~~~~~~~
tpm12/tpm_init.c:662:28: note: initialize the variable 'tag' to silence this warning
TPM_STRUCTURE_TAG tag;
^
= 0
Stefan Berger [Sun, 13 May 2018 23:32:11 +0000 (19:32 -0400)]
Load permanent state before testing volatile or save state
The permanent state has to be loaded before the volatile or save state blobs
can be tested since they are connected to the permanenent state.
We implement TPM_PermanentAll_NVLoad_Preserve that makes a copy of any
cached permanent state blobs before we load the permanent state via
TPM_PermanentAll_NVLoad, which would consume and free any cached state blob,
if there was one (would fall back to reading from file otherwise). We then
set the copy of any cached permanent state blob back so that it can be used
when the TPM 1.2 start.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Sun, 18 Mar 2018 22:22:51 +0000 (18:22 -0400)]
TPM_MainInit write permanent state blob if SetState() blob was used
If the permanent state was set using SetState() write the permanent
state once we successfully read the volatile state and can use it.
This way we have the state in a file.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Sun, 11 Mar 2018 00:13:01 +0000 (19:13 -0500)]
Modify TPM_NVRAM_LoadData() to try to get cached state blob
Modify TPM_NVRAM_LoadData() to try to get the cached state blob before trying
to read the state blob from the file. We clear the state blob as part of
passing it to the TPM.
A side effect is now that if TPMLIB_ValidateState is called on a blob that
this call would not remove the cached blob. So we have to save a copy before
reading (and parsing) the state blob so we still have it when TPM_MainInit()
is called.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Sat, 10 Mar 2018 23:45:36 +0000 (18:45 -0500)]
Add APIs for getting and setting all state blobs
This patch adds APIs for getting and setting all types of state
blobs. We cache these blobs and allow them to be picked up when
the TPM starts. It will get any of these state blobs, if they
were set, before we go out and try to read the state blob from
a file.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Mon, 23 Apr 2018 10:29:04 +0000 (06:29 -0400)]
Implement TPMLIB_GetInfo() to for example get TPM spec. info
The EK certificates need information about the TPM specification that was
implemented. The best place to get the information from seems the TPM itself.
So we implement a function TPMLIB_GetInfo() to allow to query for the TPM
specification information and possibly other information in the future.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Wed, 28 Mar 2018 01:51:21 +0000 (21:51 -0400)]
Fix logic invoking validation of state
The logic for invoking the validation of the TPM 1.2 state was
broken. The validation of volatile and save state state requires
that the permanent state is available, so we always load it
first.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Sat, 17 Feb 2018 18:10:12 +0000 (13:10 -0500)]
Implement TPMLIB_ValidateState() to test state blobs early
Implement TPMLIB_ValidateState(), which is supposed to be used
for checking usability of state blobs before TPMLIB_MainInit()
is called or TPM_Startup has been sent to the TPM.
This function is useful to be called once TPM state blobs
have been migrated to a destination and we need to check
whether libtpms can use these state blobs and if not
we have a chance to fall back to the migration source host.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Sat, 4 Nov 2017 04:27:10 +0000 (00:27 -0400)]
Implement TPMLIB_SetBufferSize() for setting the size of the I/O buffer
Implement TPMLIB_SetBufferSize() for setting the size of the I/O buffer
that the TPM may advertise. For TPM 1.2 the size remains fixed since the
TIS interface can handle the current 4096 bytes.
This function will be important for TPM 2 with a CRB interface that cannot
handle 4096 bytes.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Wed, 11 Oct 2017 21:31:51 +0000 (17:31 -0400)]
build: add -lc when checking for missing symbols on OpenBSD
When checking for missing symbols we need to add -lc to the libraries
passed to gcc otherwise we always see lots of missing symbols even if
there aren't any.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan Berger [Tue, 8 Dec 2015 14:07:35 +0000 (09:07 -0500)]
Introduce internal interface to reach TPM functionality
Introduce an internal interface that allows us to reach TPM functionality
from the libary's API layer. This prepares the code for the addition
of a new API function that lets us choose which TPM to use, TPM 1.2 or
TPM2. Currently only TPM 1.2 functionality is available.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>