!13 FIX the issue where the lenth of the generated prime value is insufficient
From: @jackjf Reviewed-by: @zhujianwei001 Signed-off-by: @zhujianwei001
This commit is contained in:
commit
15b16e6b47
17
libtpms.spec
17
libtpms.spec
@ -6,7 +6,7 @@
|
||||
|
||||
%define name libtpms
|
||||
%define versionx 0.7.3
|
||||
%define release 3
|
||||
%define release 4
|
||||
|
||||
# Valid crypto subsystems are 'freebl' and 'openssl'
|
||||
%if "%{?crypto_subsystem}" == ""
|
||||
@ -19,7 +19,7 @@
|
||||
Summary: Library providing Trusted Platform Module (TPM) functionality
|
||||
Name: %{name}
|
||||
Version: %{versionx}
|
||||
Release: 3
|
||||
Release: 4
|
||||
License: BSD
|
||||
Group: Development/Libraries
|
||||
Url: http://github.com/stefanberger/libtpms
|
||||
@ -27,6 +27,13 @@ Source0: %{url}/archive/%{gitcommit}/%{name}-%{gitshortcommit}.tar.gz
|
||||
Provides: libtpms-%{crypto_subsystem} = %{version}-%{release}
|
||||
|
||||
Patch0: 0001-tpm2-CryptSym-fix-AES-output-IV.patch
|
||||
Patch1: tpm2-Add-SEED_COMPAT_LEVEL-to-seeds-in.patch
|
||||
Patch2: tpm2-Add-SEED_COMPAT_LEVEL-to-nullSeed-to-track-comp.patch
|
||||
Patch3: tpm2-Add-SEED_COMPAT_LEVEL-to-DRBG-state.patch
|
||||
Patch4: tpm2-rev155-Add-new-RsaAdjustPrimeCandidate-code.patch
|
||||
Patch5: tpm2-Introduce-SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FI.patch
|
||||
Patch6: tpm2-Pass-SEED_COMPAT_LEVEL-to-CryptAdjustPrimeCandi.patch
|
||||
Patch7: tpm2-Activate-SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX.patch
|
||||
|
||||
%if "%{crypto_subsystem}" == "openssl"
|
||||
BuildRequires: openssl-devel
|
||||
@ -119,6 +126,12 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/libtpms.la
|
||||
%postun -p /sbin/ldconfig
|
||||
|
||||
%changelog
|
||||
* Tue May 11 2021 jiangfangjie <jiangfangjie@huawei.com> - 0.7.3-4
|
||||
-TYPE: CVE
|
||||
-ID:NA
|
||||
-SUG:NA
|
||||
-DESC:fix CVE-2021-3505
|
||||
|
||||
* Mon Apr 5 2021 jiangfangjie <jiangfangjie@huawei.com> - 0.7.3-3
|
||||
- Type:CVE
|
||||
- ID:NA
|
||||
|
||||
52
tpm2-Activate-SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX.patch
Normal file
52
tpm2-Activate-SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From eb36e429ebe6d0dd7e1ca07013245ab766eec02d Mon Sep 17 00:00:00 2001
|
||||
From: jiangfangjie 00559066 <jiangfangjie@huawei.com>
|
||||
Date: Tue, 11 May 2021 14:17:54 +0800
|
||||
Subject: [PATCH 7/7] tpm2: Activate SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX
|
||||
|
||||
---
|
||||
src/tpm2/BackwardsCompatibility.h | 2 +-
|
||||
src/tpm2/crypto/openssl/CryptPrime.c | 8 ++++----
|
||||
2 files changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/tpm2/BackwardsCompatibility.h b/src/tpm2/BackwardsCompatibility.h
|
||||
index ded6936..6d33b60 100644
|
||||
--- a/src/tpm2/BackwardsCompatibility.h
|
||||
+++ b/src/tpm2/BackwardsCompatibility.h
|
||||
@@ -43,7 +43,7 @@ typedef UINT8 SEED_COMPAT_LEVEL;
|
||||
enum {
|
||||
SEED_COMPAT_LEVEL_ORIGINAL = 0, /* original TPM 2 code up to rev155 */
|
||||
SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX = 1, /* RsaAdjustPrimeCandidate was fixed */
|
||||
- SEED_COMPAT_LEVEL_LAST = SEED_COMPAT_LEVEL_ORIGINAL
|
||||
+ SEED_COMPAT_LEVEL_LAST = SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX
|
||||
};
|
||||
|
||||
#endif /* BACKWARDS_COMPATIBILITY_H */
|
||||
diff --git a/src/tpm2/crypto/openssl/CryptPrime.c b/src/tpm2/crypto/openssl/CryptPrime.c
|
||||
index 2e8601c..9ffacc2 100644
|
||||
--- a/src/tpm2/crypto/openssl/CryptPrime.c
|
||||
+++ b/src/tpm2/crypto/openssl/CryptPrime.c
|
||||
@@ -369,8 +369,8 @@ RsaAdjustPrimeCandidate(
|
||||
case SEED_COMPAT_LEVEL_ORIGINAL:
|
||||
RsaAdjustPrimeCandidate_PreRev155(prime);
|
||||
break;
|
||||
- /* case SEED_COMPAT_LEVEL_LAST: */
|
||||
- case SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX:
|
||||
+ case SEED_COMPAT_LEVEL_LAST:
|
||||
+ /* case SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX: */
|
||||
RsaAdjustPrimeCandidate_New(prime);
|
||||
break;
|
||||
default:
|
||||
@@ -409,8 +409,8 @@ BnGeneratePrimeForRSA(
|
||||
if (g_inFailureMode)
|
||||
return;
|
||||
break;
|
||||
- /* case SEED_COMPAT_LEVEL_LAST: */
|
||||
- case SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX:
|
||||
+ case SEED_COMPAT_LEVEL_LAST:
|
||||
+ /* case SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX: */
|
||||
if(!BnGetRandomBits(prime, bits, rand)) // new
|
||||
return;
|
||||
break;
|
||||
--
|
||||
2.21.0.windows.1
|
||||
|
||||
143
tpm2-Add-SEED_COMPAT_LEVEL-to-DRBG-state.patch
Normal file
143
tpm2-Add-SEED_COMPAT_LEVEL-to-DRBG-state.patch
Normal file
@ -0,0 +1,143 @@
|
||||
From 8b534099d59ec5e746802dd77680612539945324 Mon Sep 17 00:00:00 2001
|
||||
From: jiangfangjie 00559066 <jiangfangjie@huawei.com>
|
||||
Date: Tue, 11 May 2021 11:32:08 +0800
|
||||
Subject: [PATCH 3/7] tpm2: Add SEED_COMPAT_LEVEL to DRBG state
|
||||
|
||||
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.
|
||||
---
|
||||
src/tpm2/HierarchyCommands.c | 3 ++-
|
||||
src/tpm2/ObjectCommands.c | 3 ++-
|
||||
src/tpm2/crypto/CryptRand.h | 1 +
|
||||
src/tpm2/crypto/CryptRand_fp.h | 9 ++++++++-
|
||||
src/tpm2/crypto/openssl/CryptRand.c | 26 +++++++++++++++++++++++++-
|
||||
5 files changed, 38 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/tpm2/HierarchyCommands.c b/src/tpm2/HierarchyCommands.c
|
||||
index 776d2e2..e757191 100644
|
||||
--- a/src/tpm2/HierarchyCommands.c
|
||||
+++ b/src/tpm2/HierarchyCommands.c
|
||||
@@ -103,7 +103,8 @@ TPM2_CreatePrimary(
|
||||
&HierarchyGetPrimarySeed(in->primaryHandle)->b,
|
||||
PRIMARY_OBJECT_CREATION,
|
||||
(TPM2B *)PublicMarshalAndComputeName(publicArea, &name),
|
||||
- &in->inSensitive.sensitive.data.b);
|
||||
+ &in->inSensitive.sensitive.data.b,
|
||||
+ HierarchyGetPrimarySeedCompatLevel(in->primaryHandle)); // libtpms added
|
||||
newObject->attributes.primary = SET;
|
||||
if(in->primaryHandle == TPM_RH_ENDORSEMENT)
|
||||
newObject->attributes.epsHierarchy = SET;
|
||||
diff --git a/src/tpm2/ObjectCommands.c b/src/tpm2/ObjectCommands.c
|
||||
index 590a702..26919eb 100644
|
||||
--- a/src/tpm2/ObjectCommands.c
|
||||
+++ b/src/tpm2/ObjectCommands.c
|
||||
@@ -508,7 +508,8 @@ TPM2_CreateLoaded(
|
||||
PRIMARY_OBJECT_CREATION,
|
||||
(TPM2B *)PublicMarshalAndComputeName(publicArea,
|
||||
&name),
|
||||
- &in->inSensitive.sensitive.data.b);
|
||||
+ &in->inSensitive.sensitive.data.b,
|
||||
+ HierarchyGetPrimarySeedCompatLevel(in->parentHandle)); // libtpms added
|
||||
}
|
||||
else
|
||||
// This is an ordinary object so use the normal random number generator
|
||||
diff --git a/src/tpm2/crypto/CryptRand.h b/src/tpm2/crypto/CryptRand.h
|
||||
index 3eaf986..c3947aa 100644
|
||||
--- a/src/tpm2/crypto/CryptRand.h
|
||||
+++ b/src/tpm2/crypto/CryptRand.h
|
||||
@@ -138,6 +138,7 @@ typedef union
|
||||
UINT64 reseedCounter;
|
||||
UINT32 magic;
|
||||
DRBG_SEED seed; // contains the key and IV for the counter mode DRBG
|
||||
+ SEED_COMPAT_LEVEL seedCompatLevel; // libtpms added: the compatibility level for keeping backwards compatibility
|
||||
UINT32 lastValue[4]; // used when the TPM does continuous self-test
|
||||
// for FIPS compliance of DRBG
|
||||
} DRBG_STATE, *pDRBG_STATE;
|
||||
diff --git a/src/tpm2/crypto/CryptRand_fp.h b/src/tpm2/crypto/CryptRand_fp.h
|
||||
index b10ee3d..9bf9209 100644
|
||||
--- a/src/tpm2/crypto/CryptRand_fp.h
|
||||
+++ b/src/tpm2/crypto/CryptRand_fp.h
|
||||
@@ -127,7 +127,8 @@ DRBG_InstantiateSeeded(
|
||||
const TPM2B *seed, // IN: the seed to use
|
||||
const TPM2B *purpose, // IN: a label for the generation process.
|
||||
const TPM2B *name, // IN: name of the object
|
||||
- const TPM2B *additional // IN: additional data
|
||||
+ const TPM2B *additional, // IN: additional data
|
||||
+ SEED_COMPAT_LEVEL seedCompatLevel// IN: compatibility level (associated with seed); libtpms added
|
||||
);
|
||||
LIB_EXPORT BOOL
|
||||
CryptRandStartup(
|
||||
@@ -143,6 +144,12 @@ DRBG_Generate(
|
||||
BYTE *random, // OUT: buffer to receive the random values
|
||||
UINT16 randomSize // IN: the number of bytes to generate
|
||||
);
|
||||
+// libtpms added begin
|
||||
+LIB_EXPORT SEED_COMPAT_LEVEL
|
||||
+DRBG_GetSeedCompatLevel(
|
||||
+ RAND_STATE *state // IN
|
||||
+ );
|
||||
+// libtpms added end
|
||||
LIB_EXPORT BOOL
|
||||
DRBG_Instantiate(
|
||||
DRBG_STATE *drbgState, // OUT: the instantiated value
|
||||
diff --git a/src/tpm2/crypto/openssl/CryptRand.c b/src/tpm2/crypto/openssl/CryptRand.c
|
||||
index 118e1c9..e5bca22 100644
|
||||
--- a/src/tpm2/crypto/openssl/CryptRand.c
|
||||
+++ b/src/tpm2/crypto/openssl/CryptRand.c
|
||||
@@ -589,7 +589,8 @@ DRBG_InstantiateSeeded(
|
||||
const TPM2B *seed, // IN: the seed to use
|
||||
const TPM2B *purpose, // IN: a label for the generation process.
|
||||
const TPM2B *name, // IN: name of the object
|
||||
- const TPM2B *additional // IN: additional data
|
||||
+ const TPM2B *additional, // IN: additional data
|
||||
+ SEED_COMPAT_LEVEL seedCompatLevel // IN: compatibility level; libtpms added
|
||||
)
|
||||
{
|
||||
DF_STATE dfState;
|
||||
@@ -600,6 +601,7 @@ DRBG_InstantiateSeeded(
|
||||
// Initialize the DRBG state
|
||||
memset(drbgState, 0, sizeof(DRBG_STATE));
|
||||
drbgState->magic = DRBG_MAGIC;
|
||||
+ drbgState->seedCompatLevel = seedCompatLevel; // libtpms added
|
||||
// Size all of the values
|
||||
totalInputSize = (seed != NULL) ? seed->size : 0;
|
||||
totalInputSize += (purpose != NULL) ? purpose->size : 0;
|
||||
@@ -655,6 +657,28 @@ CryptRandInit(
|
||||
#endif
|
||||
return DRBG_SelfTest();
|
||||
}
|
||||
+// libtpms added begin
|
||||
+LIB_EXPORT SEED_COMPAT_LEVEL
|
||||
+DRBG_GetSeedCompatLevel(
|
||||
+ RAND_STATE *state
|
||||
+ )
|
||||
+{
|
||||
+ if(state == NULL)
|
||||
+ {
|
||||
+ return SEED_COMPAT_LEVEL_LAST;
|
||||
+ }
|
||||
+ else if(state->drbg.magic == DRBG_MAGIC)
|
||||
+ {
|
||||
+ DRBG_STATE *drbgState = (DRBG_STATE *)state;
|
||||
+
|
||||
+ return drbgState->seedCompatLevel;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return SEED_COMPAT_LEVEL_LAST;
|
||||
+ }
|
||||
+}// libtpms added end
|
||||
+
|
||||
/* 10.2.18.5 DRBG_Generate() */
|
||||
/* This function generates a random sequence according SP800-90A. If random is not NULL, then
|
||||
randomSize bytes of random values are generated. If random is NULL or randomSize is zero, then
|
||||
--
|
||||
2.21.0.windows.1
|
||||
|
||||
110
tpm2-Add-SEED_COMPAT_LEVEL-to-nullSeed-to-track-comp.patch
Normal file
110
tpm2-Add-SEED_COMPAT_LEVEL-to-nullSeed-to-track-comp.patch
Normal file
@ -0,0 +1,110 @@
|
||||
From 6617eecb7ea815974a1cfc19f60a091f64c7ba30 Mon Sep 17 00:00:00 2001
|
||||
From: jiangfangjie 00559066 <jiangfangjie@huawei.com>
|
||||
Date: Tue, 11 May 2021 10:34:49 +0800
|
||||
Subject: [PATCH 2/7] tpm2: Add SEED_COMPAT_LEVEL to nullSeed to track
|
||||
compatibility level
|
||||
|
||||
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.
|
||||
---
|
||||
src/tpm2/Global.h | 1 +
|
||||
src/tpm2/Hierarchy.c | 3 ++-
|
||||
src/tpm2/NVMarshal.c | 21 ++++++++++++++++++---
|
||||
3 files changed, 21 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/tpm2/Global.h b/src/tpm2/Global.h
|
||||
index 011aff8..3448de3 100644
|
||||
--- a/src/tpm2/Global.h
|
||||
+++ b/src/tpm2/Global.h
|
||||
@@ -809,6 +809,7 @@ typedef struct state_reset_data
|
||||
// the TPM_RH_NULL hierarchy. The
|
||||
// default reset value is from the RNG.
|
||||
TPM2B_SEED nullSeed; // The seed value for the TPM_RN_NULL
|
||||
+ SEED_COMPAT_LEVEL nullSeedCompatLevel; // libtpms added
|
||||
// hierarchy. The default reset value
|
||||
// is from the RNG.
|
||||
//*****************************************************************************
|
||||
diff --git a/src/tpm2/Hierarchy.c b/src/tpm2/Hierarchy.c
|
||||
index 70a3588..e9e6d6d 100644
|
||||
--- a/src/tpm2/Hierarchy.c
|
||||
+++ b/src/tpm2/Hierarchy.c
|
||||
@@ -154,6 +154,7 @@ HierarchyStartup(
|
||||
CryptRandomGenerate(gr.nullProof.t.size, gr.nullProof.t.buffer);
|
||||
gr.nullSeed.t.size = sizeof(gr.nullSeed.t.buffer);
|
||||
CryptRandomGenerate(gr.nullSeed.t.size, gr.nullSeed.t.buffer);
|
||||
+ gr.nullSeedCompatLevel = SEED_COMPAT_LEVEL_LAST; // libtpms added
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -235,7 +236,7 @@ HierarchyGetPrimarySeedCompatLevel(
|
||||
return gp.EPSeedCompatLevel;
|
||||
break;
|
||||
case TPM_RH_NULL:
|
||||
- return SEED_COMPAT_LEVEL_LAST;
|
||||
+ return gr.nullSeedCompatLevel;
|
||||
default:
|
||||
FAIL(FATAL_ERROR_INTERNAL);
|
||||
break;
|
||||
diff --git a/src/tpm2/NVMarshal.c b/src/tpm2/NVMarshal.c
|
||||
index 653ef1a..5c1955b 100644
|
||||
--- a/src/tpm2/NVMarshal.c
|
||||
+++ b/src/tpm2/NVMarshal.c
|
||||
@@ -1235,7 +1235,7 @@ skip_future_versions:
|
||||
}
|
||||
|
||||
#define STATE_RESET_DATA_MAGIC 0x01102332
|
||||
-#define STATE_RESET_DATA_VERSION 2
|
||||
+#define STATE_RESET_DATA_VERSION 3
|
||||
|
||||
TPM_RC
|
||||
STATE_RESET_DATA_Unmarshal(STATE_RESET_DATA *data, BYTE **buffer, INT32 *size)
|
||||
@@ -1326,11 +1326,21 @@ STATE_RESET_DATA_Unmarshal(STATE_RESET_DATA *data, BYTE **buffer, INT32 *size)
|
||||
#endif
|
||||
skip_alg_ecc:
|
||||
|
||||
+ /* default values before conditional block */
|
||||
+ data->nullSeedCompatLevel = SEED_COMPAT_LEVEL_ORIGINAL;
|
||||
+
|
||||
/* version 2 starts having indicator for next versions that we can skip;
|
||||
this allows us to downgrade state */
|
||||
if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
|
||||
- BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
|
||||
+ BLOCK_SKIP_READ(skip_future_versions, hdr.version >= 3, buffer, size,
|
||||
"STATE_RESET_DATA", "version 3 or later");
|
||||
+ if (rc == TPM_RC_SUCCESS) {
|
||||
+ rc = SEED_COMPAT_LEVEL_Unmarshal(&gr.nullSeedCompatLevel,
|
||||
+ buffer, size, "nullSeed");
|
||||
+ }
|
||||
+
|
||||
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
|
||||
+ "STATE_RESET_DATA", "version 4 or later");
|
||||
/* future versions nest-append here */
|
||||
}
|
||||
|
||||
@@ -1349,7 +1359,7 @@ STATE_RESET_DATA_Marshal(STATE_RESET_DATA *data, BYTE **buffer, INT32 *size)
|
||||
|
||||
written = NV_HEADER_Marshal(buffer, size,
|
||||
STATE_RESET_DATA_VERSION,
|
||||
- STATE_RESET_DATA_MAGIC, 1);
|
||||
+ STATE_RESET_DATA_MAGIC, 3);
|
||||
written += TPM2B_PROOF_Marshal(&data->nullProof, buffer, size);
|
||||
written += TPM2B_Marshal(&data->nullSeed.b, buffer, size);
|
||||
written += UINT32_Marshal(&data->clearCount, buffer, size);
|
||||
@@ -1383,9 +1393,14 @@ STATE_RESET_DATA_Marshal(STATE_RESET_DATA *data, BYTE **buffer, INT32 *size)
|
||||
#endif
|
||||
BLOCK_SKIP_WRITE_POP(size);
|
||||
|
||||
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
|
||||
+ written += SEED_COMPAT_LEVEL_Marshal(&data->nullSeedCompatLevel,
|
||||
+ buffer, size);
|
||||
+
|
||||
written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
|
||||
/* future versions append below this line */
|
||||
|
||||
+ BLOCK_SKIP_WRITE_POP(size);
|
||||
BLOCK_SKIP_WRITE_POP(size);
|
||||
|
||||
BLOCK_SKIP_WRITE_CHECK;
|
||||
--
|
||||
2.21.0.windows.1
|
||||
|
||||
346
tpm2-Add-SEED_COMPAT_LEVEL-to-seeds-in.patch
Normal file
346
tpm2-Add-SEED_COMPAT_LEVEL-to-seeds-in.patch
Normal file
@ -0,0 +1,346 @@
|
||||
From 2833825447cbc0b23c1aa13a15521aa1d0ec0175 Mon Sep 17 00:00:00 2001
|
||||
From: jiangfangjie 00559066 <jiangfangjie@huawei.com>
|
||||
Date: Tue, 11 May 2021 10:32:16 +0800
|
||||
Subject: [PATCH 1/7] tpm2: Add SEED_COMPAT_LEVEL to seeds in PERSISTENT_DATA
|
||||
|
||||
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.
|
||||
---
|
||||
src/Makefile.am | 1 +
|
||||
src/tpm2/BackwardsCompatibility.h | 48 +++++++++++++++++++++++++
|
||||
src/tpm2/Global.h | 5 +++
|
||||
src/tpm2/Hierarchy.c | 31 ++++++++++++++++
|
||||
src/tpm2/HierarchyCommands.c | 5 +++
|
||||
src/tpm2/Hierarchy_fp.h | 6 ++++
|
||||
src/tpm2/NVMarshal.c | 59 +++++++++++++++++++++++++++++--
|
||||
7 files changed, 152 insertions(+), 3 deletions(-)
|
||||
create mode 100644 src/tpm2/BackwardsCompatibility.h
|
||||
|
||||
diff --git a/src/Makefile.am b/src/Makefile.am
|
||||
index 670afbf..e18ba4d 100644
|
||||
--- a/src/Makefile.am
|
||||
+++ b/src/Makefile.am
|
||||
@@ -482,6 +482,7 @@ noinst_HEADERS += \
|
||||
tpm2/VerifySignature_fp.h \
|
||||
tpm2/ZGen_2Phase_fp.h \
|
||||
\
|
||||
+ tpm2/BackwardsCompatibility.h \
|
||||
tpm2/LibtpmsCallbacks.h \
|
||||
tpm2/NVMarshal.h \
|
||||
tpm2/StateMarshal.h \
|
||||
diff --git a/src/tpm2/BackwardsCompatibility.h b/src/tpm2/BackwardsCompatibility.h
|
||||
new file mode 100644
|
||||
index 0000000..aa79763
|
||||
--- /dev/null
|
||||
+++ b/src/tpm2/BackwardsCompatibility.h
|
||||
@@ -0,0 +1,48 @@
|
||||
+/********************************************************************************/
|
||||
+/* */
|
||||
+/* Backwards compatibility related stuff */
|
||||
+/* Written by Stefan Berger */
|
||||
+/* IBM Thomas J. Watson Research Center */
|
||||
+/* */
|
||||
+/* (c) Copyright IBM Corporation 2017,2018. */
|
||||
+/* */
|
||||
+/* All rights reserved. */
|
||||
+/* */
|
||||
+/* Redistribution and use in source and binary forms, with or without */
|
||||
+/* modification, are permitted provided that the following conditions are */
|
||||
+/* met: */
|
||||
+/* */
|
||||
+/* Redistributions of source code must retain the above copyright notice, */
|
||||
+/* this list of conditions and the following disclaimer. */
|
||||
+/* */
|
||||
+/* Redistributions in binary form must reproduce the above copyright */
|
||||
+/* notice, this list of conditions and the following disclaimer in the */
|
||||
+/* documentation and/or other materials provided with the distribution. */
|
||||
+/* */
|
||||
+/* Neither the names of the IBM Corporation nor the names of its */
|
||||
+/* contributors may be used to endorse or promote products derived from */
|
||||
+/* this software without specific prior written permission. */
|
||||
+/* */
|
||||
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
|
||||
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
|
||||
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
|
||||
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
|
||||
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
|
||||
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
|
||||
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
|
||||
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
|
||||
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
|
||||
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
|
||||
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||||
+/********************************************************************************/
|
||||
+
|
||||
+#ifndef BACKWARDS_COMPATIBILITY_H
|
||||
+#define BACKWARDS_COMPATIBILITY_H
|
||||
+
|
||||
+typedef UINT8 SEED_COMPAT_LEVEL;
|
||||
+enum {
|
||||
+ SEED_COMPAT_LEVEL_ORIGINAL = 0, /* original TPM 2 code up to rev155 */
|
||||
+ SEED_COMPAT_LEVEL_LAST = SEED_COMPAT_LEVEL_ORIGINAL
|
||||
+};
|
||||
+
|
||||
+#endif /* BACKWARDS_COMPATIBILITY_H */
|
||||
diff --git a/src/tpm2/Global.h b/src/tpm2/Global.h
|
||||
index 7a215cb..011aff8 100644
|
||||
--- a/src/tpm2/Global.h
|
||||
+++ b/src/tpm2/Global.h
|
||||
@@ -76,6 +76,7 @@ _NORMAL_WARNING_LEVEL_
|
||||
#undef CONTEXT_SLOT
|
||||
# define CONTEXT_SLOT UINT8
|
||||
#endif
|
||||
+#include "BackwardsCompatibility.h" // libtpms added
|
||||
#include "Capabilities.h"
|
||||
#include "TpmTypes.h"
|
||||
#include "CommandAttributes.h"
|
||||
@@ -619,6 +620,10 @@ typedef struct
|
||||
TPM2B_SEED EPSeed;
|
||||
TPM2B_SEED SPSeed;
|
||||
TPM2B_SEED PPSeed;
|
||||
+ // SEED_COMPAT_LEVELs related to creation time of seeds
|
||||
+ SEED_COMPAT_LEVEL EPSeedCompatLevel; // libtpms added begin
|
||||
+ SEED_COMPAT_LEVEL SPSeedCompatLevel;
|
||||
+ SEED_COMPAT_LEVEL PPSeedCompatLevel; // libtpms added end
|
||||
// Note there is a nullSeed in the state_reset memory.
|
||||
// Hierarchy proofs
|
||||
TPM2B_PROOF phProof;
|
||||
diff --git a/src/tpm2/Hierarchy.c b/src/tpm2/Hierarchy.c
|
||||
index 798c037..70a3588 100644
|
||||
--- a/src/tpm2/Hierarchy.c
|
||||
+++ b/src/tpm2/Hierarchy.c
|
||||
@@ -86,6 +86,9 @@ HierarchyPreInstall_Init(
|
||||
#endif
|
||||
CryptRandomGenerate(gp.SPSeed.t.size, gp.SPSeed.t.buffer);
|
||||
CryptRandomGenerate(gp.PPSeed.t.size, gp.PPSeed.t.buffer);
|
||||
+ gp.EPSeedCompatLevel = SEED_COMPAT_LEVEL_LAST; // libtpms added begin
|
||||
+ gp.SPSeedCompatLevel = SEED_COMPAT_LEVEL_LAST;
|
||||
+ gp.PPSeedCompatLevel = SEED_COMPAT_LEVEL_LAST; // libtpms added end
|
||||
// Initialize owner, endorsement and lockout authorization
|
||||
gp.ownerAuth.t.size = 0;
|
||||
gp.endorsementAuth.t.size = 0;
|
||||
@@ -109,6 +112,9 @@ HierarchyPreInstall_Init(
|
||||
NV_SYNC_PERSISTENT(EPSeed);
|
||||
NV_SYNC_PERSISTENT(SPSeed);
|
||||
NV_SYNC_PERSISTENT(PPSeed);
|
||||
+ NV_SYNC_PERSISTENT(EPSeedCompatLevel); // libtpms added begin
|
||||
+ NV_SYNC_PERSISTENT(SPSeedCompatLevel);
|
||||
+ NV_SYNC_PERSISTENT(PPSeedCompatLevel); // libtpms added end
|
||||
NV_SYNC_PERSISTENT(ownerAuth);
|
||||
NV_SYNC_PERSISTENT(endorsementAuth);
|
||||
NV_SYNC_PERSISTENT(lockoutAuth);
|
||||
@@ -211,6 +217,31 @@ HierarchyGetPrimarySeed(
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
+// libtpms added begin
|
||||
+SEED_COMPAT_LEVEL
|
||||
+HierarchyGetPrimarySeedCompatLevel(
|
||||
+ TPMI_RH_HIERARCHY hierarchy // IN: hierarchy
|
||||
+ )
|
||||
+{
|
||||
+ switch(hierarchy)
|
||||
+ {
|
||||
+ case TPM_RH_PLATFORM:
|
||||
+ return gp.PPSeedCompatLevel;
|
||||
+ break;
|
||||
+ case TPM_RH_OWNER:
|
||||
+ return gp.SPSeedCompatLevel;
|
||||
+ break;
|
||||
+ case TPM_RH_ENDORSEMENT:
|
||||
+ return gp.EPSeedCompatLevel;
|
||||
+ break;
|
||||
+ case TPM_RH_NULL:
|
||||
+ return SEED_COMPAT_LEVEL_LAST;
|
||||
+ default:
|
||||
+ FAIL(FATAL_ERROR_INTERNAL);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+// libtpms added end
|
||||
/* 8.3.3.5 HierarchyIsEnabled() */
|
||||
/* This function checks to see if a hierarchy is enabled. */
|
||||
/* NOTE: The TPM_RH_NULL hierarchy is always enabled. */
|
||||
diff --git a/src/tpm2/HierarchyCommands.c b/src/tpm2/HierarchyCommands.c
|
||||
index 6627e99..776d2e2 100644
|
||||
--- a/src/tpm2/HierarchyCommands.c
|
||||
+++ b/src/tpm2/HierarchyCommands.c
|
||||
@@ -291,6 +291,7 @@ TPM2_ChangePPS(
|
||||
// Internal Data Update
|
||||
// Reset platform hierarchy seed from RNG
|
||||
CryptRandomGenerate(sizeof(gp.PPSeed.t.buffer), gp.PPSeed.t.buffer);
|
||||
+ gp.PPSeedCompatLevel = SEED_COMPAT_LEVEL_LAST; // libtpms added
|
||||
// Create a new phProof value from RNG to prevent the saved platform
|
||||
// hierarchy contexts being loaded
|
||||
CryptRandomGenerate(sizeof(gp.phProof.t.buffer), gp.phProof.t.buffer);
|
||||
@@ -303,6 +304,7 @@ TPM2_ChangePPS(
|
||||
NvFlushHierarchy(TPM_RH_PLATFORM);
|
||||
// Save hierarchy changes to NV
|
||||
NV_SYNC_PERSISTENT(PPSeed);
|
||||
+ NV_SYNC_PERSISTENT(PPSeedCompatLevel); // libtpms added
|
||||
NV_SYNC_PERSISTENT(phProof);
|
||||
// Re-initialize PCR policies
|
||||
#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
|
||||
@@ -335,6 +337,7 @@ TPM2_ChangeEPS(
|
||||
// Internal Data Update
|
||||
// Reset endorsement hierarchy seed from RNG
|
||||
CryptRandomGenerate(sizeof(gp.EPSeed.t.buffer), gp.EPSeed.t.buffer);
|
||||
+ gp.EPSeedCompatLevel = SEED_COMPAT_LEVEL_LAST; // libtpms added
|
||||
// Create new ehProof value from RNG
|
||||
CryptRandomGenerate(sizeof(gp.ehProof.t.buffer), gp.ehProof.t.buffer);
|
||||
// Enable endorsement hierarchy
|
||||
@@ -352,6 +355,7 @@ TPM2_ChangeEPS(
|
||||
NvFlushHierarchy(TPM_RH_ENDORSEMENT);
|
||||
// Save hierarchy changes to NV
|
||||
NV_SYNC_PERSISTENT(EPSeed);
|
||||
+ NV_SYNC_PERSISTENT(EPSeedCompatLevel); // libtpms added
|
||||
NV_SYNC_PERSISTENT(ehProof);
|
||||
NV_SYNC_PERSISTENT(endorsementAuth);
|
||||
NV_SYNC_PERSISTENT(endorsementAlg);
|
||||
@@ -382,6 +386,7 @@ TPM2_Clear(
|
||||
// Internal Data Update
|
||||
// Reset storage hierarchy seed from RNG
|
||||
CryptRandomGenerate(sizeof(gp.SPSeed.t.buffer), gp.SPSeed.t.buffer);
|
||||
+ gp.SPSeedCompatLevel = SEED_COMPAT_LEVEL_LAST; // libtpms added
|
||||
// Create new shProof and ehProof value from RNG
|
||||
CryptRandomGenerate(sizeof(gp.shProof.t.buffer), gp.shProof.t.buffer);
|
||||
CryptRandomGenerate(sizeof(gp.ehProof.t.buffer), gp.ehProof.t.buffer);
|
||||
diff --git a/src/tpm2/Hierarchy_fp.h b/src/tpm2/Hierarchy_fp.h
|
||||
index 51c79c0..d6e0a89 100644
|
||||
--- a/src/tpm2/Hierarchy_fp.h
|
||||
+++ b/src/tpm2/Hierarchy_fp.h
|
||||
@@ -78,6 +78,12 @@ TPM2B_SEED *
|
||||
HierarchyGetPrimarySeed(
|
||||
TPMI_RH_HIERARCHY hierarchy // IN: hierarchy
|
||||
);
|
||||
+// libtpms added begin
|
||||
+SEED_COMPAT_LEVEL
|
||||
+HierarchyGetPrimarySeedCompatLevel(
|
||||
+ TPMI_RH_HIERARCHY hierarchy // IN: hierarchy
|
||||
+ );
|
||||
+// libtpms added end
|
||||
BOOL
|
||||
HierarchyIsEnabled(
|
||||
TPMI_RH_HIERARCHY hierarchy // IN: hierarchy
|
||||
diff --git a/src/tpm2/NVMarshal.c b/src/tpm2/NVMarshal.c
|
||||
index ec94ebf..653ef1a 100644
|
||||
--- a/src/tpm2/NVMarshal.c
|
||||
+++ b/src/tpm2/NVMarshal.c
|
||||
@@ -242,6 +242,29 @@ BOOL_Unmarshal(BOOL *boolean, BYTE **buffer, INT32 *size)
|
||||
return rc;
|
||||
}
|
||||
|
||||
+static UINT16
|
||||
+SEED_COMPAT_LEVEL_Marshal(SEED_COMPAT_LEVEL *source,
|
||||
+ BYTE **buffer, INT32 *size)
|
||||
+{
|
||||
+ return UINT8_Marshal((UINT8 *)source, buffer, size);
|
||||
+}
|
||||
+
|
||||
+static TPM_RC
|
||||
+SEED_COMPAT_LEVEL_Unmarshal(SEED_COMPAT_LEVEL *source,
|
||||
+ BYTE **buffer, INT32 *size,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ TPM_RC rc;
|
||||
+
|
||||
+ rc = UINT8_Unmarshal((UINT8 *)source, buffer, size);
|
||||
+ if (rc == TPM_RC_SUCCESS && *source > SEED_COMPAT_LEVEL_LAST) {
|
||||
+ TPMLIB_LogTPM2Error("%s compatLevel '%u' higher than supported '%u'\n",
|
||||
+ name, *source, SEED_COMPAT_LEVEL_LAST);
|
||||
+ rc = TPM_RC_BAD_VERSION;
|
||||
+ }
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
TPM2B_Cmp(const TPM2B *t1, const TPM2B *t2)
|
||||
{
|
||||
@@ -3690,7 +3713,7 @@ skip_future_versions:
|
||||
}
|
||||
|
||||
#define PERSISTENT_DATA_MAGIC 0x12213443
|
||||
-#define PERSISTENT_DATA_VERSION 3
|
||||
+#define PERSISTENT_DATA_VERSION 4
|
||||
|
||||
static UINT16
|
||||
PERSISTENT_DATA_Marshal(PERSISTENT_DATA *data, BYTE **buffer, INT32 *size)
|
||||
@@ -3703,7 +3726,7 @@ PERSISTENT_DATA_Marshal(PERSISTENT_DATA *data, BYTE **buffer, INT32 *size)
|
||||
|
||||
written = NV_HEADER_Marshal(buffer, size,
|
||||
PERSISTENT_DATA_VERSION,
|
||||
- PERSISTENT_DATA_MAGIC, 1);
|
||||
+ PERSISTENT_DATA_MAGIC, 4);
|
||||
written += BOOL_Marshal(&data->disableClear, buffer, size);
|
||||
written += TPM_ALG_ID_Marshal(&data->ownerAlg, buffer, size);
|
||||
written += TPM_ALG_ID_Marshal(&data->endorsementAlg, buffer, size);
|
||||
@@ -3775,9 +3798,18 @@ PERSISTENT_DATA_Marshal(PERSISTENT_DATA *data, BYTE **buffer, INT32 *size)
|
||||
/* there's a 'shadow' pcrAllocated as well */
|
||||
written += TPML_PCR_SELECTION_Marshal(&gp.pcrAllocated, buffer, size);
|
||||
|
||||
+ written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
|
||||
+ written += SEED_COMPAT_LEVEL_Marshal(&data->EPSeedCompatLevel,
|
||||
+ buffer, size);
|
||||
+ written += SEED_COMPAT_LEVEL_Marshal(&data->SPSeedCompatLevel,
|
||||
+ buffer, size);
|
||||
+ written += SEED_COMPAT_LEVEL_Marshal(&data->PPSeedCompatLevel,
|
||||
+ buffer, size);
|
||||
+
|
||||
written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
|
||||
/* future versions append below this line */
|
||||
|
||||
+ BLOCK_SKIP_WRITE_POP(size);
|
||||
BLOCK_SKIP_WRITE_POP(size);
|
||||
BLOCK_SKIP_WRITE_POP(size);
|
||||
|
||||
@@ -3963,6 +3995,11 @@ skip_num_policy_pcr_group:
|
||||
#endif
|
||||
}
|
||||
|
||||
+ /* default values before conditional block */
|
||||
+ data->EPSeedCompatLevel = SEED_COMPAT_LEVEL_ORIGINAL;
|
||||
+ data->SPSeedCompatLevel = SEED_COMPAT_LEVEL_ORIGINAL;
|
||||
+ data->PPSeedCompatLevel = SEED_COMPAT_LEVEL_ORIGINAL;
|
||||
+
|
||||
/* version 2 starts having indicator for next versions that we can skip;
|
||||
this allows us to downgrade state */
|
||||
if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
|
||||
@@ -3970,8 +4007,24 @@ skip_num_policy_pcr_group:
|
||||
"Volatile State", "version 3 or later");
|
||||
rc = TPML_PCR_SELECTION_Unmarshal(&shadow.pcrAllocated, buffer, size);
|
||||
|
||||
- BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
|
||||
+ BLOCK_SKIP_READ(skip_future_versions, hdr.version >= 4, buffer, size,
|
||||
"PERSISTENT DATA", "version 4 or later");
|
||||
+
|
||||
+ if (rc == TPM_RC_SUCCESS) {
|
||||
+ rc = SEED_COMPAT_LEVEL_Unmarshal(&data->EPSeedCompatLevel,
|
||||
+ buffer, size, "EPSeed");
|
||||
+ }
|
||||
+ if (rc == TPM_RC_SUCCESS) {
|
||||
+ rc = SEED_COMPAT_LEVEL_Unmarshal(&data->SPSeedCompatLevel,
|
||||
+ buffer, size, "SPSeed");
|
||||
+ }
|
||||
+ if (rc == TPM_RC_SUCCESS) {
|
||||
+ rc = SEED_COMPAT_LEVEL_Unmarshal(&data->PPSeedCompatLevel,
|
||||
+ buffer, size, "PPSeed");
|
||||
+ }
|
||||
+
|
||||
+ BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
|
||||
+ "PERSISTENT DATA", "version 5 or later");
|
||||
/* future versions nest-append here */
|
||||
}
|
||||
|
||||
--
|
||||
2.21.0.windows.1
|
||||
|
||||
25
tpm2-Introduce-SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FI.patch
Normal file
25
tpm2-Introduce-SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FI.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From 087e54dcc99a36151677581eda92c321907988d9 Mon Sep 17 00:00:00 2001
|
||||
From: jiangfangjie 00559066 <jiangfangjie@huawei.com>
|
||||
Date: Tue, 11 May 2021 14:12:37 +0800
|
||||
Subject: [PATCH 5/7] tpm2: Introduce SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX
|
||||
but do not use yet
|
||||
|
||||
---
|
||||
src/tpm2/BackwardsCompatibility.h | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/tpm2/BackwardsCompatibility.h b/src/tpm2/BackwardsCompatibility.h
|
||||
index aa79763..ded6936 100644
|
||||
--- a/src/tpm2/BackwardsCompatibility.h
|
||||
+++ b/src/tpm2/BackwardsCompatibility.h
|
||||
@@ -42,6 +42,7 @@
|
||||
typedef UINT8 SEED_COMPAT_LEVEL;
|
||||
enum {
|
||||
SEED_COMPAT_LEVEL_ORIGINAL = 0, /* original TPM 2 code up to rev155 */
|
||||
+ SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX = 1, /* RsaAdjustPrimeCandidate was fixed */
|
||||
SEED_COMPAT_LEVEL_LAST = SEED_COMPAT_LEVEL_ORIGINAL
|
||||
};
|
||||
|
||||
--
|
||||
2.21.0.windows.1
|
||||
|
||||
85
tpm2-Pass-SEED_COMPAT_LEVEL-to-CryptAdjustPrimeCandi.patch
Normal file
85
tpm2-Pass-SEED_COMPAT_LEVEL-to-CryptAdjustPrimeCandi.patch
Normal file
@ -0,0 +1,85 @@
|
||||
From 5ffbddedaedc3215da219d35dc3f95b1c52ef393 Mon Sep 17 00:00:00 2001
|
||||
From: jiangfangjie 00559066 <jiangfangjie@huawei.com>
|
||||
Date: Tue, 11 May 2021 14:15:09 +0800
|
||||
Subject: [PATCH 6/7] tpm2: Pass SEED_COMPAT_LEVEL to CryptAdjustPrimeCandidate
|
||||
function
|
||||
|
||||
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.
|
||||
---
|
||||
src/tpm2/crypto/CryptPrime_fp.h | 3 ++-
|
||||
src/tpm2/crypto/openssl/CryptPrime.c | 26 ++++++++++++++++++++------
|
||||
2 files changed, 22 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/tpm2/crypto/CryptPrime_fp.h b/src/tpm2/crypto/CryptPrime_fp.h
|
||||
index 8cd23f5..e8ac8b8 100644
|
||||
--- a/src/tpm2/crypto/CryptPrime_fp.h
|
||||
+++ b/src/tpm2/crypto/CryptPrime_fp.h
|
||||
@@ -89,7 +89,8 @@ RsaCheckPrime(
|
||||
);
|
||||
LIB_EXPORT void
|
||||
RsaAdjustPrimeCandidate(
|
||||
- bigNum prime
|
||||
+ bigNum prime,
|
||||
+ SEED_COMPAT_LEVEL seedCompatLevel // IN: compatibility level; libtpms added
|
||||
);
|
||||
void
|
||||
BnGeneratePrimeForRSA(
|
||||
diff --git a/src/tpm2/crypto/openssl/CryptPrime.c b/src/tpm2/crypto/openssl/CryptPrime.c
|
||||
index 9a5ee7d..2e8601c 100644
|
||||
--- a/src/tpm2/crypto/openssl/CryptPrime.c
|
||||
+++ b/src/tpm2/crypto/openssl/CryptPrime.c
|
||||
@@ -361,13 +361,21 @@ RsaAdjustPrimeCandidate_New(
|
||||
}
|
||||
LIB_EXPORT void
|
||||
RsaAdjustPrimeCandidate(
|
||||
- bigNum prime
|
||||
+ bigNum prime,
|
||||
+ SEED_COMPAT_LEVEL seedCompatLevel // IN: compatibility level; libtpms added
|
||||
)
|
||||
{
|
||||
- if (1)
|
||||
+ switch (seedCompatLevel) {
|
||||
+ case SEED_COMPAT_LEVEL_ORIGINAL:
|
||||
RsaAdjustPrimeCandidate_PreRev155(prime);
|
||||
- else
|
||||
+ break;
|
||||
+ /* case SEED_COMPAT_LEVEL_LAST: */
|
||||
+ case SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX:
|
||||
RsaAdjustPrimeCandidate_New(prime);
|
||||
+ break;
|
||||
+ default:
|
||||
+ FAIL(FATAL_ERROR_INTERNAL);
|
||||
+ }
|
||||
}
|
||||
/* 10.2.14.1.8 BnGeneratePrimeForRSA() */
|
||||
|
||||
@@ -395,15 +403,21 @@ BnGeneratePrimeForRSA(
|
||||
// DRBG_Generate(rand, (BYTE *)prime->d, (UINT16)BITS_TO_BYTES(bits));// old
|
||||
// if(g_inFailureMode) // old
|
||||
// libtpms changed begin
|
||||
- if (1) {
|
||||
+ switch (DRBG_GetSeedCompatLevel(rand)) {
|
||||
+ case SEED_COMPAT_LEVEL_ORIGINAL:
|
||||
DRBG_Generate(rand, (BYTE *)prime->d, (UINT16)BITS_TO_BYTES(bits));
|
||||
if (g_inFailureMode)
|
||||
return;
|
||||
- } else {
|
||||
+ break;
|
||||
+ /* case SEED_COMPAT_LEVEL_LAST: */
|
||||
+ case SEED_COMPAT_LEVEL_RSA_PRIME_ADJUST_FIX:
|
||||
if(!BnGetRandomBits(prime, bits, rand)) // new
|
||||
return;
|
||||
+ break;
|
||||
+ default:
|
||||
+ FAIL(FATAL_ERROR_INTERNAL);
|
||||
}
|
||||
- RsaAdjustPrimeCandidate(prime);
|
||||
+ RsaAdjustPrimeCandidate(prime, DRBG_GetSeedCompatLevel(rand));
|
||||
// libtpms changed end
|
||||
found = RsaCheckPrime(prime, exponent, rand) == TPM_RC_SUCCESS;
|
||||
}
|
||||
--
|
||||
2.21.0.windows.1
|
||||
|
||||
172
tpm2-rev155-Add-new-RsaAdjustPrimeCandidate-code.patch
Normal file
172
tpm2-rev155-Add-new-RsaAdjustPrimeCandidate-code.patch
Normal file
@ -0,0 +1,172 @@
|
||||
From b4ff6345a6b1533f907ed1922d884acae62d2501 Mon Sep 17 00:00:00 2001
|
||||
From: jiangfangjie 00559066 <jiangfangjie@huawei.com>
|
||||
Date: Tue, 11 May 2021 11:52:44 +0800
|
||||
Subject: [PATCH 4/7] tpm2: rev155: Add new RsaAdjustPrimeCandidate code but
|
||||
do not use
|
||||
|
||||
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.
|
||||
---
|
||||
src/tpm2/crypto/openssl/CryptPrime.c | 110 ++++++++++++++++++++++-----
|
||||
1 file changed, 89 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/src/tpm2/crypto/openssl/CryptPrime.c b/src/tpm2/crypto/openssl/CryptPrime.c
|
||||
index 662c762..9a5ee7d 100644
|
||||
--- a/src/tpm2/crypto/openssl/CryptPrime.c
|
||||
+++ b/src/tpm2/crypto/openssl/CryptPrime.c
|
||||
@@ -3,7 +3,7 @@
|
||||
/* Code for prime validation. */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
-/* $Id: CryptPrime.c 1262 2018-07-11 21:03:43Z kgoldman $ */
|
||||
+/* $Id: CryptPrime.c 1476 2019-06-10 19:32:03Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@@ -55,7 +55,7 @@
|
||||
/* arising in any way out of use or reliance upon this specification or any */
|
||||
/* information herein. */
|
||||
/* */
|
||||
-/* (c) Copyright IBM Corp. and others, 2016 - 2018 */
|
||||
+/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@@ -292,19 +292,14 @@ RsaCheckPrime(
|
||||
return PrimeSelectWithSieve(prime, exponent, rand);
|
||||
#endif
|
||||
}
|
||||
-/* 10.2.16.1.7 AdjustPrimeCandiate() */
|
||||
-/* This function adjusts the candidate prime so that it is odd and > root(2)/2. This allows the
|
||||
- product of these two numbers to be .5, which, in fixed point notation means that the most
|
||||
- significant bit is 1. For this routine, the root(2)/2 is approximated with 0xB505 which is, in
|
||||
- fixed point is 0.7071075439453125 or an error of 0.0001%. Just setting the upper two bits would
|
||||
- give a value > 0.75 which is an error of > 6%. Given the amount of time all the other
|
||||
- computations take, reducing the error is not much of a cost, but it isn't totally required
|
||||
- either. */
|
||||
-/* The function also puts the number on a field boundary. */
|
||||
-LIB_EXPORT void
|
||||
-RsaAdjustPrimeCandidate(
|
||||
- bigNum prime
|
||||
- )
|
||||
+/*
|
||||
+ * RsaAdjustPrimeCandidate_PreRev155 is the pre-rev.155 algorithm used; we
|
||||
+ * still have to use it for old seeds to maintain backwards compatibility.
|
||||
+ */
|
||||
+static void
|
||||
+RsaAdjustPrimeCandidate_PreRev155(
|
||||
+ bigNum prime
|
||||
+ )
|
||||
{
|
||||
UINT16 highBytes;
|
||||
crypt_uword_t *msw = &prime->d[prime->size - 1];
|
||||
@@ -316,14 +311,74 @@ RsaAdjustPrimeCandidate(
|
||||
*msw = ((crypt_uword_t)(highBytes) << (RADIX_BITS - 16)) + (*msw & MASK);
|
||||
prime->d[0] |= 1;
|
||||
}
|
||||
-/* 10.2.16.1.8 BnGeneratePrimeForRSA() */
|
||||
+
|
||||
+/* 10.2.14.1.7 RsaAdjustPrimeCandidate() */
|
||||
+
|
||||
+/* For this math, we assume that the RSA numbers are fixed-point numbers with the decimal point to
|
||||
+ the left of the most significant bit. This approach helps make it clear what is happening with
|
||||
+ the MSb of the values. The two RSA primes have to be large enough so that their product will be a
|
||||
+ number with the necessary number of significant bits. For example, we want to be able to multiply
|
||||
+ two 1024-bit numbers to produce a number with 2028 significant bits. If we accept any 1024-bit
|
||||
+ prime that has its MSb set, then it is possible to produce a product that does not have the MSb
|
||||
+ SET. For example, if we use tiny keys of 16 bits and have two 8-bit primes of 0x80, then the
|
||||
+ public key would be 0x4000 which is only 15-bits. So, what we need to do is made sure that each
|
||||
+ of the primes is large enough so that the product of the primes is twice as large as each
|
||||
+ prime. A little arithmetic will show that the only way to do this is to make sure that each of
|
||||
+ the primes is no less than root(2)/2. That's what this functions does. This function adjusts the
|
||||
+ candidate prime so that it is odd and >= root(2)/2. This allows the product of these two numbers
|
||||
+ to be .5, which, in fixed point notation means that the most significant bit is 1. For this
|
||||
+ routine, the root(2)/2 (0.7071067811865475) approximated with 0xB505 which is, in fixed point,
|
||||
+ 0.7071075439453125 or an error of 0.000108%. Just setting the upper two bits would give a value >
|
||||
+ 0.75 which is an error of > 6%. Given the amount of time all the other computations take,
|
||||
+ reducing the error is not much of a cost, but it isn't totally required either. */
|
||||
+/* This function can be replaced with a function that just sets the two most significant bits of
|
||||
+ each prime candidate without introducing any computational issues. */
|
||||
+
|
||||
+static void
|
||||
+RsaAdjustPrimeCandidate_New(
|
||||
+ bigNum prime
|
||||
+ )
|
||||
+{
|
||||
+ UINT32 msw;
|
||||
+ UINT32 adjusted;
|
||||
+
|
||||
+ // If the radix is 32, the compiler should turn this into a simple assignment
|
||||
+ msw = prime->d[prime->size - 1] >> ((RADIX_BITS == 64) ? 32 : 0);
|
||||
+ // Multiplying 0xff...f by 0x4AFB gives 0xff..f - 0xB5050...0
|
||||
+ adjusted = (msw >> 16) * 0x4AFB;
|
||||
+ adjusted += ((msw & 0xFFFF) * 0x4AFB) >> 16;
|
||||
+ adjusted += 0xB5050000UL;
|
||||
+#if RADIX_BITS == 64
|
||||
+ // Save the low-order 32 bits
|
||||
+ prime->d[prime->size - 1] &= 0xFFFFFFFFUL;
|
||||
+ // replace the upper 32-bits
|
||||
+ prime->d[prime->size -1] |= ((crypt_uword_t)adjusted << 32);
|
||||
+#else
|
||||
+ prime->d[prime->size - 1] = (crypt_uword_t)adjusted;
|
||||
+#endif
|
||||
+ // make sure the number is odd
|
||||
+ prime->d[0] |= 1;
|
||||
+}
|
||||
+LIB_EXPORT void
|
||||
+RsaAdjustPrimeCandidate(
|
||||
+ bigNum prime
|
||||
+ )
|
||||
+{
|
||||
+ if (1)
|
||||
+ RsaAdjustPrimeCandidate_PreRev155(prime);
|
||||
+ else
|
||||
+ RsaAdjustPrimeCandidate_New(prime);
|
||||
+}
|
||||
+/* 10.2.14.1.8 BnGeneratePrimeForRSA() */
|
||||
+
|
||||
/* Function to generate a prime of the desired size with the proper attributes for an RSA prime. */
|
||||
void
|
||||
BnGeneratePrimeForRSA(
|
||||
- bigNum prime,
|
||||
- UINT32 bits,
|
||||
- UINT32 exponent,
|
||||
- RAND_STATE *rand
|
||||
+ bigNum prime, // IN/OUT: points to the BN that will get the
|
||||
+ // random value
|
||||
+ UINT32 bits, // IN: number of bits to get
|
||||
+ UINT32 exponent, // IN: the exponent
|
||||
+ RAND_STATE *rand // IN: the random state
|
||||
)
|
||||
{
|
||||
BOOL found = FALSE;
|
||||
@@ -335,8 +390,21 @@ BnGeneratePrimeForRSA(
|
||||
prime->size = BITS_TO_CRYPT_WORDS(bits);
|
||||
while(!found)
|
||||
{
|
||||
- DRBG_Generate(rand, (BYTE *)prime->d, (UINT16)BITS_TO_BYTES(bits));
|
||||
+ // The change below is to make sure that all keys that are generated from the same
|
||||
+ // seed value will be the same regardless of the endianess or word size of the CPU.
|
||||
+ // DRBG_Generate(rand, (BYTE *)prime->d, (UINT16)BITS_TO_BYTES(bits));// old
|
||||
+ // if(g_inFailureMode) // old
|
||||
+ // libtpms changed begin
|
||||
+ if (1) {
|
||||
+ DRBG_Generate(rand, (BYTE *)prime->d, (UINT16)BITS_TO_BYTES(bits));
|
||||
+ if (g_inFailureMode)
|
||||
+ return;
|
||||
+ } else {
|
||||
+ if(!BnGetRandomBits(prime, bits, rand)) // new
|
||||
+ return;
|
||||
+ }
|
||||
RsaAdjustPrimeCandidate(prime);
|
||||
+ // libtpms changed end
|
||||
found = RsaCheckPrime(prime, exponent, rand) == TPM_RC_SUCCESS;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.21.0.windows.1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user