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.

Committer:
IanBenzMaxim
Date:
Thu Jul 21 11:06:13 2016 -0500
Revision:
17:41be4896ed6d
Parent:
14:0962f818bf7f
Child:
18:6fbf7e7b6ab6
Fixed issue with LCD controller initialization on some boards due to power instability. Updated following downstream restructuring in OneWire library.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
IanBenzMaxim 1:e1c7c1c636af 1 /*******************************************************************************
IanBenzMaxim 1:e1c7c1c636af 2 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
IanBenzMaxim 1:e1c7c1c636af 3 *
IanBenzMaxim 1:e1c7c1c636af 4 * Permission is hereby granted, free of charge, to any person obtaining a
IanBenzMaxim 1:e1c7c1c636af 5 * copy of this software and associated documentation files (the "Software"),
IanBenzMaxim 1:e1c7c1c636af 6 * to deal in the Software without restriction, including without limitation
IanBenzMaxim 1:e1c7c1c636af 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
IanBenzMaxim 1:e1c7c1c636af 8 * and/or sell copies of the Software, and to permit persons to whom the
IanBenzMaxim 1:e1c7c1c636af 9 * Software is furnished to do so, subject to the following conditions:
IanBenzMaxim 1:e1c7c1c636af 10 *
IanBenzMaxim 1:e1c7c1c636af 11 * The above copyright notice and this permission notice shall be included
IanBenzMaxim 1:e1c7c1c636af 12 * in all copies or substantial portions of the Software.
IanBenzMaxim 1:e1c7c1c636af 13 *
IanBenzMaxim 1:e1c7c1c636af 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
IanBenzMaxim 1:e1c7c1c636af 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
IanBenzMaxim 1:e1c7c1c636af 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IanBenzMaxim 1:e1c7c1c636af 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
IanBenzMaxim 1:e1c7c1c636af 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
IanBenzMaxim 1:e1c7c1c636af 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
IanBenzMaxim 1:e1c7c1c636af 20 * OTHER DEALINGS IN THE SOFTWARE.
IanBenzMaxim 1:e1c7c1c636af 21 *
IanBenzMaxim 1:e1c7c1c636af 22 * Except as contained in this notice, the name of Maxim Integrated
IanBenzMaxim 1:e1c7c1c636af 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
IanBenzMaxim 1:e1c7c1c636af 24 * Products, Inc. Branding Policy.
IanBenzMaxim 1:e1c7c1c636af 25 *
IanBenzMaxim 1:e1c7c1c636af 26 * The mere transfer of this software does not imply any licenses
IanBenzMaxim 1:e1c7c1c636af 27 * of trade secrets, proprietary technology, copyrights, patents,
IanBenzMaxim 1:e1c7c1c636af 28 * trademarks, maskwork rights, or any other form of intellectual
IanBenzMaxim 1:e1c7c1c636af 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
IanBenzMaxim 1:e1c7c1c636af 30 * ownership rights.
IanBenzMaxim 1:e1c7c1c636af 31 *******************************************************************************
IanBenzMaxim 1:e1c7c1c636af 32 */
IanBenzMaxim 1:e1c7c1c636af 33
IanBenzMaxim 1:e1c7c1c636af 34 #include "SensorNode.hpp"
IanBenzMaxim 1:e1c7c1c636af 35 #include "common.hpp"
IanBenzMaxim 6:b6bafd0a7013 36 #include "Masters/DS2465/DS2465.h"
IanBenzMaxim 17:41be4896ed6d 37 #include "RomId/RomCommands.h"
IanBenzMaxim 6:b6bafd0a7013 38 #include "I2C.h"
IanBenzMaxim 1:e1c7c1c636af 39
IanBenzMaxim 1:e1c7c1c636af 40 #ifdef TARGET_MAX32600
IanBenzMaxim 1:e1c7c1c636af 41 #include "max32600.h"
IanBenzMaxim 1:e1c7c1c636af 42 #include "clkman_regs.h"
IanBenzMaxim 1:e1c7c1c636af 43 #include "tpu_regs.h"
IanBenzMaxim 1:e1c7c1c636af 44 #else
IanBenzMaxim 1:e1c7c1c636af 45 #include <cstdlib>
IanBenzMaxim 1:e1c7c1c636af 46 #endif
IanBenzMaxim 1:e1c7c1c636af 47
IanBenzMaxim 8:594529956266 48 using namespace OneWire;
IanBenzMaxim 17:41be4896ed6d 49 using namespace OneWire::RomCommands;
IanBenzMaxim 6:b6bafd0a7013 50
IanBenzMaxim 1:e1c7c1c636af 51 bool SensorNode::rngInitialized = false;
IanBenzMaxim 1:e1c7c1c636af 52
IanBenzMaxim 1:e1c7c1c636af 53 void SensorNode::initializeRng()
IanBenzMaxim 1:e1c7c1c636af 54 {
IanBenzMaxim 1:e1c7c1c636af 55 #ifdef TARGET_MAX32600
IanBenzMaxim 1:e1c7c1c636af 56 MXC_CLKMAN->clk_config |= (MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_ENABLE | MXC_F_CLKMAN_CLK_CONFIG_CRYPTO_RESET_N); // Enable crypto oscillator
IanBenzMaxim 1:e1c7c1c636af 57 while ((MXC_CLKMAN->intfl & MXC_F_CLKMAN_INTFL_CRYPTO_STABLE) != MXC_F_CLKMAN_INTFL_CRYPTO_STABLE) ; // Wait for crypto oscillator stability
IanBenzMaxim 1:e1c7c1c636af 58 MXC_CLKMAN->clk_ctrl |= MXC_F_CLKMAN_CLK_CTRL_CRYPTO_GATE_N; // Disable crypto clock gating
IanBenzMaxim 1:e1c7c1c636af 59 MXC_CLKMAN->crypt_clk_ctrl_2_prng = MXC_CLKMAN->clk_ctrl_10_prng = 1; // Set PRNG clock to crypto clock
IanBenzMaxim 1:e1c7c1c636af 60 MXC_CLKMAN->clk_gate_ctrl2 |= (1 << MXC_F_CLKMAN_CLK_GATE_CTRL2_TPU_CLK_GATER_POS); // Use dynamic clock gating
IanBenzMaxim 1:e1c7c1c636af 61 #endif
IanBenzMaxim 1:e1c7c1c636af 62 }
IanBenzMaxim 1:e1c7c1c636af 63
IanBenzMaxim 6:b6bafd0a7013 64 SensorNode::SensorNode(mbed::I2C & i2c, uint8_t ds7505_i2c_addr, uint8_t max44009_i2c_addr, DS2465 & ds2465)
IanBenzMaxim 9:bc3d211d75ce 65 : m_initialLux(1),ds2465(ds2465), selector(ds2465), ds28e15_22_25(selector), ds7505(i2c, ds7505_i2c_addr), max44009(i2c, max44009_i2c_addr)
IanBenzMaxim 1:e1c7c1c636af 66 {
IanBenzMaxim 1:e1c7c1c636af 67 if (!rngInitialized)
IanBenzMaxim 1:e1c7c1c636af 68 {
IanBenzMaxim 1:e1c7c1c636af 69 initializeRng();
IanBenzMaxim 1:e1c7c1c636af 70 rngInitialized = true;
IanBenzMaxim 1:e1c7c1c636af 71 }
IanBenzMaxim 1:e1c7c1c636af 72 }
IanBenzMaxim 1:e1c7c1c636af 73
IanBenzMaxim 1:e1c7c1c636af 74 bool SensorNode::initializeSensors()
IanBenzMaxim 1:e1c7c1c636af 75 {
IanBenzMaxim 1:e1c7c1c636af 76 return (max44009.read_current_lux(m_initialLux) == MAX44009::Success);
IanBenzMaxim 1:e1c7c1c636af 77 }
IanBenzMaxim 1:e1c7c1c636af 78
IanBenzMaxim 1:e1c7c1c636af 79 bool SensorNode::setSecret()
IanBenzMaxim 1:e1c7c1c636af 80 {
IanBenzMaxim 1:e1c7c1c636af 81 DS28E15_22_25::Scratchpad scratchpad;
IanBenzMaxim 1:e1c7c1c636af 82 DS28E15_22_25::Page pageData;
IanBenzMaxim 1:e1c7c1c636af 83
IanBenzMaxim 1:e1c7c1c636af 84 // Create constant partial secret
IanBenzMaxim 1:e1c7c1c636af 85 std::memset(scratchpad, defaultPaddingByte, scratchpad.length);
IanBenzMaxim 1:e1c7c1c636af 86 // Read page data
IanBenzMaxim 11:aeaa77b488c0 87 bool result = (ds2465.readMemory(DS2465::UserMemoryPage0, pageData, pageData.length, false) == OneWireMaster::Success);
IanBenzMaxim 1:e1c7c1c636af 88 // Calculate secret
IanBenzMaxim 1:e1c7c1c636af 89 if (result)
IanBenzMaxim 1:e1c7c1c636af 90 {
IanBenzMaxim 14:0962f818bf7f 91 result = (DS28E15_22_25::computeNextSecret(ds2465, pageData, authData.pageNum, scratchpad, ds28e15_22_25.romId(), ds28e15_22_25.manId()) == ISha256MacCoproc::Success);
IanBenzMaxim 1:e1c7c1c636af 92 }
IanBenzMaxim 1:e1c7c1c636af 93 return result;
IanBenzMaxim 1:e1c7c1c636af 94 }
IanBenzMaxim 1:e1c7c1c636af 95
IanBenzMaxim 1:e1c7c1c636af 96 bool SensorNode::checkProvisioned(bool & provisioned)
IanBenzMaxim 1:e1c7c1c636af 97 {
IanBenzMaxim 1:e1c7c1c636af 98 DS28E15_22_25::BlockProtection protectionStatus;
IanBenzMaxim 1:e1c7c1c636af 99 bool result;
IanBenzMaxim 1:e1c7c1c636af 100
IanBenzMaxim 9:bc3d211d75ce 101
IanBenzMaxim 9:bc3d211d75ce 102 result = (ds28e15_22_25.readBlockProtection(0, protectionStatus) == OneWireSlave::Success);
IanBenzMaxim 1:e1c7c1c636af 103 if (result)
IanBenzMaxim 1:e1c7c1c636af 104 {
IanBenzMaxim 1:e1c7c1c636af 105 if (!protectionStatus.noProtection())
IanBenzMaxim 1:e1c7c1c636af 106 {
IanBenzMaxim 9:bc3d211d75ce 107 result = (ds28e15_22_25.readSegment(authData.pageNum, authData.segmentNum, authData.segment) == OneWireSlave::Success);
IanBenzMaxim 1:e1c7c1c636af 108 if (result)
IanBenzMaxim 1:e1c7c1c636af 109 provisioned = true;
IanBenzMaxim 1:e1c7c1c636af 110 }
IanBenzMaxim 1:e1c7c1c636af 111 else
IanBenzMaxim 1:e1c7c1c636af 112 {
IanBenzMaxim 1:e1c7c1c636af 113 provisioned = false;
IanBenzMaxim 1:e1c7c1c636af 114 }
IanBenzMaxim 1:e1c7c1c636af 115 }
IanBenzMaxim 1:e1c7c1c636af 116 return result;
IanBenzMaxim 1:e1c7c1c636af 117 }
IanBenzMaxim 1:e1c7c1c636af 118
IanBenzMaxim 1:e1c7c1c636af 119 bool SensorNode::checkAuthentic(unsigned int userEntropy)
IanBenzMaxim 1:e1c7c1c636af 120 {
IanBenzMaxim 1:e1c7c1c636af 121 DS28E15_22_25::Scratchpad challenge;
IanBenzMaxim 1:e1c7c1c636af 122 DS28E15_22_25::Page pageData;
IanBenzMaxim 1:e1c7c1c636af 123
IanBenzMaxim 1:e1c7c1c636af 124 // Read page data
IanBenzMaxim 1:e1c7c1c636af 125 if (ds28e15_22_25.readPage(authData.pageNum, pageData, false) != OneWireSlave::Success)
IanBenzMaxim 1:e1c7c1c636af 126 return false;
IanBenzMaxim 1:e1c7c1c636af 127
IanBenzMaxim 1:e1c7c1c636af 128 // Create random challenge
IanBenzMaxim 1:e1c7c1c636af 129 // Use hardare RNG on MAX32600
IanBenzMaxim 1:e1c7c1c636af 130 #ifdef TARGET_MAX32600
IanBenzMaxim 1:e1c7c1c636af 131 MXC_TPU->prng_user_entropy = userEntropy;
IanBenzMaxim 1:e1c7c1c636af 132 #else
IanBenzMaxim 1:e1c7c1c636af 133 std::srand(userEntropy);
IanBenzMaxim 1:e1c7c1c636af 134 #endif
IanBenzMaxim 6:b6bafd0a7013 135 for (size_t i = 0; i < challenge.length; i++)
IanBenzMaxim 1:e1c7c1c636af 136 {
IanBenzMaxim 1:e1c7c1c636af 137 #ifdef TARGET_MAX32600
IanBenzMaxim 1:e1c7c1c636af 138 challenge[i] = MXC_TPU->prng_rnd_num;
IanBenzMaxim 1:e1c7c1c636af 139 #else
IanBenzMaxim 1:e1c7c1c636af 140 challenge[i] = std::rand();
IanBenzMaxim 1:e1c7c1c636af 141 #endif
IanBenzMaxim 1:e1c7c1c636af 142 }
IanBenzMaxim 1:e1c7c1c636af 143
IanBenzMaxim 1:e1c7c1c636af 144 // Write challenge to scratchpad
IanBenzMaxim 1:e1c7c1c636af 145 if (ds28e15_22_25.writeScratchpad(challenge) != OneWireSlave::Success)
IanBenzMaxim 1:e1c7c1c636af 146 return false;
IanBenzMaxim 1:e1c7c1c636af 147 // Have device compute MAC
IanBenzMaxim 1:e1c7c1c636af 148 DS28E15_22_25::Mac nodeMac;
IanBenzMaxim 1:e1c7c1c636af 149 if (ds28e15_22_25.computeReadPageMac(0, false, nodeMac) != OneWireSlave::Success)
IanBenzMaxim 1:e1c7c1c636af 150 return false;
IanBenzMaxim 1:e1c7c1c636af 151 // Compute expected MAC
IanBenzMaxim 1:e1c7c1c636af 152 DS28E15_22_25::Mac controllerMac;
IanBenzMaxim 14:0962f818bf7f 153 if (DS28E15_22_25::computeAuthMac(ds2465, pageData, authData.pageNum, challenge, ds28e15_22_25.romId(), ds28e15_22_25.manId(), controllerMac) != ISha256MacCoproc::Success)
IanBenzMaxim 1:e1c7c1c636af 154 return false;
IanBenzMaxim 1:e1c7c1c636af 155 // Check if authentic
IanBenzMaxim 1:e1c7c1c636af 156 return (nodeMac == controllerMac);
IanBenzMaxim 1:e1c7c1c636af 157 }
IanBenzMaxim 1:e1c7c1c636af 158
IanBenzMaxim 1:e1c7c1c636af 159 bool SensorNode::readSensorData(SensorData & sensorData)
IanBenzMaxim 1:e1c7c1c636af 160 {
IanBenzMaxim 1:e1c7c1c636af 161 bool result;
IanBenzMaxim 1:e1c7c1c636af 162 std::int8_t temp;
IanBenzMaxim 1:e1c7c1c636af 163
IanBenzMaxim 1:e1c7c1c636af 164 // Read temperature sensor
IanBenzMaxim 1:e1c7c1c636af 165 result = (ds7505.read_current_temp(temp) == DS7505::Success);
IanBenzMaxim 1:e1c7c1c636af 166
IanBenzMaxim 1:e1c7c1c636af 167 if (result)
IanBenzMaxim 1:e1c7c1c636af 168 {
IanBenzMaxim 1:e1c7c1c636af 169 sensorData.temp = temp;
IanBenzMaxim 1:e1c7c1c636af 170
IanBenzMaxim 1:e1c7c1c636af 171 // Read light sensor
IanBenzMaxim 1:e1c7c1c636af 172 double currentLux;
IanBenzMaxim 1:e1c7c1c636af 173 result = (max44009.read_current_lux(currentLux) == MAX44009::Success);
IanBenzMaxim 1:e1c7c1c636af 174 if (result)
IanBenzMaxim 1:e1c7c1c636af 175 {
IanBenzMaxim 1:e1c7c1c636af 176 // Convert lux to remaining filter life
IanBenzMaxim 1:e1c7c1c636af 177 sensorData.filterLife = (unsigned int)((currentLux / m_initialLux) * 100);
IanBenzMaxim 1:e1c7c1c636af 178 }
IanBenzMaxim 1:e1c7c1c636af 179 }
IanBenzMaxim 1:e1c7c1c636af 180
IanBenzMaxim 1:e1c7c1c636af 181 return result;
IanBenzMaxim 1:e1c7c1c636af 182 }
IanBenzMaxim 1:e1c7c1c636af 183
IanBenzMaxim 1:e1c7c1c636af 184 bool SensorNode::checkAndWriteAuthData(SensorData & sensorData)
IanBenzMaxim 1:e1c7c1c636af 185 {
IanBenzMaxim 1:e1c7c1c636af 186 bool result = true;
IanBenzMaxim 1:e1c7c1c636af 187
IanBenzMaxim 1:e1c7c1c636af 188 if (sensorData.filterLife > authData.filterLife)
IanBenzMaxim 1:e1c7c1c636af 189 {
IanBenzMaxim 1:e1c7c1c636af 190 sensorData.filterLife = authData.filterLife;
IanBenzMaxim 1:e1c7c1c636af 191 }
IanBenzMaxim 1:e1c7c1c636af 192 else if (sensorData.filterLife < authData.filterLife)
IanBenzMaxim 1:e1c7c1c636af 193 {
IanBenzMaxim 1:e1c7c1c636af 194 AuthData oldAuthData(authData);
IanBenzMaxim 1:e1c7c1c636af 195 authData.filterLife = sensorData.filterLife;
IanBenzMaxim 1:e1c7c1c636af 196 // Write new filter life to DS28E15
IanBenzMaxim 9:bc3d211d75ce 197 result = (ds28e15_22_25.writeAuthSegment(ds2465, authData.pageNum, authData.segmentNum, authData.segment, oldAuthData.segment, false) == OneWireSlave::Success);
IanBenzMaxim 1:e1c7c1c636af 198 }
IanBenzMaxim 1:e1c7c1c636af 199
IanBenzMaxim 1:e1c7c1c636af 200 return result;
IanBenzMaxim 1:e1c7c1c636af 201 }
IanBenzMaxim 1:e1c7c1c636af 202
IanBenzMaxim 1:e1c7c1c636af 203 SensorNode::State SensorNode::detect(unsigned int userEntropy)
IanBenzMaxim 1:e1c7c1c636af 204 {
IanBenzMaxim 1:e1c7c1c636af 205 bool provisioned;
IanBenzMaxim 1:e1c7c1c636af 206
IanBenzMaxim 7:e24f0b29f1f7 207 ds2465.OWSetSpeed(DS2465::OverdriveSpeed);
IanBenzMaxim 1:e1c7c1c636af 208
IanBenzMaxim 14:0962f818bf7f 209 RomId romId;
IanBenzMaxim 17:41be4896ed6d 210 if (OWReadRom(ds2465, romId) != OneWireMaster::Success)
IanBenzMaxim 1:e1c7c1c636af 211 return UnableToCommunicate;
IanBenzMaxim 14:0962f818bf7f 212 ds28e15_22_25.setRomId(romId);
IanBenzMaxim 1:e1c7c1c636af 213
IanBenzMaxim 1:e1c7c1c636af 214 if (!checkProvisioned(provisioned))
IanBenzMaxim 1:e1c7c1c636af 215 return UnableToCommunicate;
IanBenzMaxim 1:e1c7c1c636af 216
IanBenzMaxim 1:e1c7c1c636af 217 if (!provisioned)
IanBenzMaxim 1:e1c7c1c636af 218 return NotProvisioned;
IanBenzMaxim 1:e1c7c1c636af 219
IanBenzMaxim 1:e1c7c1c636af 220 if (!setSecret())
IanBenzMaxim 1:e1c7c1c636af 221 return UnableToCommunicate;
IanBenzMaxim 1:e1c7c1c636af 222
IanBenzMaxim 1:e1c7c1c636af 223 if (!checkAuthentic(userEntropy))
IanBenzMaxim 1:e1c7c1c636af 224 return NotAuthentic;
IanBenzMaxim 1:e1c7c1c636af 225
IanBenzMaxim 1:e1c7c1c636af 226 if (!initializeSensors())
IanBenzMaxim 1:e1c7c1c636af 227 return UnableToCommunicate;
IanBenzMaxim 1:e1c7c1c636af 228
IanBenzMaxim 1:e1c7c1c636af 229 return Authentic;
IanBenzMaxim 1:e1c7c1c636af 230 }
IanBenzMaxim 1:e1c7c1c636af 231
IanBenzMaxim 1:e1c7c1c636af 232 SensorNode::State SensorNode::authenticatedReadSensorData(unsigned int userEntropy, SensorData & sensorData)
IanBenzMaxim 1:e1c7c1c636af 233 {
IanBenzMaxim 7:e24f0b29f1f7 234 ds2465.OWSetSpeed(DS2465::OverdriveSpeed);
IanBenzMaxim 1:e1c7c1c636af 235
IanBenzMaxim 1:e1c7c1c636af 236 if (!setSecret())
IanBenzMaxim 1:e1c7c1c636af 237 return UnableToCommunicate;
IanBenzMaxim 1:e1c7c1c636af 238
IanBenzMaxim 1:e1c7c1c636af 239 if (!checkAuthentic(userEntropy))
IanBenzMaxim 1:e1c7c1c636af 240 return NotAuthentic;
IanBenzMaxim 1:e1c7c1c636af 241
IanBenzMaxim 1:e1c7c1c636af 242 if (!readSensorData(sensorData))
IanBenzMaxim 1:e1c7c1c636af 243 return UnableToCommunicate;
IanBenzMaxim 1:e1c7c1c636af 244
IanBenzMaxim 1:e1c7c1c636af 245 if (!checkAndWriteAuthData(sensorData))
IanBenzMaxim 1:e1c7c1c636af 246 return NotAuthentic;
IanBenzMaxim 1:e1c7c1c636af 247
IanBenzMaxim 1:e1c7c1c636af 248 return Authentic;
IanBenzMaxim 1:e1c7c1c636af 249 }