secure-boot: Log an error if TPM measurement fails

Log an error if the TPM measurement fails due to the absence or
invalid value of the file '/sys/class/tpm/tpm0/pcr-sha256/0'.

Tested:
Verified that an error is logged when '/sys/class/tpm/tpm0/pcr-sha256/0'
is absent, empty, or has a value of 0, indicating that the TPM
measurement has failed.
```
"Severity" : {
	"type" : "s",
	"data" : "xyz.openbmc_project.Logging.Entry.Level.Error"
},
"Message" : {
	"type" : "s",
	"data" : "xyz.openbmc_project.State.Error.TpmMeasurementFail"
},
"AdditionalData" : {
	"type" : "as",
	"data" : [
		"ERROR=TPM measurement value is empty: /sys/class/tpm/tpm0/pcr-sha256/0",
		"_PID=501"
	]
},
```

Change-Id: I9be610a9b473a529b09feec6643ec65b58a62907
Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
diff --git a/meson.build b/meson.build
index f734b46..4e9ccf5 100644
--- a/meson.build
+++ b/meson.build
@@ -61,6 +61,9 @@
 conf.set10(
     'ONLY_RUN_APR_ON_POWER_LOSS', get_option('only-run-apr-on-power-loss'))
 
+conf.set_quoted(
+    'SYSFS_TPM_MEASUREMENT_PATH', get_option('sysfs-tpm-measurement-path'))
+
 # globals shared across applications
 conf.set_quoted(
     'BASE_FILE_DIR', '/run/openbmc/')
diff --git a/meson_options.txt b/meson_options.txt
index bdf0bbc..9c978a0 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -130,3 +130,9 @@
     value : 'false',
     description : 'Only run automatic restore policy due to loss of AC power.'
 )
+
+option('sysfs-tpm-measurement-path', type : 'string',
+    value : '/sys/class/tpm/tpm0/pcr-sha256/0',
+    description : 'The sysfs path to the tpm measurement value.',
+)
+
diff --git a/secure_boot_check.cpp b/secure_boot_check.cpp
index fc5cec0..edbd8ff 100644
--- a/secure_boot_check.cpp
+++ b/secure_boot_check.cpp
@@ -12,6 +12,55 @@
 
 constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
 
+// Check if the TPM measurement file exists and has a valid value.
+// If the TPM measurement is invalid, it logs an error message.
+void checkTpmMeasurement()
+{
+    bool tpmError = false;
+    std::string errorMsg;
+    if (!std::filesystem::exists(std::string(SYSFS_TPM_MEASUREMENT_PATH)))
+    {
+        tpmError = true;
+        errorMsg = "TPM measurement file does not exist: " +
+                   std::string(SYSFS_TPM_MEASUREMENT_PATH);
+    }
+    else
+    {
+        std::string tpmValueStr;
+        std::ifstream tpmFile(std::string(SYSFS_TPM_MEASUREMENT_PATH));
+
+        tpmFile >> tpmValueStr;
+        if (tpmValueStr.empty())
+        {
+            tpmError = true;
+            errorMsg = "TPM measurement value is empty: " +
+                       std::string(SYSFS_TPM_MEASUREMENT_PATH);
+        }
+        else if (tpmValueStr == "0")
+        {
+            tpmError = true;
+            errorMsg = "TPM measurement value is 0: " +
+                       std::string(SYSFS_TPM_MEASUREMENT_PATH);
+        }
+        tpmFile.close();
+    }
+
+    if (tpmError)
+    {
+        // Doesn't have valid TPM measurement, log an error message
+        std::map<std::string, std::string> additionalData;
+        error("{ERROR}", "ERROR", errorMsg);
+        additionalData.emplace("ERROR", errorMsg);
+        auto bus = sdbusplus::bus::new_default();
+        phosphor::state::manager::utils::createError(
+            bus, "xyz.openbmc_project.State.Error.TpmMeasurementFail",
+            sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
+                Error,
+            additionalData);
+    }
+    return;
+}
+
 // Utilize the QuiesceOnHwError setting as an indication that the system
 // is operating in an environment where the user should be notified of
 // security settings (i.e. "Manufacturing")
@@ -139,5 +188,8 @@
         }
     }
 
+    // Check the TPM measurement
+    checkTpmMeasurement();
+
     return 0;
 }