diff --git a/src/swtpm/ctrlchannel.c b/src/swtpm/ctrlchannel.c index 9be8dbd4..1d1c709d 100644 --- a/src/swtpm/ctrlchannel.c +++ b/src/swtpm/ctrlchannel.c @@ -175,6 +175,9 @@ static int ctrlchannel_return_state(ptm_getstate *pgs, int fd, if (!blobname) res = TPM_FAIL; + if (res == 0 && blobtype == PTM_BLOB_TYPE_PERMANENT) + res = SWTPM_NVRAM_Store_Permanent(); + if (res == 0 && blobtype == PTM_BLOB_TYPE_VOLATILE) res = SWTPM_NVRAM_Store_Volatile(); diff --git a/src/swtpm/swtpm_nvstore.c b/src/swtpm/swtpm_nvstore.c index 361babde..52ddf50d 100644 --- a/src/swtpm/swtpm_nvstore.c +++ b/src/swtpm/swtpm_nvstore.c @@ -481,6 +481,37 @@ TPM_RESULT SWTPM_NVRAM_Store_Volatile(void) return rc; } +/* + * Flush libtpms's in-memory PERMANENT state to disk so that the next + * SWTPM_NVRAM_GetStateBlob(PERMANENT) returns a blob consistent with what + * libtpms is actually running. Counterpart to SWTPM_NVRAM_Store_Volatile(). + * + * Without this, GET_STATEBLOB(PERMANENT) on the migration-out path reads a + * file that may be missing, empty, or stale relative to libtpms RAM (the + * file is only written by _plat__NvCommit() on UT_NV-class commands), and + * an empty/short-read blob then poisons the destination's state restore. + */ +TPM_RESULT SWTPM_NVRAM_Store_Permanent(void) +{ + TPM_RESULT rc = 0; + char *name = TPM_PERMANENT_ALL_NAME; + uint32_t tpm_number = 0; + unsigned char *buffer = NULL; + uint32_t buflen = 0; + + TPM_DEBUG(" SWTPM_Store_Permanent: Name %s\n", name); + if (rc == 0) { + rc = TPMLIB_GetState(TPMLIB_STATE_PERMANENT, &buffer, &buflen); + } + if (rc == 0 && buflen > 0) { + rc = SWTPM_NVRAM_StoreData(buffer, buflen, tpm_number, name); + } + + free(buffer); + + return rc; +} + static TPM_RESULT SWTPM_NVRAM_KeyParamCheck(uint32_t keylen, enum encryption_mode encmode) diff --git a/src/swtpm/swtpm_nvstore.h b/src/swtpm/swtpm_nvstore.h index cab3fa94..eeb891ae 100644 --- a/src/swtpm/swtpm_nvstore.h +++ b/src/swtpm/swtpm_nvstore.h @@ -69,6 +69,7 @@ TPM_RESULT SWTPM_NVRAM_DeleteName(uint32_t tpm_number, const char *name, TPM_BOOL mustExist); TPM_RESULT SWTPM_NVRAM_Store_Volatile(void); +TPM_RESULT SWTPM_NVRAM_Store_Permanent(void); TPM_RESULT SWTPM_NVRAM_Set_FileKey(const unsigned char *data, uint32_t length,