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:
29:590a7561318b
Parent:
28:e5cdaf13d299
Child:
30:0784010d6975
--- a/WebServerInterface.cpp	Thu Jan 26 14:18:21 2017 -0600
+++ b/WebServerInterface.cpp	Thu Jan 26 16:55:23 2017 -0600
@@ -31,11 +31,9 @@
 *******************************************************************************
 */
 
-#include <sstream>
 #include <vector>
 #include "WebServerInterface.hpp"
-#include "NetworkStack.h"
-#include "TCPSocket.h"
+#include "ESP8266.hpp"
 #include "Slaves/Authenticators/ISha256MacCoproc.h"
 #include "SensorData.hpp"
 #include "HexConversions.hpp"
@@ -44,6 +42,8 @@
 
 using OneWire::ISha256MacCoproc;
 
+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";
@@ -71,6 +71,26 @@
   return (MacCoproc.computeSlaveSecret(fillData, fillData, secretData) == ISha256MacCoproc::Success);
 }
 
+bool WebServerInterface::initialize()
+{
+  esp8266.setPowered(true);
+  esp8266.reset();
+  bool result = (esp8266.performSelfTest() == ESP8266::AT_OK);
+  if (result)
+  {
+    result = (esp8266.setCurrentWifiMode(ESP8266::softAP_station_mode) == ESP8266::AT_OK);
+  }
+  if (result)
+  {
+    result = (esp8266.setMaxRFTXPower(10) == ESP8266::AT_OK);
+  }
+  if (result)
+  {
+    result = (esp8266.joinCurrentAccessPoint(wifiSsid, wifiPassword) == ESP8266::AT_OK);
+  }
+  return result;
+}
+
 /// Format an HTTP GET request as a string for transmission.
 /// @param host Web server address.
 /// @param path Web server location to retrieve.
@@ -215,7 +235,13 @@
 
 bool WebServerInterface::authPostHttpEvent(ISha256MacCoproc & macCoproc, PostEvent event, const std::string & postData, bool setSecret)
 {
+  const std::string challengeSearch(newline + newline);
   bool result;
+  uint8_t challenge[challengeLen];
+  std::string response;
+  
+  std::memset(challenge, defaultPaddingByte, challengeLen);
+  response.reserve(300);
   
   if (setSecret)
   {
@@ -225,47 +251,58 @@
   }
   
   // Open connection
-  TCPSocket socket(&networkStack);
-  result = (socket.connect(serverAddress, 80) == 0);
+  esp8266.clearRecvData(); // Clear received data buffer
+  result = (esp8266.openConnection(ESP8266::TCP, serverAddress, 80) == ESP8266::AT_OK);
   if (result)
   {
     // Request challenge
-    std::string httpData = formatHttpGet(serverAddress, serverChallengePath, m_sessionIdString);
-    result = (socket.send(httpData.data(), httpData.size()) == httpData.size());
+    result = (esp8266.sendData(formatHttpGet(serverAddress, serverChallengePath, m_sessionIdString)) == ESP8266::AT_OK);
     if (result)
     {
       // Receive server response
-      int recvResult = socket.recv(recvBuf, sizeof(recvBuf) / sizeof(recvBuf[0]));
-      result = recvResult > 0;
-
-      if (result)
-      {          
-        // Parse challenge from response
-        const std::string challengeSearch(newline + newline);
-        httpData.assign(recvBuf, recvResult);
-        size_t challengePos = httpData.find(challengeSearch);
-        if ((challengePos != std::string::npos) && ((challengePos + challengeSearch.length() + (challengeLen * charsPerByte)) <= httpData.length()))
+      for (int i = 0; i < 10; i++)
+      {
+        while (esp8266.recvIpDataReadable())
         {
-          uint8_t challenge[challengeLen];
-          challengePos += challengeSearch.length();
-          for (size_t i = 0; i < challengeLen; i++)
+          char read = esp8266.getcRecvIpData();
+          if (response.length() < response.capacity())
           {
-            std::sscanf(httpData.substr(challengePos + (i * charsPerByte), charsPerByte).c_str(), "%2hhx", &challenge[i]);
+            response += read;
           }
-          
-          // Post sensor data
-          httpData = formatHttpPost(serverAddress, serverPostPath, m_sessionIdString, macCoproc, event, postData, challenge);
-          result = (socket.send(httpData.data(), httpData.size()) == httpData.size());
-          if (result)
+          else
           {
-              result = (socket.recv(recvBuf, sizeof(recvBuf) / sizeof(recvBuf[0])) >= 0);
+            wait_ms(ESP8266::sendDataRecoveryTimeMs); // Wait for ESP8266 specified recovery time
+            goto close_get_connection;
           }
         }
+        wait_ms(100);
+      }
+      // Close connection
+    close_get_connection:
+      esp8266.closeConnection();
+      
+      // Parse challenge from response
+      size_t challengePos = response.find(challengeSearch);
+      if ((challengePos != std::string::npos) && ((challengePos + challengeSearch.length() + (challengeLen * charsPerByte)) <= response.length()))
+      {
+        challengePos += challengeSearch.length();
+        for (size_t i = 0; i < challengeLen; i++)
+        {
+          std::sscanf(response.substr(challengePos + (i * charsPerByte), charsPerByte).c_str(), "%2hhx", &challenge[i]);
+        }
+      }
+      
+      // Post sensor data
+      result = (esp8266.openConnection(ESP8266::TCP, serverAddress, serverPort) == ESP8266::AT_OK);
+      if (result)
+      {
+        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
       }
     }
     
     // Close connection
-    socket.close();
+    esp8266.closeConnection();
   }
   
   return result;