MAXREFDES143#: DeepCover Embedded Security in IoT Authenticated Sensing & Notification

Dependencies:   MaximInterface mbed

The MAXREFDES143# is an Internet of Things (IoT) embedded security reference design, built to protect an industrial sensing node by means of authentication and notification to a web server. The hardware includes a peripheral module representing a protected sensor node monitoring operating temperature and remaining life of a filter (simulated through ambient light sensing) and an mbed shield representing a controller node responsible for monitoring one or more sensor nodes. The design is hierarchical with each controller node communicating data from connected sensor nodes to a web server that maintains a centralized log and dispatches notifications as necessary. The mbed shield contains a Wi-Fi module, a DS2465 coprocessor with 1-Wire® master function, an LCD, LEDs, and pushbuttons. The protected sensor node contains a DS28E15 authenticator, a DS7505 temperature sensor, and a MAX44009 light sensor. The mbed shield communicates to a web server by the onboard Wi-Fi module and to the protected sensor node with I2C and 1-Wire. The MAXREFDES143# is equipped with a standard shield connector for immediate testing using an mbed board such as the MAX32600MBED#. The simplicity of this design enables rapid integration into any star-topology IoT network requiring the heightened security with low overhead provided by the SHA-256 symmetric-key algorithm.

More information about the MAXREFDES143# is available on the Maxim Integrated website.

Revision:
25:37ea43ff81be
Parent:
20:cdba71cb5506
Child:
27:81a87d29bedd
--- a/WebServerInterface.cpp	Wed Oct 19 13:23:41 2016 -0500
+++ b/WebServerInterface.cpp	Fri Dec 16 10:47:34 2016 -0600
@@ -32,18 +32,18 @@
 */
 
 #include <vector>
-
 #include "WebServerInterface.hpp"
 #include "ESP8266.hpp"
 #include "Slaves/Authenticators/ISha256MacCoproc.h"
-#include "common.hpp"
+#include "SensorData.hpp"
+#include "HexConversions.hpp"
 #include "Serial.h"
 #include "wait_api.h"
 
 using OneWire::ISha256MacCoproc;
 
-const char WebServerInterface::wifiSsid[] = "WifiSsid";
-const char WebServerInterface::wifiPassword[] = "WifiPassword";
+const char WebServerInterface::wifiSsid[] = "TWS iPhone";
+const char WebServerInterface::wifiPassword[] = "maxim1234";
 const char WebServerInterface::serverAddress[] = "www.mxim-security.us";
 const unsigned int WebServerInterface::serverPort = 80;
 const char WebServerInterface::serverPostPath[] = "/post.php";
@@ -61,12 +61,14 @@
 
 /// Select the Transport Secret for the web server in the Controller.
 /// @returns True on success.
-static bool setHttpPostSecret(ISha256MacCoproc & MacCoproc)
+static bool setHttpPostSecret(ISha256MacCoproc & MacCoproc, const OneWire::RomId & sessionId)
 {
-  ISha256MacCoproc::DevicePage::Buffer fillData;
-  std::memset(fillData, defaultPaddingByte, ISha256MacCoproc::DevicePage::length);
-  // static_assert(ISha256MacCoproc::DevicePage::length > ISha256MacCoproc::SlaveSecretData::length);
-  return (MacCoproc.computeSlaveSecret(fillData, fillData, reinterpret_cast<const ISha256MacCoproc::SlaveSecretData::Buffer &>(fillData)) == ISha256MacCoproc::Success);
+  ISha256MacCoproc::DevicePage fillData;
+  fillData.fill(defaultPaddingByte);
+  ISha256MacCoproc::SlaveSecretData secretData;
+  secretData.fill(defaultPaddingByte);
+  std::copy(sessionId.buffer.begin(), sessionId.buffer.end(), secretData.begin());
+  return (MacCoproc.computeSlaveSecret(fillData, fillData, secretData) == ISha256MacCoproc::Success);
 }
 
 WebServerInterface::WebServerInterface(ESP8266 & esp8266, mbed::Serial * pc)
@@ -80,26 +82,19 @@
   esp8266.setPowered(true);
   esp8266.reset();
   bool result = (esp8266.performSelfTest() == ESP8266::AT_OK);
-  if (!result)
+  if (result)
   {
-    return false;
-  }
-  result = (esp8266.setCurrentWifiMode(ESP8266::softAP_station_mode) == ESP8266::AT_OK);
-  if (!result)
-  {
-    return false;
+    result = (esp8266.setCurrentWifiMode(ESP8266::softAP_station_mode) == ESP8266::AT_OK);
   }
-  result = (esp8266.setMaxRFTXPower(10) == ESP8266::AT_OK);
-  if (!result)
+  if (result)
   {
-    return false;
+    result = (esp8266.setMaxRFTXPower(10) == ESP8266::AT_OK);
   }
-  result = (esp8266.joinCurrentAccessPoint(wifiSsid, wifiPassword) == ESP8266::AT_OK);
-  if (!result)
+  if (result)
   {
-    return false;
+    result = (esp8266.joinCurrentAccessPoint(wifiSsid, wifiPassword) == ESP8266::AT_OK);
   }
-  return true;
+  return result;
 }
 
 /// Format an HTTP GET request as a string for transmission.
@@ -129,19 +124,19 @@
   ISha256MacCoproc::DeviceScratchpad block;
   size_t index = 0;
   ISha256MacCoproc::AuthMacData padding;
-  std::memset(padding, defaultPaddingByte, padding.length);
-  std::memset(output, defaultPaddingByte, output.length); // Set initial hash value
+  padding.fill(defaultPaddingByte);
+  output.fill(defaultPaddingByte); // Set initial hash value
   while (index < ilen)
   {
-    if ((index + block.length) <= ilen) // Full block
+    if ((index + block.size()) <= ilen) // Full block
     {
-      std::memcpy(block, &input[index], block.length);
-      index += block.length;
+      std::memcpy(block.data(), &input[index], block.size());
+      index += block.size();
     }
     else // Partial block with padding
     {
-      std::memcpy(block, &input[index], ilen - index);
-      std::memset(&block[ilen - index], defaultPaddingByte, block.length - (ilen - index));
+      std::memcpy(block.data(), &input[index], ilen - index);
+      std::memset(&block[ilen - index], defaultPaddingByte, block.size() - (ilen - index));
       index = ilen;
     }
     // Write data to coprocessor and hash block
@@ -207,13 +202,13 @@
   // Combine initial post body with initial secret and hash
   std::vector<uint8_t> hashInput;
   hashInput.reserve(challengeLen + httpPost.length());
-  hashInput.insert(hashInput.end(), challenge, challenge + challengeLen);
+  hashInput.assign(challenge, challenge + challengeLen);
   hashInput.insert(hashInput.end(), httpPost.begin(), httpPost.end());
   ISha256MacCoproc::Mac mac;
   calculateHttpPostMac(macCoproc, &hashInput[0], hashInput.size(), mac);
   
   char contentLen[5];
-  snprintf(contentLen, sizeof(contentLen) / sizeof(contentLen[0]), "%u", (hashInput.size() - challengeLen) + (mac.length * charsPerByte) + 5 /* &MAC= */);
+  snprintf(contentLen, sizeof(contentLen) / sizeof(contentLen[0]), "%u", (hashInput.size() - challengeLen) + (mac.size() * charsPerByte) + 5 /* &MAC= */);
   
   // Construct full post request
   httpPost = "";
@@ -238,7 +233,7 @@
   httpPost += fieldSeparator;
   httpPost += "MAC";
   httpPost += keyValSeparator;
-  byteArrayToHexString(mac, mac.length, httpPost);
+  byteArrayToHexString(mac.data(), mac.size(), httpPost);
   httpPost += newline;
   
   return httpPost;
@@ -256,7 +251,7 @@
   
   if (setSecret)
   {
-    result = setHttpPostSecret(macCoproc);
+    result = setHttpPostSecret(macCoproc, m_sessionId);
     if (!result)
       return result;
   }
@@ -267,7 +262,7 @@
   if (result)
   {
     // Request challenge
-    result = (esp8266.sendData(formatHttpGet(serverAddress, serverChallengePath, sessionId)) == ESP8266::AT_OK);
+    result = (esp8266.sendData(formatHttpGet(serverAddress, serverChallengePath, m_sessionIdString)) == ESP8266::AT_OK);
     if (result)
     {
       // Receive server response
@@ -309,7 +304,7 @@
       result = (esp8266.openConnection(ESP8266::TCP, serverAddress, serverPort) == ESP8266::AT_OK);
       if (result)
       {
-        result = (esp8266.sendData(formatHttpPost(serverAddress, serverPostPath, sessionId, macCoproc, event, postData, challenge)) == ESP8266::AT_OK);
+        result = (esp8266.sendData(formatHttpPost(serverAddress, serverPostPath, m_sessionIdString, macCoproc, event, postData, challenge)) == ESP8266::AT_OK);
         wait_ms(ESP8266::sendDataRecoveryTimeMs); // Wait for ESP8266 specified recovery time
       }
     }
@@ -333,4 +328,10 @@
   postBodyStream << fieldSeparator;
   postBodyStream << "FilterLifeAlarm" << keyValSeparator << (sensorData.filterLifeAlarm() ? "true" : "false");
   return postBodyStream.str();
+}
+
+void WebServerInterface::setSessionId(const OneWire::RomId & sessionId)
+{
+    m_sessionIdString = byteArrayToHexString(sessionId.buffer.data(), sessionId.buffer.size());
+    m_sessionId = sessionId;
 }
\ No newline at end of file