mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-06 05:21:22 +03:00
Use 2nd stack for update signature verification (#7149)
* Use 2nd stack for update signature verification Fixes #7145 When doing a signed update, the signature calculation can use a lot of stack, so move it silently to the BearSSL second stack. Also fix a memory leak of signature-bytes found by @JiriBilek * Reset state on any error condition in Updater::end
This commit is contained in:
parent
afb9921d38
commit
e252873263
@ -1,6 +1,7 @@
|
|||||||
#include "Updater.h"
|
#include "Updater.h"
|
||||||
#include "eboot_command.h"
|
#include "eboot_command.h"
|
||||||
#include <esp8266_peri.h>
|
#include <esp8266_peri.h>
|
||||||
|
#include "StackThunk.h"
|
||||||
|
|
||||||
//#define DEBUG_UPDATER Serial
|
//#define DEBUG_UPDATER Serial
|
||||||
|
|
||||||
@ -40,6 +41,14 @@ UpdaterClass::UpdaterClass()
|
|||||||
{
|
{
|
||||||
#if ARDUINO_SIGNING
|
#if ARDUINO_SIGNING
|
||||||
installSignature(&esp8266::updaterSigningHash, &esp8266::updaterSigningVerifier);
|
installSignature(&esp8266::updaterSigningHash, &esp8266::updaterSigningVerifier);
|
||||||
|
stack_thunk_add_ref();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdaterClass::~UpdaterClass()
|
||||||
|
{
|
||||||
|
#if ARDUINO_SIGNING
|
||||||
|
stack_thunk_del_ref();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,6 +208,7 @@ bool UpdaterClass::end(bool evenIfRemaining){
|
|||||||
#ifdef DEBUG_UPDATER
|
#ifdef DEBUG_UPDATER
|
||||||
DEBUG_UPDATER.println(F("no update"));
|
DEBUG_UPDATER.println(F("no update"));
|
||||||
#endif
|
#endif
|
||||||
|
_reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +216,6 @@ bool UpdaterClass::end(bool evenIfRemaining){
|
|||||||
#ifdef DEBUG_UPDATER
|
#ifdef DEBUG_UPDATER
|
||||||
DEBUG_UPDATER.printf_P(PSTR("premature end: res:%u, pos:%zu/%zu\n"), getError(), progress(), _size);
|
DEBUG_UPDATER.printf_P(PSTR("premature end: res:%u, pos:%zu/%zu\n"), getError(), progress(), _size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_reset();
|
_reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -226,6 +235,7 @@ bool UpdaterClass::end(bool evenIfRemaining){
|
|||||||
#endif
|
#endif
|
||||||
if (sigLen != _verify->length()) {
|
if (sigLen != _verify->length()) {
|
||||||
_setError(UPDATE_ERROR_SIGN);
|
_setError(UPDATE_ERROR_SIGN);
|
||||||
|
_reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,6 +261,7 @@ bool UpdaterClass::end(bool evenIfRemaining){
|
|||||||
uint8_t *sig = (uint8_t*)malloc(sigLen);
|
uint8_t *sig = (uint8_t*)malloc(sigLen);
|
||||||
if (!sig) {
|
if (!sig) {
|
||||||
_setError(UPDATE_ERROR_SIGN);
|
_setError(UPDATE_ERROR_SIGN);
|
||||||
|
_reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ESP.flashRead(_startAddress + binSize, (uint32_t *)sig, sigLen);
|
ESP.flashRead(_startAddress + binSize, (uint32_t *)sig, sigLen);
|
||||||
@ -262,9 +273,12 @@ bool UpdaterClass::end(bool evenIfRemaining){
|
|||||||
DEBUG_UPDATER.printf("\n");
|
DEBUG_UPDATER.printf("\n");
|
||||||
#endif
|
#endif
|
||||||
if (!_verify->verify(_hash, (void *)sig, sigLen)) {
|
if (!_verify->verify(_hash, (void *)sig, sigLen)) {
|
||||||
|
free(sig);
|
||||||
_setError(UPDATE_ERROR_SIGN);
|
_setError(UPDATE_ERROR_SIGN);
|
||||||
|
_reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
free(sig);
|
||||||
#ifdef DEBUG_UPDATER
|
#ifdef DEBUG_UPDATER
|
||||||
DEBUG_UPDATER.printf_P(PSTR("[Updater] Signature matches\n"));
|
DEBUG_UPDATER.printf_P(PSTR("[Updater] Signature matches\n"));
|
||||||
#endif
|
#endif
|
||||||
|
@ -53,6 +53,7 @@ class UpdaterClass {
|
|||||||
typedef std::function<void(size_t, size_t)> THandlerFunction_Progress;
|
typedef std::function<void(size_t, size_t)> THandlerFunction_Progress;
|
||||||
|
|
||||||
UpdaterClass();
|
UpdaterClass();
|
||||||
|
~UpdaterClass();
|
||||||
|
|
||||||
/* Optionally add a cryptographic signature verification hash and method */
|
/* Optionally add a cryptographic signature verification hash and method */
|
||||||
void installSignature(UpdaterHashClass *hash, UpdaterVerifyClass *verify) { _hash = hash; _verify = verify; }
|
void installSignature(UpdaterHashClass *hash, UpdaterVerifyClass *verify) { _hash = hash; _verify = verify; }
|
||||||
|
@ -870,9 +870,9 @@ uint32_t SigningVerifier::length()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SigningVerifier::verify(UpdaterHashClass *hash, const void *signature, uint32_t signatureLen) {
|
// We need to use the 2nd stack to do a verification, so do the thunk
|
||||||
if (!_pubKey || !hash || !signature || signatureLen != length()) return false;
|
// directly inside the class function for ease of use.
|
||||||
|
extern "C" bool SigningVerifier_verify(PublicKey *_pubKey, UpdaterHashClass *hash, const void *signature, uint32_t signatureLen) {
|
||||||
if (_pubKey->isRSA()) {
|
if (_pubKey->isRSA()) {
|
||||||
bool ret;
|
bool ret;
|
||||||
unsigned char vrf[hash->len()];
|
unsigned char vrf[hash->len()];
|
||||||
@ -890,6 +890,20 @@ bool SigningVerifier::verify(UpdaterHashClass *hash, const void *signature, uint
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !CORE_MOCK
|
||||||
|
make_stack_thunk(SigningVerifier_verify);
|
||||||
|
extern "C" bool thunk_SigningVerifier_verify(PublicKey *_pubKey, UpdaterHashClass *hash, const void *signature, uint32_t signatureLen);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool SigningVerifier::verify(UpdaterHashClass *hash, const void *signature, uint32_t signatureLen) {
|
||||||
|
if (!_pubKey || !hash || !signature || signatureLen != length()) return false;
|
||||||
|
#if !CORE_MOCK
|
||||||
|
return thunk_SigningVerifier_verify(_pubKey, hash, signature, signatureLen);
|
||||||
|
#else
|
||||||
|
return SigningVerifier_verify(_pubKey, hash, signature, signatureLen);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if !CORE_MOCK
|
#if !CORE_MOCK
|
||||||
|
|
||||||
// Second stack thunked helpers
|
// Second stack thunked helpers
|
||||||
|
Loading…
x
Reference in New Issue
Block a user