Make the expected array size of compile-time constants dependent on
the version of the header. This way we can add elements to the array
while bumping up the version of the header.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Extend the test case data generation script with sm4. Since several
distros' openssl do not support sm4, we need to test for whether sm4
is supported by the installed openssl.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Use the EC_POINT_set/get_affine_coordinates function on OpenSSL >= 1.1.
These function are a 1:1 replacement for the
EC_POINT_set/get_affine_coordinates_GFp functions and are available
since OpenSSL 1.1 and are deprecated in OpenSSL 3.0.
This patch addresses one aspect of the OpenSSL 3.0 issues raised in
issue #215.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The NVRAM entries in s_indexOrderlyRam array do not need to contain a
0-sized terminating node. Instead, the entries may fill up this 512
byte array so that no NV_RAM_HEADER structure fits anymore. The fact
that no more NV_RAM_HEADER structure fits is also an indicator for the
last entry. We need to account for this in the code marshalling and
unmarshalling the entries so that we stop marshalling the entries
then and similarly stop unmarshalling.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Initialize a while OBJECT before using it. This is necessary since
an OBJECT may also be used as a HASH_OBJECT via the ANY_OBJECT
union and that HASH_OBJECT can leave bad size inidicators in TPM2B
buffer in the OBJECT. To get rid of this problem we reset the whole
OBJECT to 0 before using it. This is as if the memory for the
OBJECT was just initialized.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Fix the following compiler warning from gcc 10.3.0 by using memcpy
instead of MemoryCopy (fixes issue #229).
tpm2/NVDynamic.c: In function 'NvRamGetEnd':
tpm2/NVDynamic.c:378:12: warning: function may return address of local variable [-Wreturn-local-addr]
378 | return iter;
| ^
tpm2/NVDynamic.c:339:26: note: declared here
339 | NV_RAM_HEADER header;
| ^
tpm2/NVDynamic.c: In function 'NvRamGetIndex':
tpm2/NVDynamic.c:411:12: warning: function may return address of local variable [-Wreturn-local-addr]
411 | return currentAddr;
| ^
tpm2/NVDynamic.c:339:26: note: declared here
339 | NV_RAM_HEADER header;
| ^
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Restore the original value of the memory location where data from
a stream was unmarshalled and the unmarshalled value was found to
be illegal. The goal is to not keep illegal values in memory.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add maxSize parameter to TPM2B_Marshal and assert on it checking
the size of the data intended to be marshaled versus the maximum
buffer size.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Reset the buffer size indicator in a TPM2B type of buffer after it failed
the test for the maximum buffer size it allows. This prevents having bad
buffer sizes in memory that can come to haunt us when writing the volatile
state for example.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Windows 2019 Server padds the TPM_ContextLoad() command with additional
bytes up to TPM_PT_MAX_OBJECT_CONTEXT for the TPMS_CONTEXT part. Since
libtpms does not use an OBJECT to serialize the keys (anymore) it now
uses less bytes than the MAXimum of TPM_PT_MAX_OBJECT_CONTEXT bytes and
the padding leaves some unconsumed bytes that end up failing the command
since no left-over bytes are allowed in any command.
When unconsumed bytes are left in TPMS_CONTEXT_Unmarshal() we check that
the original passed in size was that of TPM_PT_MAX_OBJECT_CONTEXT and
only then consume the additional padding bytes. Luckily only one command
calls TPMS_CONTEXT_Unmarshal() so that no unwanted side effects should
occur anywhere else, such as no bytes left for unmarshalling the next
structure.
The wisdom behind the padding is not quite clear but it feels like
ill-fixing the code to work around a Windows 2019 server bug...
This patch fixes issed #217
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This patch addresses issue #209.
The context gap for libtpms is currently only 0xff due to the CONTEXT_SLOT
being a UINT8. To extend this to 0xffff, we need to define the CONTEXT_SLOT
as UINT16 and introduce a global variable s_ContextArrayMask that takes on
two valid values, 0xff for simulating the CONTEXT_SLOT when it was UINT8
and 0xffff for usage with the new CONTEXT_SLOT of type UINT16. All
occurrences of casts to CONTEXT_SLOT are replaced with a macro
CONTEXT_SLOT_MASKED that applies this mask to a value instead of using the
cast. We also use it for some calculations to avoid spilling over from
1 byte into 2 bytes for example. The cast with the new code is the same as
applying the mask 0xffff, and using the 0xff mask we can simulate the old
CONTEXT_SLOT (1 byte), which we need for seamlessly resuming old state. We
switch from the 0xff mask to the 0xffff mask when the TPM is reset.
There's one place where the s_ContextArrayMask is initialized to 0xff, and
this is when we resume 'old' STATE_RESET_DATA. The places where it is
intialized to 0xffff are in TPM_Manufacture() and
TPM_SessionStartup(SU_CLEAR), both of which are not called after resuming
state.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Do not call BLOCK_SKIP_READ once rc has been set to any error value.
Therefore, surround all occurrences of BLOCK_SKIP_READ() with tests
of 'rc'.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement a cache for the private exponent 'D' and prime 'Q' so that we
do not have to recalculate 'Q' and 'D' every time an RSA key is used. For
a cache hit we now use ~34000 cycles and on a cache miss it needs around
130000 cycles. Previously it needed around 100000 cycles to calcuate 'Q'
and 'D'. Assuming that keys will be reused and the cache is big enough
for the number of keys being use (64 entries), it seems well worth it.
This solution is better than extending the OBJECT with 'D' since OBJECT is
kept in the TPM's NVRAM and we would then need more memory to store OBJECTs
there.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
When testing downgrading from libtpms 0.8 to 0.7 (which is not
possible), the error message which is reported is:
libtpms/tpm2: Unexpect value for MAX_RSA_KEY_BITS; its value 3072 is
not = 2048; (version: 2).
codespell (https://github.com/codespell-project/codespell) reports a
misspelling for "Unexpect", which should be "Unexpected". As the project
contains many more misspellings in comments, error messages and
documentation, fix all misspellings reported by codespell.
Signed-off-by: Nicolas Iooss <nicolas.iooss@ledger.fr>
The TPM is supposed to provide the output IV in the ivInOut parameter in
CryptSymmetricEncrypt. In the case of using the openssl routines, the
output IV is missed, and the resulting output from the TPM is in the
input IV.
OpenSSL unfortunately does not export EVP_CIPHER_CTX_iv() until
tags/OpenSSL_1_1_0, so we have to fall back to the reference code for
previous OpenSSL versions.
Signed-off-by: William Roberts <william.c.roberts@intel.com>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This patch addresses the bug reported in issue #195 where the saving of
an externally loaded public key's context doesn't work due to the usage of
ANY_CONTEXT_SAVE for saving key contexts. This patch fixes the issue by
creating local versions of TPM_SENSITIVE_Marshal/_Unmarshal that deals
with the case where sensitiveType is not a type of private key but a
public key instead that basically doesn't have much information in
TPM_SENSITIVE but is all zeros instead.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
For some peace-of-mind add a function that allows us to check the RSA keys
that are generated, especially the primary keys that are not generated by
OpenSSL.
Use the following configure line to compile libtpms:
CFLAGS="-DDO_RSA_CHECK_KEY=1" ./autogen.sh --prefix=/usr \
--with-tpm2 --with-openssl
Start swtpm after installing libtpms:
swtpm socket --tpmstate dir=/tmp/myvtpm --tpm2 --ctrl type=tcp,port=2322 \
--server type=tcp,port=2321 --flags not-need-init --log level=0
We can now run this test program to check keys by using an RSA primary key
for signing.
export TPM_COMMAND_PORT=2321 TPM_PLATFORM_PORT=2322 \
TPM_SERVER_NAME=localhost TPM_INTERFACE_TYPE=socsim \
TPM_SERVER_TYPE=raw
echo "test" > input
swtpm_ioctl --tcp :${TPM_PLATFORM_PORT} -i
tssstartup
while :; do
for keysize in 2048 3072; do
tsscreateprimary -rsa $keysize -si -hi n
tsssign -hk 80000000 -if input
tssflushcontext -ha 80000000
done
done
Libtpms has passed multiple hours of testing.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Some older systems do not define static_assert, so we have to provide
our own static_assert that does 'nothing'.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Sanitize some of the values read from the TPM state stream.
All Coverity discoveries seem to be false positives.
Coverity doesn't like to see array_size being used in the loop even
though it was compared against ARRAY_SIZE() before. We solve this by
using ARRAY_SIZE() as the loop limit now rather than array size.
Compare seed.b.size against PRIMARY_SEED_SIZE even though this is
already being done in TPM2B_Unmarshal().
The num_bytes parameter is sanitized via a comparison involving a
sum over a sum of values, but Coverity doesn't seem to detect this.
Then we have to use it as a loop limit. I don't see another way.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Prevent a potential buffer overrun by checking that EVP_DecryptUpdate()
has not overrun the buffer it was passed in, so this overrun should
never occurr unless EVP_DecryptUpdate() was wrong. Also the pAssert above
it should have taken care of it already.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Coverity complains that the *output* variable passed to
AES_set_encrypt_key contains uninitialized bytes, so we initialize
the variables now.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Coverity complains that nrh may not be initialize when copying nrh.size
from it into the buffer pointer to by nrhp. So resolve this by clearing
nrh at the beginning of the loop and checking 'rc' after the Unmarshal.
Previously we could have copied an uninitialized nrh.size but would have
propagated the rc error code from UINT32_Unmarshal(), so this fix doesn't
really change anything.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Save key and hash contexts using the ANY_OBJECT_Marshal function and try
to load it using ANY_OBJECT_Unmarshal(). Unfortunately older contexts were
written out as plain OBJECTs, so we have to accomodate this case as well
so that we can restore key contexts from libtpms-0.7.x. We do not support
resuming HASH contexts from libtpms-0.7.x.
Before this modification context files written out by the IBM TSS stack
were 2692 bytes independent of content. Now an RSA 2048 key is 1222 bytes
and a NIST p384 key is 982 bytes.
Several of the original TPM 2 function exporting Sequence state and
importing it can now be disabled.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Make the functions ANY_OBJECT_Marshal/Unmarshal non-static so that we can
call it from other places. Also allow passing a parameter 'verbose' to the
ANY_OBJECT_Unmarshal function that allows us to call this function without
it logging errors. We need this when trying to load a context from an older
libtpms versions that did not use ANY_OBJECT_Marshal to write out the
OBJECT (but copied it right from memory).
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This patch ensures that the leading zeros in the b parameter for NIST P521
are being kept so that HLK accepts the returned parameters from
TPM2_ECC_Parameters. Now 66 bytes are reported for 'b' rather than only 65.
Do the same for the 'a' parameter, though that one was properly reported
already because it didn't have any leading zeros.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This patch addresses issue #177 by fixing some typos and error
reporting inconsistencies (how structures are spelled) in NVMarhsal.c.
Reported-by: Nicolas Iooss <nicolas.iooss@ledger.fr>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
cppcheck has detected the following issues in 2 functions. However,
neither one of the out-of-bounds array access can happen with the
existing code (see comments in patch).
src/tpm2/Session.c:399:5: note: After for loop, slotIndex has value 3
for(slotIndex = 0; slotIndex < MAX_LOADED_SESSIONS; slotIndex++)
^
src/tpm2/Session.c:414:15: note: Assuming condition is false
if(result != TPM_RC_SUCCESS)
^
src/tpm2/Session.c:419:15: note: Array index out of bounds
s_sessions[slotIndex].occupied = TRUE;
^
src/tpm2/Session.c:591:27: error: Array 's_sessions[3]' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]
MemoryCopy(&s_sessions[slotIndex].session, session, sizeof(SESSION));
^
src/tpm2/Session.c:571:5: note: After for loop, slotIndex has value 3
for(slotIndex = 0; slotIndex < MAX_LOADED_SESSIONS; slotIndex++)
^
src/tpm2/Session.c:581:8: note: Assuming condition is false
&& contextIndex != s_oldestSavedSession)
^
src/tpm2/Session.c:591:27: note: Array index out of bounds
MemoryCopy(&s_sessions[slotIndex].session, session, sizeof(SESSION));
^
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
UBSAN detects possibly misaligned address when reading out of the
TPM 2's NVRAM and when writing back into it. The NV_RAM_HEADER may
be unaligned like this:
tests/test_tpm2_save_load_state_3.log:tpm2/Marshal.c:117:29: \
runtime error: load of misaligned address 0x7ffcb53b3bca for type 'UINT32', which requires 4 byte alignment
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Make sure that the value of bnK is not short so that the subsequent
BnEccModMult() runs in constant time. We take the same approach as with
the modifications to BnEccGenerateKeyPair() where we request bnK to have
all bytes set (no leading zeros that will be cut away) in case the order
of the curve is as byte boundary. In the other cases we add the order
to bnK, which creates bnK1, which we then use for BnEccModMult's scalar
parameter.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Suggested-by: Charanjit Jutla <csjutla@us.ibm.com>
Reviewed-by: Charanjit Jutla <csjutla@us.ibm.com>
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
To avoid a potential side channel in the EcSchnorr signing algorithm,
enforce that the OpenSSL-generated bnD does not have leading zeros
that may then cause a timing side channel in the BnEccModMult() operation.
We modified BnEccGenerateKeyPair() so it calls BnEccModMult with a scalar
of constant number of bytes (for a particular curve):
In this version of BnEccGenerateKeyPair we take a dual approach to constant
time requirements: For curves whose order is at the byte boundary, e.g.
NIST P224/P256/P384, we make sure that bnD has all bytes set (no leading zeros)
so that OpenSSL BIGNUM code will not reduce the number of bytes and the
subsequent BnEccModMult() would run faster for a shoter value. For all other
curves whose order is not at the byte boundary, e.g. NIST P521, we simply
always add the order to bnD and call BnEccModMult() with the result bnD1,
which leads to the same result.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Suggested-by: Charanjit Jutla <csjutla@us.ibm.com>
Reviewed-by: Charanjit Jutla <csjutla@us.ibm.com>
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
A tpm12 function that is only needed with freebl library can
be conditionally enabled with '#if USE_FREEBL_CRYPTO_LIBRARY'.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The JSON returned by TPM2_GetInfo contains a leading zero in the level.
$> swtpm_ioctl --tcp :10000 --info 1
{"TPMSpecification":{"family":"2.0","level":00,"revision":162+0}}
This patch fixes this to:
$> swtpm_ioctl --tcp :10000 --info 1
{"TPMSpecification":{"family":"2.0","level":0,"revision":162+0}}
This patch fixes the following compilation error on Fedora 32 / s390x:
tpm2/Marshal.c: In function 'TPM2B_CREATION_DATA_Marshal':
tpm2/Marshal.c:95:19: error: 'sizePtr' may be used uninitialized in this function [-Werror=maybe-uninitialized]
95 | (*buffer)[0] = (BYTE)((*source >> 8) & 0xff);
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tpm2/Marshal.c:2201:11: note: 'sizePtr' was declared here
2201 | BYTE *sizePtr;
| ^~~~~~~
The error is a false positive since sizePtr will have been initialized if
UINT16_Marshal() is called.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
tpm12/tpm_nvram.c: In function 'TPM_Process_NVWriteValue':
tpm12/tpm_nvram.c:2313:45: error: 'd1NvdataSensitive' may be used uninitialized in this function [-Werror=maybe-uninitialized]
2313 | if ((d1NvdataSensitive->pubInfo.permission.attributes & TPM_NV_PER_WRITEALL) &&
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
This compiler error is a false positive since the above statement is inside
this if clause:
if ((returnCode == TPM_SUCCESS) && !done && !dir) {
However, if d1NvdataSensitive was not set then returnCode is
either != TPM_SUCCESS OR
- case index0 = FALSE : dir = TRUE per line 2106 OR
- case index0 = TRUE (nvIndex = 0): done = TRUE per line 2215.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Fix PCRBelongsTCBGroup by adjusting the set of PCRs that belong to the TCB
Group. The effect of this is that PCR changes to PCR 16 (for example) do
not change the pcrUpdateCounter anymore. The effect *should not* have any
negative side effects when using the TPM.
We also need to update the test cases that now show a different
pcrUpdateCounter in the responses. Also 'swtpm' test cases need
to be fixed to expect the changed result.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This does not affect the proper functioning of the code since all
of the commands at the end of the array are currently disabled.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
In corner cases where the size of the salt and the size of the hash
to sign + 2 exceed the signature size we cannot use the salt length =
hash length but have to resort to using the maximum possible salt
length.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Sync up on the #define's for HASH_ALIGNMENT, which does not have much
relevance for the OpenSSL implementation.
The affected 32 or 64 bit align field in the ANY_HASH_STATE doesn't carry
any significance. It can be commented without side effects.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Remove CURVE_NAME_DEF field from ECC_CURVE structure and add
#define CURVE_NAME(N)
so that nothing misses the removed field, which wasn't used
before, either.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add the #define SYMMETRIC_ALIGNMENT that aligns the tpmCryptKeySchedule_t
size. Since this tpmCryptKeySchedule_t only seems to be used as a stack
variable and the alignment field is never accessed nor the size of the
structre taken, it shouldn't affect anything.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Call EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1) when creating an RSA
signature to set the PSS salt length to the digest length. Without
this call we previously set the salt length to the maximum
permissible value, but this is not how TPM 2 implements it.
Per interoperability testing between signatures created previously
with the max. permissible value and the new code, which does not
modify the signature verification code, old signatures still verify.
New signatures also verify.
This patch may solve interoperability with hardware TPMs that signatures
created following this patch now verify on hardware TPMs as well.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Always use a temporary buffer large enough to meet the requirements of the
EVP_DecryptUpdate() call.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add missing call of EVP_CIPHER_CTX_set_padding(ctx, 0) in the symmetric
decryption case. This was missing and failed some decryption cases.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add a missing input size check for CryptSymmetricDecrypt so that we return
the proper error code TPM_RC_SIZE in case the input size is not a multiple
of the block size. Before TPM_RC_FAILURE was returned.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
For the RSA decryption we have to use an output buffer of the size of the
(largest possible) RSA key for the decryption to always work.
This fixes a stack corruption bug that caused a SIGBUS and termination of
'swtpm'.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add missing EC Curve cases in Unmarshal function.
Also, don't accept curves that are not usable during runtime because OpenSSL
may not support them.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
PrimeSieve was accessing the sieveMarks array at out-of-bounds index 5
due to a bug in other parts of the code. This patch fixes the issue
and prevents this access by limiting the values that 'next' can take on.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Return the RSAKeySizes in the JSON produced by TPM2_GetInfo() under
a new flag with value '4'. This helps higher level tools and users
to easily determine what key sizes are supported for RSA.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Start supporting RSA 3072 keys.
NVMarshal.c: We now accept state that was written by libtpms when RSA keys
sizes were 2048 or are 3072, basically less-or-equal than 3072.
Also increase the NVRAM memory size by ~45 kb to accommodate the worst
case where the USER NVRAM is full of 65 2048 bit persisted keys whose 65
OBJECTs are now expanding and need to again fit into the NVRAM. We have
to add exactly 45760 bytes to accomodate this case. See swtpm test
case test_tpm2_save_load_state_2. 65 * 704 = 45760.
NOTE: BETTER TO NOT BACKPORT!!! MAY NEGATIVELY AFFECT UPGRADE PATH!
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Increase the MAX_CONTEXT_SIZE to 2680 to support the increased context
size when using 3072 bit keys.
NVMarhsal.c: Accept MAX_CONTEXT_SIZE values of less-or-equal the 2680,
which also accepts context sizes of the old value 2474.
NOTE: BETTER TO NOT BACKPORT!
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This is the Coverity complaint about the line
infoDataSize = TimeGetMarshaled(&infoData);
CID 1402057: Out-of-bounds access (OVERRUN)
1. overrun-buffer-val: Overrunning array infoData of 32 bytes by passing
it to a function which accesses it at byte offset 255.
TimeGetMarshaled() correctly serializes into &infoData, which is casted to
a buffer and then the data are written into the buffer. Also only 25 bytes,
as indicated by infoDataSize, are used, which is less than sizeof(infoData),
which is 32.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The original TPM 2 version of BIG_INITIALIZED uses a BIGNUM
on the stack and uses the internals of the BIGNUM's data structure
to initialize it. We don't do this here but use only the API
functions and therefor have tp free the BIGNMs create with
BIG_INITIALIZED().
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add tpmCryptKeySchedule to union tpmCryptKeySchedule_t. Since this is
causing linker problems on OSX and is not used anywhere at this point,
comment it.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
With some x509 related issues fixed, advertise revision 155 now
so that IBM TSS 2 test suite passes the X509 tests.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
When a child key is derived from an Object, we need to know what
SEED_COMPAT_LEVEL the Object was created under (or what the its seed is)
so that we can later on derive child with the appropriate
SEED_COMPAT_LEVEL.
When an external object is loaded we set the SEED_COMPAT_LEVEL to
SEED_COMPAT_LEVEL_ORIGINAL so that any RSA key that could possibly be
derived from it will always create the same RSA key independent
of the SEED_COMPAT_LEVEL of the hierarchy it is loaded under. This
way any key derivation that could happen on an external key remains
the same before and after this code change.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Pass the SEED_COMPAT_LEVEL, originating from the seed that's being used,
to the CryptAdjustPrimeCandidate function and use it to determine
whether the old code should be used or the new one.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add in the new RsaAdjustPrimeCandidate() function but do not use it
so far since it creates slightly different primes than the previous
code and we would get different derived keys if we were to use it with
'old' seeds.
Adjust the code to return the same results for 64 bit and 32 bit machines.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add a SEED_COMPAT_LEVEL to the DRBG state that is associated with the seed
and indicates the seed compatibility level we need to maintain when deriving
RSA keys from seeds. We only need to be able to handle RSA keys derived via
the DRBG state. Other keys, such as symmetric keys, are not affected. Also
RSA keys cannot be derived from a KDR, so the KDF does not need to carry
the SEED_COMPAT_LEVEL.
All functions that need to pass a value set SEED_COMPAT_LEVEL to
SEED_COMPAT_LEVEL_ORIGINAL (0) for now.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add SEED_COMPAT_LEVEL to the nullSeed in the state_reset data to track
its compatibility level. We need it for VM suspend and resume.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add a variable seedCompatLevel to the each seed in the PERSISTENT_DATA
that allows us to track the age of the seed. Whenever a new seed
is created the seedCompatLevel is also written and set to the latest
version. This seedCompatLevel then influences the crypto algorithm that
can be used for deriving keys so that previously derived keys
are now still generated in the same way. When the seed is changed
the old keys are all useless and newly derived keys can then use
the new algorithm.
This patch only sets the variables to the current compatibility
level SEED_COMPAT_LEVEL_ORIGINAL and writes it out as part of the state
file. This makes the state file not downgradeable.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
- Introduce Platform.h and replace usage of PlatformData.h and
Platform_fp.h
- Drop Implementation.h since we now use TpmProfile.h (which we
prepared previously); many #defines were moved to TpmTypes.h
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Have some DRBG related functions return BOOL or TPM_RC to be
able to handle failure cases. Inside the functions do not
use FAIL anymore but LOG_FAILURE and return FALSE.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Replace FAIL_NOCMD with LOG_FAILURE, which calls into LogFailure,
which in turn calls TpmSetFailureMode, just like before.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Rev 155 code defines MAX_SM4_KEY_BITS = 0 and MAX_CAMELLIA_KEY_BITS = 0
since both algorithms are not enabled. To be able to read old state
we now replace the usage of the #defines with hard coded values that
have no further meaning. If we ever activate the algoritms, we have to
extend the state.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Keep the size of PRIVATE_VENDOR_SPECIFIC_BYTES. Changing its size would
change the size of an Object, which we don't want since Objects are in
NVRAM memory and now more would fit than before. Fitting more is not the
problem but the state cannot be downgraded anymore since an earlier
implementation would require more bytes per Object and would not allow
fitting them all anymore.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Return an error code from TPM2_Shutdown in case an unknown shutdown
type code was given. Before that a failure was returned, which should
never have happened since the unmarshal function for parsing the shutdown
code would have caused an error when the command was parsed.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This patch addresses the following false positives on Ubuntu Trusty
on x86_64:
tpm12/tpm_process.c: In function ?TPM_Process_GetCapability?:
tpm12/tpm_process.c:3521:35: error: ?transportEncrypt? may be used uninitialized in this function [-Werror=maybe-uninitialized]
returnCode = TPM_ProcessAudit(tpm_state,
^
tpm12/tpm_counter.c: In function ?TPM_Process_IncrementCounter?:
tpm12/tpm_counter.c:421:27: error: ?counterValue? may be used uninitialized in this function [-Werror=maybe-uninitialized]
rc = TPM_Sbuffer_Append32(sbuffer, tpm_counter_value->counter);
^
tpm12/tpm_counter.c:791:24: note: ?counterValue? was declared here
TPM_COUNTER_VALUE *counterValue; /* The counter value */
^
tpm12/tpm_key.c: In function ?TPM_KeyParms_CheckProperties?:
tpm12/tpm_key.c:1959:42: error: ?tpm_rsa_key_parms? may be used uninitialized in this function [-Werror=maybe-uninitialized]
rc = TPM_KeyParams_CheckDefaultExponent(&(tpm_rsa_key_parms->exponent));
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
The above gcc on x86 with -O3 reports the following false positives:
gcc -DHAVE_CONFIG_H -I. -I.. -include tpm_library_conf.h -I../include/libtpms -I../include/libtpms -fstack-protector-strong -DTPM_V12 -DTPM_PCCLIENT -DTPM_VOLATILE_LOAD -DTPM_ENABLE_ACTIVATE -DTPM_AES -DTPM_LIBTPMS_CALLBACKS -DTPM_NV_DISK -DTPM_POSIX -DTPM_NOMAINTENANCE_COMMANDS -O3 -DUSE_OPENSSL_FUNCTIONS_SYMMETRIC=1 -DUSE_OPENSSL_FUNCTIONS_EC=1 -DUSE_OPENSSL_FUNCTIONS_ECDSA=0 -DUSE_OPENSSL_FUNCTIONS_RSA=0 -Wall -Werror -Wreturn-type -Wsign-compare -Wno-self-assign -MT tpm12/libtpms_tpm12_la-tpm_nvram.lo -MD -MP -MF tpm12/.deps/libtpms_tpm12_la-tpm_nvram.Tpo -c tpm12/tpm_nvram.c -o tpm12/libtpms_tpm12_la-tpm_nvram.o
tpm12/tpm_nvram.c: In function ‘TPM_Process_NVReadValue’:
tpm12/tpm_nvram.c:1539:38: error: ‘isGPIO’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
if ((returnCode == TPM_SUCCESS) && !isGPIO) {
^
tpm12/tpm_nvram.c: In function ‘TPM_Process_NVWriteValue’:
tpm12/tpm_nvram.c:2323:6: error: ‘isGPIO’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
if (!isGPIO) {
^
gcc -DHAVE_CONFIG_H -I. -I.. -include tpm_library_conf.h -I../include/libtpms -I../include/libtpms -fstack-protector-strong -DTPM_V12 -DTPM_PCCLIENT -DTPM_VOLATILE_LOAD -DTPM_ENABLE_ACTIVATE -DTPM_AES -DTPM_LIBTPMS_CALLBACKS -DTPM_NV_DISK -DTPM_POSIX -DTPM_NOMAINTENANCE_COMMANDS -O3 -DUSE_OPENSSL_FUNCTIONS_SYMMETRIC=1 -DUSE_OPENSSL_FUNCTIONS_EC=1 -DUSE_OPENSSL_FUNCTIONS_ECDSA=0 -DUSE_OPENSSL_FUNCTIONS_RSA=0 -Wall -Werror -Wreturn-type -Wsign-compare -Wno-self-assign -MT tpm12/libtpms_tpm12_la-tpm_process.lo -MD -MP -MF tpm12/.deps/libtpms_tpm12_la-tpm_process.Tpo -c tpm12/tpm_process.c -o tpm12/libtpms_tpm12_la-tpm_process.o
tpm12/tpm_process.c: In function ‘TPM_Process_GetCapabilitySigned’:
tpm12/tpm_process.c:5089:19: error: ‘transportEncrypt’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
returnCode = TPM_ProcessAudit(tpm_state,
^
tpm12/tpm_process.c: In function ‘TPM_Process_SetCapability’:
tpm12/tpm_process.c:5309:19: error: ‘transportEncrypt’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
returnCode = TPM_ProcessAudit(tpm_state,
^
tpm12/tpm_process.c: At top level:
gcc -DHAVE_CONFIG_H -I. -I.. -include tpm_library_conf.h -I../include/libtpms -I../include/libtpms -fstack-protector-strong -DTPM_V12 -DTPM_PCCLIENT -DTPM_VOLATILE_LOAD -DTPM_ENABLE_ACTIVATE -DTPM_AES -DTPM_LIBTPMS_CALLBACKS -DTPM_NV_DISK -DTPM_POSIX -DTPM_NOMAINTENANCE_COMMANDS -O3 -DUSE_OPENSSL_FUNCTIONS_SYMMETRIC=1 -DUSE_OPENSSL_FUNCTIONS_EC=1 -DUSE_OPENSSL_FUNCTIONS_ECDSA=0 -DUSE_OPENSSL_FUNCTIONS_RSA=0 -Wall -Werror -Wreturn-type -Wsign-compare -Wno-self-assign -MT tpm12/libtpms_tpm12_la-tpm_transport.lo -MD -MP -MF tpm12/.deps/libtpms_tpm12_la-tpm_transport.Tpo -c tpm12/tpm_transport.c -o tpm12/libtpms_tpm12_la-tpm_transport.o
tpm12/tpm_transport.c: In function ‘TPM_Process_ReleaseTransportSigned’:
tpm12/tpm_transport.c:2810:42: error: ‘t1TpmTransportInternal’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
returnCode = TPM_TransportLogOut_Extend(t1TpmTransportInternal->transDigest,
^
This patch initializes the variables.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
The -O3 passed to the ppc64el gcc-5 compiler on Ubuntu 16.04 causes
the following false positives:
gcc-5 -DHAVE_CONFIG_H -I. -I.. -include tpm_library_conf.h -I../include/libtpms -I../include/libtpms -fstack-protector-strong -DTPM_V12 -DTPM_PCCLIENT -DTPM_VOLATILE_LOAD -DTPM_ENABLE_ACTIVATE -DTPM_AES -DTPM_LIBTPMS_CALLBACKS -DTPM_NV_DISK -DTPM_POSIX -DTPM_NOMAINTENANCE_COMMANDS -g -O3 -fstack-protector-strong -DUSE_OPENSSL_FUNCTIONS_SYMMETRIC=1 -DUSE_OPENSSL_FUNCTIONS_EC=1 -DUSE_OPENSSL_FUNCTIONS_ECDSA=0 -DUSE_OPENSSL_FUNCTIONS_RSA=0 -Wall -Werror -Wreturn-type -Wsign-compare -Wno-self-assign -MT tpm12/libtpms_tpm12_la-tpm_session.lo -MD -MP -MF tpm12/.deps/libtpms_tpm12_la-tpm_session.Tpo -c tpm12/tpm_session.c -o tpm12/libtpms_tpm12_la-tpm_session.o
tpm12/tpm_session.c: In function ‘TPM_Process_SaveContext’:
tpm12/tpm_session.c:3056:16: error: ‘contextIndex’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
uint32_t contextIndex; /* free index in context list */
^
tpm12/tpm_session.c: In function ‘TPM_Process_SaveAuthContext’:
tpm12/tpm_session.c:4934:16: error: ‘contextIndex’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
uint32_t contextIndex; /* free index in context list */
^
This patch initializes these variables to 0.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
gcc (Ubuntu 9.2.1-21ubuntu1) 9.2.1 20191130
The gcc compiler on Ubuntu Focal reports several false positives for
potentially uninitialized variables:
tpm12/tpm_session.c: In function ‘TPM_Process_SaveContext’:
tpm12/tpm_session.c:3229:19: error: ‘tpm_auth_session_data’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
3229 | returnCode = TPM_AuthSessionData_Store(&r1ContextSensitive, tpm_auth_session_data);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tpm12/tpm_delegate.c: In function ‘TPM_Process_DelegateManage’:
tpm12/tpm_delegate.c:1787:49: error: ‘familyRow’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
1787 | if ((opCode != TPM_FAMILY_CREATE) && (familyRow->flags & TPM_DELEGATE_ADMIN_LOCK)) {
| ~~~~~~~~~^~~~~~~
tpm12/tpm_delegate.c: In function ‘TPM_Process_DelegateUpdateVerification’:
tpm12/tpm_delegate.c:3575:48: error: ‘d1DelegateTableRow’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
3575 | d1DelegateTableRow->pub.verificationCount = familyRow->verificationCount;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
All of the variables are initialize under the same condition as they are
accessed.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This patch addresses the following valgrind issue detetcted by swtpm test suite:
== Syscall param write(buf) points to uninitialised byte(s)
==3515669== at 0x4DC14B7: write (in /usr/lib64/libc-2.30.so)
==3515669== by 0x48547FB: write_full (utils.c:242)
==3515669== by 0x48548F3: writev_full (utils.c:301)
==3515669== by 0x48520A6: SWTPM_IO_Write (swtpm_io.c:229)
==3515669== by 0x4850662: mainLoop (mainloop.c:282)
==3515669== by 0x402BE7: swtpm_main (swtpm.c:497)
==3515669== by 0x4CF61A2: (below main) (in /usr/lib64/libc-2.30.so)
==3515669== Address 0x52413a2 is 34 bytes inside a block of size 2,006 alloc'd
==3515669== at 0x483980B: malloc (vg_replace_malloc.c:309)
==3515669== by 0x48548A1: writev_full (utils.c:287)
==3515669== by 0x48520A6: SWTPM_IO_Write (swtpm_io.c:229)
==3515669== by 0x4850662: mainLoop (mainloop.c:282)
==3515669== by 0x402BE7: swtpm_main (swtpm.c:497)
==3515669== by 0x4CF61A2: (below main) (in /usr/lib64/libc-2.30.so)
==3515669== Uninitialised value was created by a stack allocation
==3515669== at 0x4953993: TPM2_Load (ObjectCommands.c:132)
==3515669==
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Revert the changes trying to use strncpy to now use strcpy again.
Recent compilers complain like this:
tpm12/tpm_nvfile.c: In function ‘TPM_NVRAM_Init’:
tpm12/tpm_nvfile.c:138:9: error: ‘strncpy’ specified bound depends on the length of the source argument [-Werror=stringop-overflow=]
138 | strncpy(state_directory, tpm_state_path, length + 1);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tpm12/tpm_nvfile.c:130:18: note: length computed here
130 | length = strlen(tpm_state_path);
| ^~~~~~~~~~~~~~~~~~~~~~
tpm12/tpm_nvfile.c: At top level:
cc1: error: unrecognized command line option ‘-Wno-self-assign’ [-Werror]
cc1: all warnings being treated as errors
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Some TDES related marshalling and unmarshalling functions were
missing, so add them. Now TDES keys can be created.
Signed-off-by: stefan Berger <stefanb@linux.ibm.com>
This patch fixes a bug described in the following TCG Document
ERRATA; Errata Version 1.9, August 23, 2019; For TCG Trusted Platform
Module Library; Family "2.0", Level 00, Revision 1.38, Sept 29, 2016
section 2.34: NV PIN Indices
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
We define USE_SPEC_COMPLIANT_PROOFS which overrides PRIMARY_SEED_SIZE in
Implentation.h and cause PRIMARY_SEED_SIZE to be set to 64. Nevertheless,
adjust the value in Implementation.h.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Do not go by the toTest vector when it comes to testing symmetric
crypto modes since those bits may have been cleared elsewhere.
Check the implemented algorithm vector instead for whether the
mode is implemented.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Add a missing break statement to the EVP function selectors
based on algorithm. So far this missing break statement had
not negative effect since no other algoritms are in use in
case statements below the TDES.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Use TPM_PrintFourLimit in those cases where less than 4 bytes of
valid data may exist. Hashes, nonces, encrypted data, and others
typically have more than 4 bytes but data read from NVRAM or
to be encrypted data may have less.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Get rid of the usage of an sprintf and use snprintf instead. In this
case the buffer is 128, so big enough to not cause problems, though.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Fix a potential buffer overflow bug in the creation of filenames
that were using sprintf() rather than snprintf(). The buffer overflow
could occurr if the buffer is longer than 4096 bytes. The state path
may alone be 4096 bytes and could possibly trigger the overflow.
Swtpm for example is not affected from this since it uses the callbacks
that are invoked before the faulty function is called.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Check the size of the available data before hashing them. A minimum
of 20 bytes needs to be passed into the function so that we can hash
the data 'before' it.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Reported-by: Yi Ren <yunye.ry@alibaba-inc.com>
Fix a Coverity complaint by using iv.t.buffer rather than the
1-byte synonym (due to union) iv.b.buffer.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement key creation with OpenSSL if rand == NULL, meaning
that we create a non-KDF-derived key, so a purely random key.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Use the CRT (Chinese Remainder Theorem) method for doing the RSA
operations. Unfortunately it is not sufficient to just pass the
precalculated dP, dQ, and qInv parameters to OpenSSL private key
crypto functions but it also needs D, which is a bit more involved
to calculate.
We are not caching D (private exponent) as part of the OBJECT since
the OBJECT lives in size-limited NVRAM and we would need to add
'D' to the privateExponent_t, which would make it bigger and which
would allow less keys to fit into memory, which in turn could be-
come an issue if we wanted to resume a TPM that filled up the NVRAM
with keys and now less keys would fit into the NVRAM.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Implement helper functions to create an RSA public and private
key. Create the latter with the CRT parameters.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>