Skip to content

Use 2nd stack for update signature verification #7149

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 3 commits into from
Mar 14, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
16 changes: 15 additions & 1 deletion cores/esp8266/Updater.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "Updater.h"
#include "eboot_command.h"
#include <esp8266_peri.h>
#include "StackThunk.h"

//#define DEBUG_UPDATER Serial

Expand Down Expand Up @@ -40,6 +41,14 @@ UpdaterClass::UpdaterClass()
{
#if ARDUINO_SIGNING
installSignature(&esp8266::updaterSigningHash, &esp8266::updaterSigningVerifier);
stack_thunk_add_ref();
#endif
}

UpdaterClass::~UpdaterClass()
{
#if ARDUINO_SIGNING
stack_thunk_del_ref();
#endif
}

Expand Down Expand Up @@ -199,14 +208,14 @@ bool UpdaterClass::end(bool evenIfRemaining){
#ifdef DEBUG_UPDATER
DEBUG_UPDATER.println(F("no update"));
#endif
_reset();
return false;
}

if(hasError() || (!isFinished() && !evenIfRemaining)){
#ifdef DEBUG_UPDATER
DEBUG_UPDATER.printf_P(PSTR("premature end: res:%u, pos:%zu/%zu\n"), getError(), progress(), _size);
#endif

_reset();
return false;
}
Expand All @@ -226,6 +235,7 @@ bool UpdaterClass::end(bool evenIfRemaining){
#endif
if (sigLen != _verify->length()) {
_setError(UPDATE_ERROR_SIGN);
_reset();
return false;
}

Expand All @@ -251,6 +261,7 @@ bool UpdaterClass::end(bool evenIfRemaining){
uint8_t *sig = (uint8_t*)malloc(sigLen);
if (!sig) {
_setError(UPDATE_ERROR_SIGN);
_reset();
return false;
}
ESP.flashRead(_startAddress + binSize, (uint32_t *)sig, sigLen);
Expand All @@ -262,9 +273,12 @@ bool UpdaterClass::end(bool evenIfRemaining){
DEBUG_UPDATER.printf("\n");
#endif
if (!_verify->verify(_hash, (void *)sig, sigLen)) {
free(sig);
_setError(UPDATE_ERROR_SIGN);
_reset();
return false;
}
free(sig);
#ifdef DEBUG_UPDATER
DEBUG_UPDATER.printf_P(PSTR("[Updater] Signature matches\n"));
#endif
Expand Down
1 change: 1 addition & 0 deletions cores/esp8266/Updater.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class UpdaterClass {
typedef std::function<void(size_t, size_t)> THandlerFunction_Progress;

UpdaterClass();
~UpdaterClass();

/* Optionally add a cryptographic signature verification hash and method */
void installSignature(UpdaterHashClass *hash, UpdaterVerifyClass *verify) { _hash = hash; _verify = verify; }
Expand Down
20 changes: 17 additions & 3 deletions libraries/ESP8266WiFi/src/BearSSLHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -870,9 +870,9 @@ uint32_t SigningVerifier::length()
}
}

bool SigningVerifier::verify(UpdaterHashClass *hash, const void *signature, uint32_t signatureLen) {
if (!_pubKey || !hash || !signature || signatureLen != length()) return false;

// We need to use the 2nd stack to do a verification, so do the thunk
// 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()) {
bool ret;
unsigned char vrf[hash->len()];
Expand All @@ -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

// Second stack thunked helpers
Expand Down