Skip to content

Guard crypto parts in "Update" to save resources #10630

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion libraries/Update/src/Update.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class UpdateClass {
*/
bool begin(size_t size = UPDATE_SIZE_UNKNOWN, int command = U_FLASH, int ledPin = -1, uint8_t ledOn = LOW, const char *label = NULL);

#ifdef UPDATE_CRYPT
/*
Setup decryption configuration
Crypt Key is 32bytes(256bits) block of data, use the same key as used to encrypt image file
Expand All @@ -71,6 +72,7 @@ class UpdateClass {
Crypt Mode, used to select if image files should be decrypted or not
*/
bool setupCrypt(const uint8_t *cryptKey = 0, size_t cryptAddress = 0, uint8_t cryptConfig = 0xf, int cryptMode = U_AES_DECRYPT_AUTO);
#endif /* UPDATE_CRYPT */

/*
Writes a buffer to the flash and increments the address
Expand Down Expand Up @@ -99,6 +101,7 @@ class UpdateClass {
*/
bool end(bool evenIfRemaining = false);

#ifdef UPDATE_CRYPT
/*
sets AES256 key(32 bytes) used for decrypting image file
*/
Expand All @@ -122,6 +125,7 @@ class UpdateClass {
void setCryptConfig(const uint8_t cryptConfig) {
_cryptCfg = cryptConfig & 0x0f;
}
#endif /* UPDATE_CRYPT */

/*
Aborts the running update
Expand All @@ -139,7 +143,11 @@ class UpdateClass {
sets the expected MD5 for the firmware (hexString)
If calc_post_decryption is true, the update library will calculate the MD5 after the decryption, if false the calculation occurs before the decryption
*/
bool setMD5(const char *expected_md5, bool calc_post_decryption = true);
bool setMD5(const char *expected_md5
#ifdef UPDATE_CRYPT
, bool calc_post_decryption = true
#endif /* #ifdef UPDATE_CRYPT */
);

/*
returns the MD5 String of the successfully ended firmware
Expand Down Expand Up @@ -236,17 +244,21 @@ class UpdateClass {
private:
void _reset();
void _abort(uint8_t err);
#ifdef UPDATE_CRYPT
void _cryptKeyTweak(size_t cryptAddress, uint8_t *tweaked_key);
bool _decryptBuffer();
#endif /* UPDATE_CRYPT */
bool _writeBuffer();
bool _verifyHeader(uint8_t data);
bool _verifyEnd();
bool _enablePartition(const esp_partition_t *partition);
bool _chkDataInBlock(const uint8_t *data, size_t len) const; // check if block contains any data or is empty

uint8_t _error;
#ifdef UPDATE_CRYPT
uint8_t *_cryptKey;
uint8_t *_cryptBuffer;
#endif /* UPDATE_CRYPT */
uint8_t *_buffer;
uint8_t *_skipBuffer;
size_t _bufferLen;
Expand All @@ -258,15 +270,19 @@ class UpdateClass {
const esp_partition_t *_partition;

String _target_md5;
#ifdef UPDATE_CRYPT
bool _target_md5_decrypted = true;
#endif /* UPDATE_CRYPT */
MD5Builder _md5;

int _ledPin;
uint8_t _ledOn;

#ifdef UPDATE_CRYPT
uint8_t _cryptMode;
size_t _cryptAddress;
uint8_t _cryptCfg;
#endif /* UPDATE_CRYPT */
};

#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_UPDATE)
Expand Down
39 changes: 36 additions & 3 deletions libraries/Update/src/Updater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
#include "spi_flash_mmap.h"
#include "esp_ota_ops.h"
#include "esp_image_format.h"
#ifdef UPDATE_CRYPT
#include "mbedtls/aes.h"
#endif /* UPDATE_CRYPT */

static const char *_err2str(uint8_t _error) {
if (_error == UPDATE_ERROR_OK) {
Expand Down Expand Up @@ -38,8 +40,10 @@ static const char *_err2str(uint8_t _error) {
return ("Bad Argument");
} else if (_error == UPDATE_ERROR_ABORT) {
return ("Aborted");
#ifdef UPDATE_CRYPT
} else if (_error == UPDATE_ERROR_DECRYPT) {
return ("Decryption error");
#endif /* UPDATE_CRYPT */
}
return ("UNKNOWN");
}
Expand Down Expand Up @@ -67,8 +71,15 @@ bool UpdateClass::_enablePartition(const esp_partition_t *partition) {
}

UpdateClass::UpdateClass()
: _error(0), _cryptKey(0), _cryptBuffer(0), _buffer(0), _skipBuffer(0), _bufferLen(0), _size(0), _progress_callback(NULL), _progress(0), _paroffset(0),
_command(U_FLASH), _partition(NULL), _cryptMode(U_AES_DECRYPT_AUTO), _cryptAddress(0), _cryptCfg(0xf) {}
: _error(0),
#ifdef UPDATE_CRYPT
_cryptKey(0), _cryptBuffer(0),
#endif /* UPDATE_CRYPT */
_buffer(0), _skipBuffer(0), _bufferLen(0), _size(0), _progress_callback(NULL), _progress(0), _paroffset(0), _command(U_FLASH), _partition(NULL)
#ifdef UPDATE_CRYPT
, _cryptMode(U_AES_DECRYPT_AUTO), _cryptAddress(0), _cryptCfg(0xf)
#endif /* UPDATE_CRYPT */
{}

UpdateClass &UpdateClass::onProgress(THandlerFunction_Progress fn) {
_progress_callback = fn;
Expand All @@ -83,7 +94,9 @@ void UpdateClass::_reset() {
delete[] _skipBuffer;
}

#ifdef UPDATE_CRYPT
_cryptBuffer = nullptr;
#endif /* UPDATE_CRYPT */
_buffer = nullptr;
_skipBuffer = nullptr;
_bufferLen = 0;
Expand Down Expand Up @@ -175,6 +188,7 @@ bool UpdateClass::begin(size_t size, int command, int ledPin, uint8_t ledOn, con
return true;
}

#ifdef UPDATE_CRYPT
bool UpdateClass::setupCrypt(const uint8_t *cryptKey, size_t cryptAddress, uint8_t cryptConfig, int cryptMode) {
if (setCryptKey(cryptKey)) {
if (setCryptMode(cryptMode)) {
Expand Down Expand Up @@ -216,6 +230,7 @@ bool UpdateClass::setCryptMode(const int cryptMode) {
}
return true;
}
#endif /* UPDATE_CRYPT */

void UpdateClass::_abort(uint8_t err) {
_reset();
Expand All @@ -226,6 +241,7 @@ void UpdateClass::abort() {
_abort(UPDATE_ERROR_ABORT);
}

#ifdef UPDATE_CRYPT
void UpdateClass::_cryptKeyTweak(size_t cryptAddress, uint8_t *tweaked_key) {
memcpy(tweaked_key, _cryptKey, ENCRYPTED_KEY_SIZE);
if (_cryptCfg == 0) {
Expand Down Expand Up @@ -338,8 +354,10 @@ bool UpdateClass::_decryptBuffer() {
}
return true;
}
#endif /* UPDATE_CRYPT */

bool UpdateClass::_writeBuffer() {
#ifdef UPDATE_CRYPT
//first bytes of loading image, check to see if loading image needs decrypting
if (!_progress) {
_cryptMode &= U_AES_DECRYPT_MODE_MASK;
Expand All @@ -360,6 +378,7 @@ bool UpdateClass::_writeBuffer() {
return false;
}
}
#endif /* UPDATE_CRYPT */
//first bytes of new firmware
uint8_t skip = 0;
if (!_progress && _command == U_FLASH) {
Expand Down Expand Up @@ -409,9 +428,13 @@ bool UpdateClass::_writeBuffer() {
if (!_progress && _command == U_FLASH) {
_buffer[0] = ESP_IMAGE_HEADER_MAGIC;
}
#ifdef UPDATE_CRYPT
if (_target_md5_decrypted) {
#endif /* UPDATE_CRYPT */
_md5.add(_buffer, _bufferLen);
#ifdef UPDATE_CRYPT
}
#endif /* UPDATE_CRYPT */
_progress += _bufferLen;
_bufferLen = 0;
if (_progress_callback) {
Expand Down Expand Up @@ -453,13 +476,19 @@ bool UpdateClass::_verifyEnd() {
return false;
}

bool UpdateClass::setMD5(const char *expected_md5, bool calc_post_decryption) {
bool UpdateClass::setMD5(const char *expected_md5
#ifdef UPDATE_CRYPT
,bool calc_post_decryption
#endif /* UPDATE_CRYPT */
) {
if (strlen(expected_md5) != 32) {
return false;
}
_target_md5 = expected_md5;
_target_md5.toLowerCase();
#ifdef UPDATE_CRYPT
_target_md5_decrypted = calc_post_decryption;
#endif /* UPDATE_CRYPT */
return true;
}

Expand Down Expand Up @@ -532,12 +561,16 @@ size_t UpdateClass::writeStream(Stream &data) {
return 0;
}

#ifdef UPDATE_CRYPT
if (_command == U_FLASH && !_cryptMode) {
#endif /* UPDATE_CRYPT */
if (!_verifyHeader(data.peek())) {
_reset();
return 0;
}
#ifdef UPDATE_CRYPT
}
#endif /* UPDATE_CRYPT */

if (_ledPin != -1) {
pinMode(_ledPin, OUTPUT);
Expand Down
Loading