From a82e549e1b43ea9e383930cf5f111be76b9aaffc Mon Sep 17 00:00:00 2001 From: rtrimana Date: Fri, 20 Apr 2018 16:44:25 -0700 Subject: [PATCH] Calculating and storing password, salt, and key into EEPROM to not repeat this calculation every time PHOTON wakes up. --- version2/src/C/Crypto.cpp | 27 +++++++++++++--- version2/src/C/Crypto.h | 16 +++++++++ version2/src/C/Sensor-Arduino.ino | 54 +++++++++++++++++++++++-------- 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/version2/src/C/Crypto.cpp b/version2/src/C/Crypto.cpp index 9fe1154..b1a3cb4 100755 --- a/version2/src/C/Crypto.cpp +++ b/version2/src/C/Crypto.cpp @@ -2,10 +2,29 @@ #include "pbkdf2-sha256.h" AESKey::AESKey(Array *password, Array *salt, int iterationCount, int keyLength) { - key = new Array(keyLength / 8); - PKCS5_PBKDF2_HMAC((unsigned char *) password->internalArray(), password->length(), - (unsigned char *) salt->internalArray(), salt->length(), - iterationCount, keyLength / 8, (unsigned char *) key->internalArray()); + + // Check if we get the same salt and password from EEPROM---create new ones otherwise + char saltBuffer[SALT_LEN], pwdBuffer[PWD_LEN], keyBuffer[KEY_LEN]; + EEPROM.get(ADDR_SALT, saltBuffer); + Array * storedSalt = new Array(saltBuffer, SALT_LEN); + EEPROM.get(ADDR_PWD, pwdBuffer); + Array * storedPwd = new Array(pwdBuffer, PWD_LEN); + if (storedSalt->equals(salt) && storedPwd->equals(password)) { // Take key from EEPROM if match + EEPROM.get(ADDR_KEY, keyBuffer); + key = new Array(keyBuffer, KEY_LEN); + delay(2000); // Delay for sensor + } else { // Generate a new key if not match + key = new Array(keyLength / 8); + PKCS5_PBKDF2_HMAC((unsigned char *) password->internalArray(), password->length(), + (unsigned char *) salt->internalArray(), salt->length(), + iterationCount, keyLength / 8, (unsigned char *) key->internalArray()); + // Store new salt and password into EEPROM---write all at once adjacently + char buffer[SALT_LEN + PWD_LEN + KEY_LEN]; + memcpy(buffer + SALT_OFFSET, (unsigned char *) salt->internalArray(), SALT_LEN); + memcpy(buffer + PWD_OFFSET, (unsigned char *) password->internalArray(), PWD_LEN); + memcpy(buffer + KEY_OFFSET, (unsigned char *) key->internalArray(), KEY_LEN); + EEPROM.put(ADDR_SALT, buffer); + } aes_key_setup((BYTE *)key->internalArray(), key_schedule, keyLength); } diff --git a/version2/src/C/Crypto.h b/version2/src/C/Crypto.h index 5334335..15931bd 100755 --- a/version2/src/C/Crypto.h +++ b/version2/src/C/Crypto.h @@ -2,6 +2,22 @@ #define CRYPTO_H #include "common.h" #include "aes.h" +#include "application.h" // Library for Particle/Arduino functions + +// Store these into EEPROM to avoid recalculating - crypto takes a lot of processing +// We store the 3 items in this order: +// 1) SALT +// 2) PASSWORD +// 3) LEN +#define SALT_LEN 8 // 8 bytes +#define PWD_LEN 12 // 12 bytes +#define KEY_LEN 16 // 16 bytes +#define ADDR_SALT 0 +#define ADDR_PWD (ADDR_SALT + SALT_LEN) +#define ADDR_KEY (ADDR_PWD + PWD_LEN) +#define SALT_OFFSET 0 +#define PWD_OFFSET (SALT_OFFSET + SALT_LEN) +#define KEY_OFFSET (PWD_OFFSET + PWD_LEN) class AESKey { public: diff --git a/version2/src/C/Sensor-Arduino.ino b/version2/src/C/Sensor-Arduino.ino index 6f5e3cf..5f3f10c 100644 --- a/version2/src/C/Sensor-Arduino.ino +++ b/version2/src/C/Sensor-Arduino.ino @@ -4,14 +4,19 @@ #include "TransactionStatus.h" #include "DHT.h" +SYSTEM_MODE(SEMI_AUTOMATIC) +SYSTEM_THREAD(ENABLED) + // System defines // Arduino -#define DHTPIN 2 // Data pin -#define PWRPIN D5 // Power pin -#define ERRPIN D7 // Error pin -#define DHTTYPE DHT22 // DHT 22 (AM2302) +#define DHTPIN 2 // Data pin +#define PWRPIN D5 // Power pin +#define ERRPIN D7 // Error pin +#define DHTTYPE DHT22 // DHT 22 (AM2302) // IoTCloud -#define SLEEP_TIME 10 // Sleep time in seconds +#define SLEEP_TIME 30 // Sleep time in seconds +#define RETRY_SLEEP_TIME 5 // Sleep time in seconds +#define RETRY_TIME 100000 // stop trying after 5 seconds // Initialize DHT sensor for normal 16mhz Arduino DHT dht(DHTPIN, DHTTYPE); @@ -26,14 +31,15 @@ char dataBuffer[80]; Table *t1; int64_t machineId; - void setup() { // TODO: // 1) Before running PHOTON's with this firmware, // please go to the master branch and run Init.C - // to initialize a table on the cloud side. + // in iotcloud/version2/src/C to initialize + // a table on the cloud side. // If you want to read the committed keys and values - // on the cloud, then you can use Read.java. + // on the cloud, then you can use Read.java in + // iotcloud/version2/src/java/simple_test. // 2) If you want to use the Serial library, // please install "screen" on your machine and run // it on the serial port right after flashing the @@ -43,10 +49,22 @@ void setup() { // We use one I/O pin to power the sensor so // that we can make it go to sleep when we go into // deep sleep. + + // TODO: Profiling! + //Serial.begin(); + //Serial.print("Time begin setup: "); + //Serial.println(micros()); + Particle.connect(); + // Wait for maximum 10 seconds - sleep if WiFi is not connected + // Wake up and try again after 5 seconds + if (!waitFor(Particle.connected, RETRY_TIME)) + System.sleep(SLEEP_MODE_DEEP, RETRY_SLEEP_TIME); + pinMode(PWRPIN, OUTPUT); // Turn on sensor digitalWrite(PWRPIN, HIGH); - + // Arduino DHT + dht.begin(); // Prepare device key from MAC (just last 2 of 6 digits) byte mac[6]; WiFi.macAddress(mac); @@ -68,20 +86,25 @@ void setup() { transStatusList = new MyVector(); IoTString *baseurl = new IoTString("http://dc-6.calit2.uci.edu/test.iotcloud/"); IoTString *password = new IoTString("reallysecret"); + + //Serial.print("Time begin rebuilding table: "); + //Serial.println(micros()); + t1 = new Table(baseurl, password, machineId, -1); t1->rebuild(); baseurl->releaseRef(); password->releaseRef(); - // Arduino DHT - dht.begin(); + //Serial.print("Time end setup: "); + //Serial.println(micros()); } void loop() { - // Wait until sensor is ready - delay(2000); + //delay(2000); + //Serial.print("Time begin loop: "); + //Serial.println(micros()); // Read humidity float humid = dht.readHumidity(); // Read temperature as Fahrenheit @@ -134,6 +157,11 @@ void loop() { // Turn off sensor digitalWrite(PWRPIN, LOW); + + //Serial.print("Time end loop: "); + //Serial.println(micros()); System.sleep(SLEEP_MODE_DEEP, SLEEP_TIME); + + //while(true) { } } -- 2.34.1