[openweave-core] Conditional PII logging

Allow logs that contain PII to be enabled/disabled by build time
configuration flags.

Bug: 80037
Test: Confirmed logs do not appear in release builds for
      first device pairing.
Change-Id: I273ed60ad1cf1ef3813f1a047a1a21d12b7536c7
diff --git a/src/adaptations/device-layer/DeviceDescriptionServer.cpp b/src/adaptations/device-layer/DeviceDescriptionServer.cpp
index afe2624..c16c25c 100644
--- a/src/adaptations/device-layer/DeviceDescriptionServer.cpp
+++ b/src/adaptations/device-layer/DeviceDescriptionServer.cpp
@@ -104,9 +104,8 @@
     {
         char ipAddrStr[64];
         nodeAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
-
-        WeaveLogProgress(DeviceLayer, "IdentifyRequest received from node %" PRIX64 " (%s)", nodeId, ipAddrStr);
-        WeaveLogProgress(DeviceLayer, "  Target Fabric Id: %016" PRIX64, reqMsg.TargetFabricId);
+        WeaveLogProgress(DeviceLayer, "IdentifyRequest received from node %s (%s)", WEAVE_PII_FMT("%" PRIX64, nodeId), WEAVE_PII(ipAddrStr));
+        WeaveLogProgress(DeviceLayer, "  Target Fabric Id: %s", WEAVE_PII_FMT("%016" PRIX64, reqMsg.TargetFabricId));
         WeaveLogProgress(DeviceLayer, "  Target Modes: %08" PRIX32, reqMsg.TargetModes);
         WeaveLogProgress(DeviceLayer, "  Target Vendor Id: %04" PRIX16, reqMsg.TargetVendorId);
         WeaveLogProgress(DeviceLayer, "  Target Product Id: %04" PRIX16, reqMsg.TargetProductId);
diff --git a/src/adaptations/device-layer/GeneralUtils.cpp b/src/adaptations/device-layer/GeneralUtils.cpp
index eadc44d..6c80268 100644
--- a/src/adaptations/device-layer/GeneralUtils.cpp
+++ b/src/adaptations/device-layer/GeneralUtils.cpp
@@ -200,6 +200,31 @@
     return true;
 }
 
+/**
+ * Utility function to produce a std::string with printf-style formatting.
+ */
+std::string FormatString(const char* fmt, ...) {
+  std::string buffer;
+  char dummy_buffer;
+  size_t size;
+  va_list args;
+
+  // Determine size of buffer.
+  va_start(args, fmt);
+  size = vsnprintf(&dummy_buffer, 0, fmt, args);
+  va_end(args);
+
+  // Allocate buffer (snprintf always writes a null terminator).
+  buffer.resize(size + 1);
+
+  // Format into buffer.
+  va_start(args, fmt);
+  vsnprintf(buffer.data(), buffer.size(), fmt, args);
+  va_end(args);
+
+  return buffer;
+}
+
 } // namespace DeviceLayer
 } // namespace Weave
 } // namespace nl
diff --git a/src/adaptations/device-layer/include/Weave/DeviceLayer/GeneralUtils.h b/src/adaptations/device-layer/include/Weave/DeviceLayer/GeneralUtils.h
index faefb84..c47816e 100644
--- a/src/adaptations/device-layer/include/Weave/DeviceLayer/GeneralUtils.h
+++ b/src/adaptations/device-layer/include/Weave/DeviceLayer/GeneralUtils.h
@@ -21,6 +21,22 @@
  *          General utility functions available on all platforms.
  */
 
+/**
+ * WEAVE_PII and WEAVE_PII_FMT
+ *
+ * Used to mark information that could be used to identify a specific user or device. This info will
+ * only be logged when PII logging is enabled, otherwise the string will be redacted.
+ *
+ * The _FMT variant additionally formats the PII by the given printf format string.
+ */
+#if WEAVE_DEVICE_CONFIG_LOG_PII
+#define WEAVE_PII(pii) pii
+#define WEAVE_PII_FMT(fmt, pii) ::nl::Weave::DeviceLayer::FormatString(fmt, pii).data()
+#else
+#define WEAVE_PII(pii) "[PII Redacted]"
+#define WEAVE_PII_FMT(fmt, pii) "[PII Redacted]"
+#endif
+
 namespace nl {
 namespace Weave {
 namespace DeviceLayer {
@@ -31,6 +47,7 @@
 extern const char * CharacterizeIPv6Prefix(const Inet::IPPrefix & inPrefix);
 extern void RegisterDeviceLayerErrorFormatter(void);
 extern bool FormatDeviceLayerError(char * buf, uint16_t bufSize, int32_t err);
+extern std::string FormatString(const char* fmt, ...);
 
 } // namespace DeviceLayer
 } // namespace Weave
diff --git a/src/adaptations/device-layer/include/Weave/DeviceLayer/WeaveDeviceConfig.h b/src/adaptations/device-layer/include/Weave/DeviceLayer/WeaveDeviceConfig.h
index d3abf26..b8475e5 100644
--- a/src/adaptations/device-layer/include/Weave/DeviceLayer/WeaveDeviceConfig.h
+++ b/src/adaptations/device-layer/include/Weave/DeviceLayer/WeaveDeviceConfig.h
@@ -130,6 +130,18 @@
 #define WEAVE_DEVICE_CONFIG_LOG_PROVISIONING_HASH 1
 #endif
 
+/**
+ * WEAVE_DEVICE_CONFIG_LOG_PII
+ *
+ * Log information that could be used to identify a user or device.
+ *
+ * The default is (!NDEBUG) to ensure logging of sensitive info is not enabled in non-debug
+ * contexts.
+ */
+#ifndef WEAVE_DEVICE_CONFIG_LOG_PII
+#define WEAVE_DEVICE_CONFIG_LOG_PII (!NDEBUG)
+#endif
+
 // -------------------- Device Identification Configuration --------------------
 
 /**
diff --git a/src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericConfigurationManagerImpl.ipp b/src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericConfigurationManagerImpl.ipp
index a7efb4f..8e56e66 100644
--- a/src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericConfigurationManagerImpl.ipp
+++ b/src/adaptations/device-layer/include/Weave/DeviceLayer/internal/GenericConfigurationManagerImpl.ipp
@@ -1085,13 +1085,13 @@
 
     WeaveLogProgress(DeviceLayer, "Device Configuration:");
 
-    WeaveLogProgress(DeviceLayer, "  Device Id: %016" PRIX64, FabricState.LocalNodeId);
+    WeaveLogProgress(DeviceLayer, "  Device Id: %s", WEAVE_PII_FMT("%016" PRIX64, FabricState.LocalNodeId));
 
     {
         char serialNum[ConfigurationManager::kMaxSerialNumberLength + 1];
         size_t serialNumLen;
         err = Impl()->_GetSerialNumber(serialNum, sizeof(serialNum), serialNumLen);
-        WeaveLogProgress(DeviceLayer, "  Serial Number: %s", (err == WEAVE_NO_ERROR) ? serialNum : "(not set)");
+        WeaveLogProgress(DeviceLayer, "  Serial Number: %s", (err == WEAVE_NO_ERROR) ? WEAVE_PII(serialNum) : "(not set)");
     }
 
     {
@@ -1138,14 +1138,14 @@
 
     if (FabricState.FabricId != kFabricIdNotSpecified)
     {
-        WeaveLogProgress(DeviceLayer, "  Fabric Id: %016" PRIX64, FabricState.FabricId);
+        WeaveLogProgress(DeviceLayer, "  Fabric Id: %s", WEAVE_PII_FMT("%016" PRIX64, FabricState.FabricId));
     }
     else
     {
         WeaveLogProgress(DeviceLayer, "  Fabric Id: (none)");
     }
 
-    WeaveLogProgress(DeviceLayer, "  Pairing Code: %s", (FabricState.PairingCode != NULL) ? FabricState.PairingCode : "(none)");
+    WeaveLogProgress(DeviceLayer, "  Pairing Code: %s", (FabricState.PairingCode != NULL) ? WEAVE_PII(FabricState.PairingCode) : "(none)");
 }
 
 #endif // WEAVE_PROGRESS_LOGGING