tpm2: Add padding to structures needed by some architectures

On m68k int's only need to be 2-byte aligned and therefore the size of
some data structures or offsets of fields within data structures is not
as expected. Fix this by adding artificial m68k-specific padding where
necessary. If padding was added on any other architecture, it would not
make a difference there. Similarly, if some day m68k gcc was to align int's
as expected, the artifical padding would not have any influence on the
expected sizes and offsets and could be removed.

With the padding applied, swtpm should now be able to read state written
by other architectures. This is for example the case with swtpm test cases.

Link: https://wiki.debian.org/M68k/Alignment
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2025-04-30 09:13:27 -04:00
parent 83df65f76a
commit 4ea8df351a
4 changed files with 32 additions and 0 deletions

View File

@ -604,6 +604,7 @@ noinst_HEADERS += \
tpm2/TPMCmd/tpm/include/tpm_public/VerifyConfiguration.h \
tpm2/Unmarshal_fp.h \
\
tpm2/TPMCmd/tpm/include/tpm_public/ArchSpecifics.h \
tpm2/BackwardsCompatibility.h \
tpm2/BackwardsCompatibilityBitArray.h \
tpm2/BackwardsCompatibilityObject.h \

View File

@ -12,6 +12,9 @@ MUST_BE(sizeof(TPM2B_NAME) == 2 + 64 + 2 + 2);
MUST_BE(sizeof(TPM2B_DIGEST) == 2 + 64);
MUST_BE(sizeof(TPM2B_NAME) == 2 + 64 + 2 + 2);
MUST_BE(sizeof(TPM2B_DIGEST) == 2 + 64);
#ifdef ARCH_NEEDS_INT_PADDING
MUST_BE(sizeof(TPMU_PUBLIC_PARMS) == 20);
#endif
/* The following are data structure from libtpms 0.7.x with RSA 2048 support
* that help to resume key and hash contexts (TPM2_ContextSave/Load) from this
@ -42,8 +45,10 @@ typedef struct {
TPMI_ALG_HASH nameAlg;
TPMA_OBJECT objectAttributes;
TPM2B_DIGEST authPolicy;
ARCH_PADDING(pad1, 2);
TPMU_PUBLIC_PARMS parameters;
RSA2048_TPMU_PUBLIC_ID unique;
ARCH_PADDING(pad2, 2);
} RSA2048_TPMT_PUBLIC;
MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, nameAlg) == 2);
MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, objectAttributes) == 2 + 2);
@ -119,12 +124,14 @@ typedef struct RSA2048_OBJECT
RSA2048_TPMT_SENSITIVE sensitive; // sensitive area of an object
RSA2048_privateExponent_t privateExponent; // Additional field for the private
TPM2B_NAME qualifiedName; // object qualified name
ARCH_PADDING(pad1, 2);
TPMI_DH_OBJECT evictHandle; // if the object is an evict object,
// the original handle is kept here.
// The 'working' handle will be the
// handle of an object slot.
TPM2B_NAME name; // Name of the object name. Kept here
// to avoid repeatedly computing it.
ARCH_PADDING(pad2, 2);
// libtpms added: OBJECT lies in NVRAM; to avoid that it needs different number
// of bytes on 32 bit and 64 bit architectures, we need to make sure it's the
@ -268,8 +275,10 @@ typedef struct {
TPMI_ALG_HASH nameAlg;
TPMA_OBJECT objectAttributes;
TPM2B_DIGEST authPolicy;
ARCH_PADDING(pad1, 2);
TPMU_PUBLIC_PARMS parameters;
RSA3072_TPMU_PUBLIC_ID unique;
ARCH_PADDING(pad2, 2);
} RSA3072_TPMT_PUBLIC;
MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, nameAlg) == 2);
MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, objectAttributes) == 2 + 2);
@ -341,6 +350,7 @@ typedef struct RSA3072_OBJECT
RSA3072_privateExponent_t privateExponent; // Additional field for the private
#endif // libtpms added end
TPM2B_NAME qualifiedName; // object qualified name
ARCH_PADDING(pad1, 2);
TPMI_DH_OBJECT evictHandle; // if the object is an evict object,
// the original handle is kept here.
// The 'working' handle will be the
@ -354,6 +364,7 @@ typedef struct RSA3072_OBJECT
// of bytes on 32 bit and 64 bit architectures, we need to make sure it's the
// same size; simple padding at the end works here
UINT8 _pad[3];
ARCH_PADDING(pad2, 2);
} RSA3072_OBJECT;
MUST_BE(sizeof(OBJECT_ATTRIBUTES) == 4);
MUST_BE(offsetof(RSA3072_OBJECT, publicArea) == 4);

View File

@ -0,0 +1,17 @@
// SPDX-License-Identifier: BSD-2-Clause
#ifndef _TPM_INCLUDE_PRIVATE_ARCHSPECIFICS_H_
#define _TPM_INCLUDE_PRIVATE_ARCHSPECIFICS_H_
#if defined(__m68k__)
// https://wiki.debian.org/M68k/Alignment
# define ARCH_NEEDS_INT_PADDING
#endif
#if defined(ARCH_NEEDS_INT_PADDING)
# define ARCH_PADDING(NAME, SIZE) char NAME[SIZE]
#else
# define ARCH_PADDING(NAME, SIZE)
#endif
#endif /* _TPM_INCLUDE_PRIVATE_ARCHSPECIFICS_H_ */

View File

@ -9,6 +9,7 @@
#ifndef MAX_CAP_BUFFER
# error MAX_CAP_BUFFER must be defined before this file so it can calculate maximum capability sizes
#endif
#include "tpm_public/ArchSpecifics.h" // libtpms added
#include "tpm_public/Capabilities.h"
#include "tpm_public/TpmAlgorithmDefines.h"
#include "tpm_public/TpmCalculatedAttributes.h"
@ -1462,6 +1463,7 @@ typedef union
{ // (Part 2: Structures)
TPMT_HA digest;
TPM_HANDLE handle;
ARCH_PADDING(pad, 2 + 64 + 2); // libtpms added: m68k
} TPMU_NAME;
typedef union
@ -2350,6 +2352,7 @@ typedef union
TPMS_ECC_PARMS eccDetail;
#endif // ALG_ECC
TPMS_ASYM_PARMS asymDetail;
ARCH_PADDING(pad, 20); // libtpms added: m68k
} TPMU_PUBLIC_PARMS;
typedef struct