Skip to content

Commit

Permalink
Merge pull request #9 from Firmware-Forge/dev
Browse files Browse the repository at this point in the history
Updates from Dev
  • Loading branch information
Patrick Shinn committed Jan 25, 2020
2 parents db53c76 + 25efe20 commit 1129ef9
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 738 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
@@ -0,0 +1,18 @@
# Changelog
All major changes made to the FFUpdates Library that resulted in a version increment on Platformio
**Please note that all alpha releases are not tagged, only release candidates and full versions are tagged.**

## 0.33a - 2020-01-25

### Added

* Changelog

### Changed

* Moved to BearSSL for SHA256 Hash calculation from Arduino Crypto
* Moved to BearSSL for AES256 crypto operations from tiny-AES-c

### Removed

* tiny-AES-c library header and c files
4 changes: 2 additions & 2 deletions examples/example.cpp
Expand Up @@ -28,5 +28,5 @@ void setup() {
void loop() {
Serial.println("Checking for an update");
updater.update(); // check for an update, apply it if one exists.
delay(5000);
}
delay(5000); // check once every 5 seconds.
}
8 changes: 1 addition & 7 deletions library.json
Expand Up @@ -12,15 +12,9 @@
"url": "https://patrick-shinn.com",
"maintainer": true
},
"version": "0.32a",
"version": "0.33a",
"platforms": "espressif8266",
"frameworks": "arduino",
"dependencies":[
{
"name": "Crypto",
"frameworks": "arduino"
}
],
"export": {
"include":[
"src",
Expand Down
71 changes: 41 additions & 30 deletions src/FFUpdates.cpp
@@ -1,41 +1,59 @@
#include "FFUpdates.h"
#include <bearssl/bearssl.h>
#include <bearssl/bearssl_block.h>
#include <bearssl/bearssl_hash.h>
#include <ESP8266httpUpdate.h>
#include <SHA256.h>
#include "aes.hpp"

FFUpdates::FFUpdates() : user_token{"Not Set"}, user_secret{"Not Set"}, token_SHA256{"Not Set"}{
// do nothing, variables are initialized in the initialization list
}

FFUpdates::FFUpdates(String user_token, String user_secret) : user_token{user_token}, user_secret{user_secret}{
SHA256 token_hash;
uint8_t value[32];
br_sha256_context ctx;
uint8_t outputbuf[32];
String expect = ""; // wipe it for reuse

token_hash.reset();
token_hash.update(user_token.c_str(), strlen(user_token.c_str()));
token_hash.update(user_secret.c_str(), strlen(user_secret.c_str()));
token_hash.finalize(value, 32);
// calculate sha256 using BearSSL builtins.
br_sha256_init(&ctx);
br_sha256_update(&ctx, user_token.c_str(), 32);
br_sha256_update(&ctx, user_secret.c_str(), 32);
br_sha256_out(&ctx, outputbuf);

for(int i = 0; i < 32; i ++){
if(value[i] < 16) expect += ("0" + String(value[i], HEX)); // ensures we use two hex values to represent each block
else expect += String(value[i], HEX);
if(outputbuf[i] < 16) expect += ("0" + String(outputbuf[i], HEX)); // ensures we use two hex values to represent each block
else expect += String(outputbuf[i], HEX);
}
FFUpdates::token_SHA256 = expect;

// create the encryption key
user_secret = ""; // wipe this for reuse
for(int i = 0; i < 32; i++) user_secret += FFUpdates::user_secret[i]; // get the first 32 chars
user_secret.toCharArray((char*)&key, user_secret.length() + 1);
}

FFUpdates::~FFUpdates(){
//todo implement?
// Handled by the compiler
}

void FFUpdates::enable_debug(bool debug){
FFUpdates::debug = debug;
Serial.println("============================================");
Serial.print("Firmware Forge Updates Library version ");
Serial.println(FFUpdates::version);
Serial.println("--------------------------------------------");
Serial.println("| |");
Serial.println("| ## ### ##((( // |");
Serial.println("| ## ((((((((((((//// |");
Serial.println("| # ## (((((# |");
Serial.println("| # (( (((((( |");
Serial.println("| |");
Serial.println("| ######((((((((((((///////////// |");
Serial.println("| #####((((((((((((//////////// |");
Serial.println("| ##((((((((((((///////// |");
Serial.println("| ((((((((////////// |");
Serial.println("| (((////////// |");
Serial.println("| ((((((/////////////// |");
Serial.println("| (((((//////////////// |");
Serial.println("| |");
Serial.println("--------------------------------------------");
if(debug) Serial.println("Debug Enabled");
else Serial.println("Debug Disabled");
Serial.println("============================================");
}

String FFUpdates::get_user_token(){
Expand Down Expand Up @@ -70,22 +88,15 @@ void FFUpdates::set_fingerprint(String fingerprint){
FFUpdates::fingerprint = fingerprint;
}

byte* FFUpdates::get_encryption_key(){
return key;
}

void FFUpdates::set_encryption_key(byte* key){
for(int i = 0; i < 33; i ++) FFUpdates::key[i] = key[i];
}

void FFUpdates::print_SHA256(){
Serial.println(FFUpdates::token_SHA256);
}

void FFUpdates::renewFingerprint(){
BearSSL::WiFiClientSecure client;
String message, buffer, challenge_token, new_fingerprint, iv;
byte iv_int[33], challenge_token_int[65]; // the strings are 32 and 64 chars long, but save a space for the null terminator
byte iv_int[16]; // iv from the server comes as 32 chars, but is hex, so actual length is 16.
byte challenge_token_int[80]; // the challenge token from the server is 160 chars long, but is hex, so actual size is 80.

if(FFUpdates::debug){
Serial.print("connecting to ");
Expand Down Expand Up @@ -147,18 +158,19 @@ void FFUpdates::renewFingerprint(){
value[1] = challenge_token[i + 1];
challenge_token_int[index] = strtol(value, NULL, 16);
}

index = 0;
for(uint i = 0; i < iv.length(); i += 2, index ++){
char value[2];
value[0] = iv[i];
value[1] = iv[i + 1];
iv_int[index] = strtol(value, NULL, 16);
}

// decrypt the message
AES_ctx ctx;
AES_init_ctx_iv(&ctx, FFUpdates::key, iv_int);
AES_CBC_decrypt_buffer(&ctx, challenge_token_int, 64);
br_aes_ct_cbcdec_keys ctx;
br_aes_ct_cbcdec_init(&ctx, FFUpdates::user_secret.c_str(), 32);
br_aes_ct_cbcdec_run(&ctx, iv_int, challenge_token_int, 64);

challenge_token = ""; // wipe and populate with the decrypted value
for(uint i = 0; i < 64; i++){
Expand Down Expand Up @@ -198,7 +210,6 @@ bool FFUpdates::handle_update(){
client.setFingerprint(FFUpdates::fingerprint.c_str());

t_httpUpdate_return ret = ESPhttpUpdate.update(client, FFUpdates::update_url, FFUpdates::user_token);
Serial.println(ESPhttpUpdate.getLastErrorString());
switch(ret){
case HTTP_UPDATE_FAILED:
Serial.println("Firmware update failed.");
Expand Down
23 changes: 3 additions & 20 deletions src/FFUpdates.h
Expand Up @@ -10,12 +10,12 @@ class FFUpdates{
private:
String user_token;
String user_secret;
String fingerprint = "";
String token_SHA256;
byte key[33];
String fingerprint = "";
const char* update_host = "firmwareforge.com";
const char* update_url = "https://firmwareforge.com/devices/update";
const char* finger_url = "/devices/fingerprint";
const char* finger_url = "/devices/fingerprint";
const char* version = "0.33a";
bool debug = false;

/**
Expand All @@ -28,7 +28,6 @@ class FFUpdates{
bool handle_update();

public:

/**
* Default Constructor for the FFUpdates class. Creates the object but does not intialize any data.
* Requires the user to provide the token_SHA256 and user_token via the set methods.
Expand Down Expand Up @@ -110,22 +109,6 @@ class FFUpdates{
*/
void print_SHA256();

/**
* Gets the encryption key. Please note that you should iterate through this pointer and store the values
* as a byte array. Storing this pointer in memory will not preserve the data through a reset as the
* pointer will be pointing to empty memory. The length of the key is 33.
*
* @return encryption key byte array pointer
*/
byte* get_encryption_key();

/**
* Sets the encryption key. The array passed should be of length 33.
*
* @param key byte array pointer.
*/
void set_encryption_key(byte* key);

/**
* Gets the stored server fingerprint.
*
Expand Down
6 changes: 1 addition & 5 deletions src/README
@@ -1,5 +1 @@
All credit for AES library goes to Github user kokke (https://github.com/kokke)
The original repo can be found here https://github.com/kokke/tiny-AES-c

The only reason it is packed with Firmware Forge ESP8266 Updater is because a header file must be modified
from this library to enable AES256, which FFUpdates needs.
ESP8266 Over the Air Updates Library for Firmware Forge. Please visit [the docs](https://esp8266-updater.readthedocs.io/en/latest/) for more info.

0 comments on commit 1129ef9

Please sign in to comment.