1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-13 13:01:55 +03:00

Add MD5 to core, Fix OTA examples and Digest Authentication to OTA and espota.py

This commit is contained in:
Me No Dev
2015-11-09 00:42:30 +02:00
parent e613e42249
commit a8976a01fd
13 changed files with 518 additions and 247 deletions

View File

@ -0,0 +1,43 @@
#include "Arduino.h"
#include "md5.h"
#include "MD5Builder.h"
#define hex_char_to_byte(c) (((c)>='a'&&(c)<='f')?((c)-87):((c)>='A'&&(c)<='F')?((c)-55):((c)>='0'&&(c)<='9')?((c)-48):0)
void MD5Builder::begin(void){
memset(_buf, 0x00, 16);
MD5Init(&_ctx);
}
void MD5Builder::add(uint8_t * data, uint16_t len){
MD5Update(&_ctx, data, len);
}
void MD5Builder::addHexString(const char * data){
uint16_t i, len = strlen(data);
uint8_t * tmp = (uint8_t*)malloc(len/2);
if(tmp == NULL)
return;
for(i=0; i<len; i+=2) tmp[i/2] = (hex_char_to_byte(data[i]) & 0x0F) << 4 | (hex_char_to_byte(data[i+1]) & 0x0F);
add(tmp, len/2);
free(tmp);
}
void MD5Builder::calculate(void){
MD5Final(_buf, &_ctx);
}
void MD5Builder::getBytes(uint8_t * output){
memcpy(output, _buf, 16);
}
void MD5Builder::getChars(char * output){
for(uint8_t i = 0; i < 16; i++)
sprintf(output + (i * 2), "%02x", _buf[i]);
}
String MD5Builder::toString(void){
char out[32];
getChars(out);
return String(out);
}

View File

@ -0,0 +1,47 @@
/*
md5.h - exposed md5 ROM functions for esp8266
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __ESP8266_MD5_BUILDER__
#define __ESP8266_MD5_BUILDER__
#include "Arduino.h"
#include "md5.h"
class MD5Builder {
private:
md5_context_t _ctx;
uint8_t _buf[16];
public:
void begin(void);
void add(uint8_t * data, uint16_t len);
void add(const char * data){ add((uint8_t*)data, strlen(data)); }
void add(char * data){ add((const char*)data); }
void add(String data){ add(data.c_str()); }
void addHexString(const char * data);
void addHexString(char * data){ addHexString((const char*)data); }
void addHexString(String data){ addHexString(data.c_str()); }
void calculate(void);
void getBytes(uint8_t * output);
void getChars(char * output);
String toString(void);
};
#endif

View File

@ -32,6 +32,7 @@ void UpdaterClass::_reset() {
_currentAddress = 0;
_size = 0;
_command = U_FLASH;
_target_md5 = 0;
}
bool UpdaterClass::begin(size_t size, int command) {
@ -96,10 +97,17 @@ bool UpdaterClass::begin(size_t size, int command) {
_size = size;
_buffer = new uint8_t[FLASH_SECTOR_SIZE];
_command = command;
_target_md5 = new char[64];
_md5.begin();
return true;
}
void UpdaterClass::setMD5(const char * expected_md5){
if(strlen(expected_md5) != 32) return;
strcpy(_target_md5, expected_md5);
}
bool UpdaterClass::end(bool evenIfRemaining){
if(_size == 0){
#ifdef DEBUG_UPDATER
@ -123,7 +131,21 @@ bool UpdaterClass::end(bool evenIfRemaining){
}
_size = progress();
}
_md5.calculate();
if(_target_md5 && strlen(_target_md5) == 32){
if(strcmp(_target_md5, _md5.toString().c_str()) != 0){
_error = UPDATE_ERROR_MD5;
#ifdef DEBUG_UPDATER
DEBUG_UPDATER.printf("MD5 Failed: expected:%s, calculated:%s\n", _target_md5, _md5.toString().c_str());
#endif
return false;
}
#ifdef DEBUG_UPDATER
else DEBUG_UPDATER.printf("MD5 Success: %s\n", _md5.toString().c_str());
#endif
}
if (_command == U_FLASH) {
eboot_command ebcmd;
ebcmd.action = ACTION_COPY_RAW;
@ -157,6 +179,7 @@ bool UpdaterClass::_writeBuffer(){
#endif
return false;
}
_md5.add(_buffer, _bufferLen);
_currentAddress += _bufferLen;
_bufferLen = 0;
return true;
@ -232,6 +255,8 @@ void UpdaterClass::printError(Stream &out){
out.println("Bad Size Given");
} else if(_error == UPDATE_ERROR_STREAM){
out.println("Stream Read Timeout");
} else if(_error == UPDATE_ERROR_MD5){
out.println("MD5 Check Failed");
} else {
out.println("UNKNOWN");
}

View File

@ -3,6 +3,7 @@
#include "Arduino.h"
#include "flash_utils.h"
#include "MD5Builder.h"
#define UPDATE_ERROR_OK 0
#define UPDATE_ERROR_WRITE 1
@ -10,11 +11,12 @@
#define UPDATE_ERROR_SPACE 3
#define UPDATE_ERROR_SIZE 4
#define UPDATE_ERROR_STREAM 5
#define UPDATE_ERROR_MD5 6
#define U_FLASH 0
#define U_SPIFFS 100
//#define DEBUG_UPDATER Serial1
//#define DEBUG_UPDATER Serial
class UpdaterClass {
public:
@ -56,7 +58,22 @@ class UpdaterClass {
Prints the last error to an output stream
*/
void printError(Stream &out);
/*
sets the expected MD5 for the firmware (hexString)
*/
void setMD5(const char * expected_md5);
/*
returns the MD5 String of the sucessfully ended firmware
*/
String md5String(void){ return _md5.toString(); }
/*
populated the result with the md5 bytes of the sucessfully ended firmware
*/
void md5(uint8_t * result){ return _md5.getBytes(result); }
//Helpers
uint8_t getError(){ return _error; }
void clearError(){ _error = UPDATE_ERROR_OK; }
@ -120,6 +137,9 @@ class UpdaterClass {
uint32_t _startAddress;
uint32_t _currentAddress;
uint32_t _command;
char *_target_md5;
MD5Builder _md5;
};
extern UpdaterClass Update;

44
cores/esp8266/md5.h Normal file
View File

@ -0,0 +1,44 @@
/*
md5.h - exposed md5 ROM functions for esp8266
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
original C source from https://github.com/morrissinger/ESP8266-Websocket/raw/master/MD5.h
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __ESP8266_MD5__
#define __ESP8266_MD5__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
uint32_t state[4];
uint32_t count[2];
uint8_t buffer[64];
} md5_context_t;
extern void MD5Init (md5_context_t *);
extern void MD5Update (md5_context_t *, uint8_t *, uint16_t);
extern void MD5Final (uint8_t [16], md5_context_t *);
#ifdef __cplusplus
} // extern "C"
#endif
#endif