ota: remove write-through pointer members from ota context struct
What changed, and why it matters
This commit is a straightforward internal code cleanup in the firmware update (OTA) module. It removes an unnecessary layer of pointers inside the OTA context structure, storing values directly instead of pointing to separate local variables. There is no indication this fixes a security bug or changes security behavior.
No security action required. Treat as a normal refactoring commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors jade_ota_ctx_t so that several members (sha_ctx, ota_handle, ota_return_status, validated_confirmed, remaining_uncompressed, expected_source) are stored by value rather than as write-through pointers to caller-owned stack variables. Call sites are updated to use direct member access (e.g., joctx->ota_handle instead of *joctx->ota_handle). It also moves the ota_status_t typedef/enum into the header and adds an ota_free() helper that frees the now-embedded mbedtls_sha256_context. The change is purely structural and reduces stack usage; no security logic is altered.
Changed components
main/process/ota.cmain/process/ota_delta.cmain/process/ota_util.cmain/process/ota_util.hInspect captured patch +130 / −139
diff --git a/main/process/ota.c b/main/process/ota.c
index 5fd0456..eb166d7 100644
--- a/main/process/ota.c
+++ b/main/process/ota.c
@@ -31,41 +31,41 @@ static int uncompressed_stream_writer(void* ctx, uint8_t* uncompressed, size_t l
jade_ota_ctx_t* joctx = (jade_ota_ctx_t*)ctx;
- if (!*joctx->validated_confirmed && length >= CUSTOM_HEADER_MIN_WRITE) {
- const enum ota_status res = ota_user_validation(joctx, uncompressed);
+ if (!joctx->validated_confirmed && length >= CUSTOM_HEADER_MIN_WRITE) {
+ const ota_status_t res = ota_user_validation(joctx, uncompressed);
if (res != OTA_SUCCESS) {
JADE_LOGE("ota_user_validation() error, %u", res);
- *joctx->ota_return_status = res;
+ joctx->ota_return_status = res;
return res;
}
- *joctx->validated_confirmed = true;
+ joctx->validated_confirmed = true;
}
- const esp_err_t res = esp_ota_write(*joctx->ota_handle, (const void*)uncompressed, length);
+ const esp_err_t res = esp_ota_write(joctx->ota_handle, (const void*)uncompressed, length);
if (res != ESP_OK) {
JADE_LOGE("ota_write() error: %u", res);
- *joctx->ota_return_status = OTA_ERR_WRITE;
+ joctx->ota_return_status = OTA_ERR_WRITE;
return DEFLATE_ERROR;
}
if (joctx->hash_type == HASHTYPE_FULLFWDATA) {
// Add written to hash calculation
- JADE_ZERO_VERIFY(mbedtls_sha256_update(joctx->sha_ctx, uncompressed, length));
+ JADE_ZERO_VERIFY(mbedtls_sha256_update(&joctx->sha_ctx, uncompressed, length));
}
- *joctx->remaining_uncompressed -= length;
+ joctx->remaining_uncompressed -= length;
joctx->fwwritten += length;
// For a full ota, the amount of fw data uncompressed should always be equal to the
// amount of new firmware we have written, as it should be the same thing.
- JADE_ASSERT(joctx->uncompressedsize - *joctx->remaining_uncompressed == joctx->fwwritten);
+ JADE_ASSERT(joctx->uncompressedsize - joctx->remaining_uncompressed == joctx->fwwritten);
- if (joctx->fwwritten > CUSTOM_HEADER_MIN_WRITE && !*joctx->validated_confirmed) {
+ if (joctx->fwwritten > CUSTOM_HEADER_MIN_WRITE && !joctx->validated_confirmed) {
return DEFLATE_ERROR;
}
/* Update the progress bar once the user has confirmed and upload is in progress */
- if (*joctx->validated_confirmed) {
+ if (joctx->validated_confirmed) {
JADE_ASSERT(joctx->progress_bar.progress_bar);
update_progress_bar(&joctx->progress_bar, joctx->uncompressedsize, joctx->fwwritten);
}
@@ -79,14 +79,8 @@ void ota_process(void* process_ptr)
jade_process_t* process = process_ptr;
bool uploading = false;
- enum ota_status ota_return_status = OTA_ERR_SETUP;
- bool validated_confirmed = false;
bool ota_end_called = false;
- // Context used to compute (compressed) firmware hash - ie. file as uploaded
- mbedtls_sha256_context sha_ctx;
- esp_ota_handle_t ota_handle = 0;
-
// We expect a current message to be present
ASSERT_CURRENT_MESSAGE(process, "ota");
GET_MSG_PARAMS(process);
@@ -134,26 +128,24 @@ void ota_process(void* process_ptr)
struct deflate_ctx* dctx = JADE_MALLOC_PREFER_SPIRAM(sizeof(struct deflate_ctx));
jade_process_free_on_exit(process, dctx);
- size_t remaining_uncompressed = firmwaresize;
-
jade_ota_ctx_t joctx = {
- .progress_bar = {},
- .sha_ctx = &sha_ctx,
+ .sha_ctx = {},
+ .progress_bar = {0},
.hash_type = hash_type,
.dctx = dctx,
.id = { 0 },
- .validated_confirmed = &validated_confirmed,
.uncompressedsize = firmwaresize,
- .remaining_uncompressed = &remaining_uncompressed,
- .ota_return_status = &ota_return_status,
- .expected_source = &ota_source,
+ .remaining_uncompressed = firmwaresize,
+ .ota_return_status = OTA_ERR_SETUP,
+ .expected_source = ota_source,
.remaining_compressed = compressedsize,
.compressedsize = compressedsize,
- .ota_handle = &ota_handle,
+ .ota_handle = 0,
.firmwaresize = firmwaresize,
.expected_hash_hexstr = expected_hash_hexstr,
.expected_hash = expected_hash,
.extended_replies = extended_replies,
+ .validated_confirmed = false,
};
if (!ota_init(&joctx)) {
@@ -168,29 +160,29 @@ void ota_process(void* process_ptr)
jade_process_reply_to_message_ok(process);
uploading = true;
- ota_return_status = OTA_SUCCESS;
+ joctx.ota_return_status = OTA_SUCCESS;
while (joctx.remaining_compressed) {
jade_process_get_in_message(&joctx, &handle_in_bin_data, true);
// NOTE: the ota_return_status can be set via ptr in joctx
- if (ota_return_status != OTA_SUCCESS) {
- JADE_LOGE("Error on ota_data message: %d", ota_return_status);
+ if (joctx.ota_return_status != OTA_SUCCESS) {
+ JADE_LOGE("Error on ota_data message: %d", joctx.ota_return_status);
goto cleanup;
}
}
- JADE_ASSERT(validated_confirmed);
+ JADE_ASSERT(joctx.validated_confirmed);
// Uploading complete
uploading = false;
// Bail-out if the fw uncompressed to an unexpected size
- if (remaining_uncompressed != 0) {
- JADE_LOGE("Expected uncompressed size: %u, got %u", firmwaresize, firmwaresize - remaining_uncompressed);
- ota_return_status = OTA_ERR_DECOMPRESS;
+ if (joctx.remaining_uncompressed != 0) {
+ JADE_LOGE("Expected uncompressed size: %u, got %u", firmwaresize, firmwaresize - joctx.remaining_uncompressed);
+ joctx.ota_return_status = OTA_ERR_DECOMPRESS;
}
if (joctx.fwwritten != firmwaresize) {
JADE_LOGE("Expected amountof firmware written: %u, expected %u", joctx.fwwritten, firmwaresize);
- ota_return_status = OTA_ERR_DECOMPRESS;
+ joctx.ota_return_status = OTA_ERR_DECOMPRESS;
}
// Expect a complete/request for status
@@ -203,14 +195,14 @@ void ota_process(void* process_ptr)
// If all good with the upload do all final checks and then finalise the ota
// and set the new boot partition, etc.
- if (ota_return_status == OTA_SUCCESS) {
- ota_return_status = post_ota_check(&joctx, &ota_end_called);
+ if (joctx.ota_return_status == OTA_SUCCESS) {
+ joctx.ota_return_status = post_ota_check(&joctx, &ota_end_called);
}
// Send final message reply with final status
- if (ota_return_status != OTA_SUCCESS) {
+ if (joctx.ota_return_status != OTA_SUCCESS) {
uint8_t buf[256];
- const char* error = ota_get_status_text(ota_return_status);
+ const char* error = ota_get_status_text(joctx.ota_return_status);
jade_process_reject_message_ex(process->ctx, CBOR_RPC_INTERNAL_ERROR, "Error completing OTA",
(const uint8_t*)error, strlen(error), buf, sizeof(buf));
goto cleanup;
@@ -221,11 +213,11 @@ void ota_process(void* process_ptr)
JADE_LOGI("Success");
cleanup:
- mbedtls_sha256_free(&sha_ctx);
+ ota_free(&joctx);
// If ota has been successful show message and reboot.
// If error, show error-message and await user acknowledgement.
- if (ota_return_status == OTA_SUCCESS) {
+ if (joctx.ota_return_status == OTA_SUCCESS) {
JADE_LOGW("OTA successful - rebooting");
const char* message[] = { "Upgrade successful!" };
@@ -234,19 +226,19 @@ cleanup:
vTaskDelay(2500 / portTICK_PERIOD_MS);
esp_restart();
} else {
- JADE_LOGE("OTA error %u: %s", ota_return_status, ota_get_status_text(ota_return_status));
- if (validated_confirmed && !ota_end_called) {
+ JADE_LOGE("OTA error %u: %s", joctx.ota_return_status, ota_get_status_text(joctx.ota_return_status));
+ if (joctx.validated_confirmed && !ota_end_called) {
// ota_begin has been called, cleanup
- const esp_err_t err = esp_ota_abort(ota_handle);
+ const esp_err_t err = esp_ota_abort(joctx.ota_handle);
JADE_ASSERT(err == ESP_OK);
}
// If we get here and we have not finished loading the data, send an error message
- const char* status_text = ota_get_status_text(ota_return_status);
+ const char* status_text = ota_get_status_text(joctx.ota_return_status);
if (uploading) {
JADE_ASSERT(joctx.id[0] != '\0');
const int error_code
- = ota_return_status == OTA_ERR_USERDECLINED ? CBOR_RPC_USER_CANCELLED : CBOR_RPC_INTERNAL_ERROR;
+ = joctx.ota_return_status == OTA_ERR_USERDECLINED ? CBOR_RPC_USER_CANCELLED : CBOR_RPC_INTERNAL_ERROR;
uint8_t buf[256];
jade_process_reject_message_with_id(joctx.id, error_code, "Error uploading OTA data",
@@ -254,7 +246,7 @@ cleanup:
}
// If the error is not 'did not start' or 'user declined', show an error screen
- if (ota_return_status != OTA_ERR_SETUP && ota_return_status != OTA_ERR_USERDECLINED) {
+ if (joctx.ota_return_status != OTA_ERR_SETUP && joctx.ota_return_status != OTA_ERR_USERDECLINED) {
await_error_activity(&status_text, 1);
}
}
diff --git a/main/process/ota_delta.c b/main/process/ota_delta.c
index a652b6a..b10a510 100644
--- a/main/process/ota_delta.c
+++ b/main/process/ota_delta.c
@@ -34,7 +34,7 @@
// the next time we receive a message and have the opportunity to reply.
#define HANDLE_NEW_ERROR(joctx, error) \
do { \
- *joctx->ota_return_status = error; \
+ joctx->ota_return_status = error; \
return (joctx->id[0] != '\0') ? error : OTA_SUCCESS; \
} while (false)
@@ -44,8 +44,8 @@
// the next time we receive a message and have the opportunity to reply.
#define HANDLE_ANY_CACHED_ERROR(joctx) \
do { \
- if (*joctx->ota_return_status != OTA_SUCCESS) { \
- return (joctx->id[0] != '\0') ? *joctx->ota_return_status : OTA_SUCCESS; \
+ if (joctx->ota_return_status != OTA_SUCCESS) { \
+ return (joctx->id[0] != '\0') ? joctx->ota_return_status : OTA_SUCCESS; \
} \
} while (false)
@@ -65,7 +65,7 @@ static int patch_stream_reader(const struct bspatch_stream* stream, void* buffer
HANDLE_NEW_ERROR(joctx, ret);
}
- *joctx->remaining_uncompressed -= length;
+ joctx->remaining_uncompressed -= length;
return OTA_SUCCESS;
}
@@ -96,34 +96,34 @@ static int ota_stream_writer(const struct bspatch_stream_n* stream, const void*
// If currently in error, return immediately without writing anything
HANDLE_ANY_CACHED_ERROR(joctx);
- if (length <= 0 || esp_ota_write(*joctx->ota_handle, buffer, length) != ESP_OK) {
+ if (length <= 0 || esp_ota_write(joctx->ota_handle, buffer, length) != ESP_OK) {
HANDLE_NEW_ERROR(joctx, OTA_ERR_PATCH);
}
- if (!*joctx->validated_confirmed && length >= CUSTOM_HEADER_MIN_WRITE) {
- const enum ota_status validation = ota_user_validation(joctx, (uint8_t*)buffer);
+ if (!joctx->validated_confirmed && length >= CUSTOM_HEADER_MIN_WRITE) {
+ const ota_status_t validation = ota_user_validation(joctx, (uint8_t*)buffer);
if (validation != OTA_SUCCESS) {
HANDLE_NEW_ERROR(joctx, validation);
}
- *joctx->validated_confirmed = true;
+ joctx->validated_confirmed = true;
}
if (joctx->hash_type == HASHTYPE_FULLFWDATA) {
// Add written to hash calculation
- JADE_ZERO_VERIFY(mbedtls_sha256_update(joctx->sha_ctx, buffer, length));
+ JADE_ZERO_VERIFY(mbedtls_sha256_update(&joctx->sha_ctx, buffer, length));
}
joctx->fwwritten += length;
// For a patch, the amount of patch data uncompressed should always be more than the
// amount of new firmware we have written, because of additional patch meta-data.
- JADE_ASSERT(joctx->uncompressedsize - *joctx->remaining_uncompressed > joctx->fwwritten);
+ JADE_ASSERT(joctx->uncompressedsize - joctx->remaining_uncompressed > joctx->fwwritten);
- if (joctx->fwwritten > CUSTOM_HEADER_MIN_WRITE && !*joctx->validated_confirmed) {
+ if (joctx->fwwritten > CUSTOM_HEADER_MIN_WRITE && !joctx->validated_confirmed) {
HANDLE_NEW_ERROR(joctx, OTA_ERR_PATCH);
}
- if (*joctx->validated_confirmed) {
+ if (joctx->validated_confirmed) {
update_progress_bar(&joctx->progress_bar, joctx->firmwaresize, joctx->fwwritten);
}
@@ -139,7 +139,7 @@ static int compressed_stream_reader(void* ctx)
// NOTE: the ota_return_status can be set via ptr in joctx
// Return any error here as it can be returned to the caller in the message reply
jade_process_get_in_message(joctx, &handle_in_bin_data, true);
- return *joctx->ota_return_status;
+ return joctx->ota_return_status;
}
void ota_delta_process(void* process_ptr)
@@ -150,12 +150,6 @@ void ota_delta_process(void* process_ptr)
bool ota_end_called = false;
bool ota_begin_called = false;
- mbedtls_sha256_context sha_ctx;
-
- esp_ota_handle_t ota_handle = 0;
- // Context used to compute (compressed) firmware hash - ie. file as uploaded
- enum ota_status ota_return_status = OTA_ERR_SETUP;
-
// We expect a current message to be present
ASSERT_CURRENT_MESSAGE(process, "ota_delta");
GET_MSG_PARAMS(process);
@@ -206,27 +200,24 @@ void ota_delta_process(void* process_ptr)
struct deflate_ctx* dctx = JADE_MALLOC_PREFER_SPIRAM(sizeof(struct deflate_ctx));
jade_process_free_on_exit(process, dctx);
- bool validated_confirmed = false;
- size_t remaining_uncompressed = uncompressedpatchsize;
-
jade_ota_ctx_t joctx = {
- .progress_bar = {},
- .sha_ctx = &sha_ctx,
+ .sha_ctx = {},
+ .progress_bar = {0},
.hash_type = hash_type,
- .ota_handle = &ota_handle,
+ .ota_handle = 0,
.dctx = dctx,
.id = { 0 },
- .validated_confirmed = &validated_confirmed,
.uncompressedsize = uncompressedpatchsize,
- .remaining_uncompressed = &remaining_uncompressed,
- .ota_return_status = &ota_return_status,
- .expected_source = &ota_source,
+ .remaining_uncompressed = uncompressedpatchsize,
+ .ota_return_status = OTA_ERR_SETUP,
+ .expected_source = ota_source,
.remaining_compressed = compressedsize,
.firmwaresize = firmwaresize,
.compressedsize = compressedsize,
.expected_hash_hexstr = expected_hash_hexstr,
.expected_hash = expected_hash,
.extended_replies = extended_replies,
+ .validated_confirmed = false,
};
int ret = deflate_init_read_uncompressed(dctx, compressedsize, compressed_stream_reader, &joctx);
@@ -256,13 +247,13 @@ void ota_delta_process(void* process_ptr)
basestream.read = &base_firmware_stream_reader;
basestream.opaque = &joctx;
- ota_return_status = OTA_SUCCESS;
+ joctx.ota_return_status = OTA_SUCCESS;
ret = bspatch(
&basestream, joctx.running_partition->size, &destination_firmware_stream_writer, firmwaresize, &stream);
if (ret != OTA_SUCCESS) {
JADE_LOGE("Error applying patch: %d", ret);
- ota_return_status = ret < 0 ? OTA_ERR_PATCH : ret;
+ joctx.ota_return_status = ret < 0 ? OTA_ERR_PATCH : ret;
goto cleanup;
}
JADE_ASSERT(ota_begin_called);
@@ -271,7 +262,7 @@ void ota_delta_process(void* process_ptr)
uploading = false;
if (joctx.fwwritten != firmwaresize) {
- ota_return_status = OTA_ERR_PATCH;
+ joctx.ota_return_status = OTA_ERR_PATCH;
}
// Expect a complete/request for status
@@ -284,14 +275,14 @@ void ota_delta_process(void* process_ptr)
// If all good with the upload do all final checks and then finalise the ota
// and set the new boot partition, etc.
- if (ota_return_status == OTA_SUCCESS) {
- ota_return_status = post_ota_check(&joctx, &ota_end_called);
+ if (joctx.ota_return_status == OTA_SUCCESS) {
+ joctx.ota_return_status = post_ota_check(&joctx, &ota_end_called);
}
// Send final message reply with final status
- if (ota_return_status != OTA_SUCCESS) {
+ if (joctx.ota_return_status != OTA_SUCCESS) {
uint8_t buf[256];
- const char* error = ota_get_status_text(ota_return_status);
+ const char* error = ota_get_status_text(joctx.ota_return_status);
jade_process_reject_message_ex(process->ctx, CBOR_RPC_INTERNAL_ERROR, "Error completing OTA delta",
(const uint8_t*)error, strlen(error), buf, sizeof(buf));
goto cleanup;
@@ -302,11 +293,11 @@ void ota_delta_process(void* process_ptr)
JADE_LOGI("Success");
cleanup:
- mbedtls_sha256_free(&sha_ctx);
+ ota_free(&joctx);
// If ota has been successful show message and reboot.
// If error, show error-message and await user acknowledgement.
- if (ota_return_status == OTA_SUCCESS) {
+ if (joctx.ota_return_status == OTA_SUCCESS) {
JADE_LOGW("OTA successful - rebooting");
const char* message[] = { "Upgrade successful!" };
@@ -315,15 +306,15 @@ cleanup:
vTaskDelay(2500 / portTICK_PERIOD_MS);
esp_restart();
} else {
- JADE_LOGE("OTA error %u: %s", ota_return_status, ota_get_status_text(ota_return_status));
+ JADE_LOGE("OTA error %u: %s", joctx.ota_return_status, ota_get_status_text(joctx.ota_return_status));
if (ota_begin_called && !ota_end_called) {
// ota_begin has been called, cleanup
- const esp_err_t err = esp_ota_abort(ota_handle);
+ const esp_err_t err = esp_ota_abort(joctx.ota_handle);
JADE_ASSERT(err == ESP_OK);
}
// If we get here and we have not finished loading the data, send an error message
- const char* status_text = ota_get_status_text(ota_return_status);
+ const char* status_text = ota_get_status_text(joctx.ota_return_status);
if (uploading) {
if (joctx.id[0] == '\0') {
// This should not happen under normal circumstances, but it could occur if the delta
@@ -332,7 +323,7 @@ cleanup:
strcpy(joctx.id, "00");
}
const int error_code
- = ota_return_status == OTA_ERR_USERDECLINED ? CBOR_RPC_USER_CANCELLED : CBOR_RPC_INTERNAL_ERROR;
+ = joctx.ota_return_status == OTA_ERR_USERDECLINED ? CBOR_RPC_USER_CANCELLED : CBOR_RPC_INTERNAL_ERROR;
uint8_t buf[256];
jade_process_reject_message_with_id(joctx.id, error_code, "Error uploading OTA delta data",
@@ -340,7 +331,7 @@ cleanup:
}
// If the error is not 'did not start' or 'user declined', show an error screen
- if (ota_return_status != OTA_ERR_SETUP && ota_return_status != OTA_ERR_USERDECLINED) {
+ if (joctx.ota_return_status != OTA_ERR_SETUP && joctx.ota_return_status != OTA_ERR_USERDECLINED) {
await_error_activity(&status_text, 1);
}
}
diff --git a/main/process/ota_util.c b/main/process/ota_util.c
index d326fa5..777eeb0 100644
--- a/main/process/ota_util.c
+++ b/main/process/ota_util.c
@@ -34,7 +34,7 @@ static void reply_ok(const void* ctx, CborEncoder* container)
CborError cberr = cbor_encoder_create_map(container, &map_encoder, 2);
JADE_ASSERT(cberr == CborNoError);
- add_boolean_to_map(&map_encoder, "confirmed", *joctx->validated_confirmed);
+ add_boolean_to_map(&map_encoder, "confirmed", joctx->validated_confirmed);
add_uint_to_map(&map_encoder, "progress", joctx->progress_bar.percent_last_value);
cberr = cbor_encoder_close_container(container, &map_encoder);
@@ -68,12 +68,12 @@ void handle_in_bin_data(void* ctx, uint8_t* data, const size_t rawsize)
// If we are carrying a cached error abandon immediately
// (the error will be returned with this id)
- if (*joctx->ota_return_status != OTA_SUCCESS) {
+ if (joctx->ota_return_status != OTA_SUCCESS) {
return;
}
if (!rpc_is_method(&value, "ota_data")) {
- *joctx->ota_return_status = OTA_ERR_BADDATA;
+ joctx->ota_return_status = OTA_ERR_BADDATA;
return;
}
@@ -82,14 +82,14 @@ void handle_in_bin_data(void* ctx, uint8_t* data, const size_t rawsize)
rpc_get_bytes_ptr("params", &value, &inbound_buf, &written);
- if (written == 0 || data[0] != *joctx->expected_source || written > JADE_OTA_BUF_SIZE || !inbound_buf) {
- *joctx->ota_return_status = OTA_ERR_BADDATA;
+ if (written == 0 || data[0] != joctx->expected_source || written > JADE_OTA_BUF_SIZE || !inbound_buf) {
+ joctx->ota_return_status = OTA_ERR_BADDATA;
return;
}
if (written > joctx->remaining_compressed) {
JADE_LOGE("Received %u bytes when only needed %u", written, joctx->remaining_compressed);
- *joctx->ota_return_status = OTA_ERR_BADDATA;
+ joctx->ota_return_status = OTA_ERR_BADDATA;
return;
}
@@ -100,13 +100,13 @@ void handle_in_bin_data(void* ctx, uint8_t* data, const size_t rawsize)
// Return any non-zero error code from the decompress routine
const int ret = joctx->dctx->write_compressed(joctx->dctx, (uint8_t* const)inbound_buf, written);
if (ret) {
- *joctx->ota_return_status = ret < 0 ? OTA_ERR_DECOMPRESS : ret;
+ joctx->ota_return_status = ret < 0 ? OTA_ERR_DECOMPRESS : ret;
return;
}
if (joctx->hash_type == HASHTYPE_FILEDATA) {
// Add received file data to hasher
- JADE_ZERO_VERIFY(mbedtls_sha256_update(joctx->sha_ctx, inbound_buf, written));
+ JADE_ZERO_VERIFY(mbedtls_sha256_update(&joctx->sha_ctx, inbound_buf, written));
}
joctx->remaining_compressed -= written;
@@ -116,12 +116,12 @@ void handle_in_bin_data(void* ctx, uint8_t* data, const size_t rawsize)
JADE_LOGI("compressed: total = %u, current = %u", joctx->compressedsize,
joctx->compressedsize - joctx->remaining_compressed);
JADE_LOGI("uncompressed: total = %u, current = %u", joctx->uncompressedsize,
- joctx->uncompressedsize - *joctx->remaining_uncompressed);
+ joctx->uncompressedsize - joctx->remaining_uncompressed);
// Send ack after all processing - see comment above.
uint8_t reply_msg[64];
jade_process_reply_to_message_result_with_id(
- joctx->id, reply_msg, sizeof(reply_msg), *joctx->expected_source, joctx, reply_ok);
+ joctx->id, reply_msg, sizeof(reply_msg), joctx->expected_source, joctx, reply_ok);
// Blank out the current msg id once 'ok' is sent for it
joctx->id[0] = '\0';
@@ -131,7 +131,7 @@ bool ota_init(jade_ota_ctx_t* joctx)
{
JADE_ASSERT(joctx);
- mbedtls_sha256_init(joctx->sha_ctx);
+ mbedtls_sha256_init(&joctx->sha_ctx);
joctx->running_partition = esp_ota_get_running_partition();
JADE_ASSERT(joctx->running_partition);
JADE_LOGI("Running partition ptr: %p", joctx->running_partition);
@@ -150,9 +150,9 @@ bool ota_init(jade_ota_ctx_t* joctx)
return false;
}
- JADE_ZERO_VERIFY(mbedtls_sha256_starts(joctx->sha_ctx, 0));
+ JADE_ZERO_VERIFY(mbedtls_sha256_starts(&joctx->sha_ctx, 0));
- const esp_err_t err = esp_ota_begin(joctx->update_partition, joctx->firmwaresize, joctx->ota_handle);
+ const esp_err_t err = esp_ota_begin(joctx->update_partition, joctx->firmwaresize, &joctx->ota_handle);
if (err != ESP_OK) {
JADE_LOGE("Failed to begin ota, error: %d", err);
return false;
@@ -161,28 +161,34 @@ bool ota_init(jade_ota_ctx_t* joctx)
return true;
}
-enum ota_status post_ota_check(jade_ota_ctx_t* joctx, bool* ota_end_called)
+void ota_free(jade_ota_ctx_t* joctx)
+{
+ if (joctx) {
+ mbedtls_sha256_free(&joctx->sha_ctx);
+ }
+}
+
+ota_status_t post_ota_check(jade_ota_ctx_t* joctx, bool* ota_end_called)
{
JADE_ASSERT(joctx);
JADE_ASSERT(ota_end_called);
// Ensure no cached error - if so return it now
- if (*joctx->ota_return_status != OTA_SUCCESS) {
- return *joctx->ota_return_status;
+ if (joctx->ota_return_status != OTA_SUCCESS) {
+ return joctx->ota_return_status;
}
- if (joctx->remaining_compressed || *joctx->remaining_uncompressed || !joctx->compressedsize
+ if (joctx->remaining_compressed || joctx->remaining_uncompressed || !joctx->compressedsize
|| !joctx->uncompressedsize) {
JADE_LOGE("OTA checks failed: uncompressed size: %u, compressed size: %u, remaining compressed %u, remaining "
"uncompressed %u",
- joctx->uncompressedsize, joctx->compressedsize, joctx->remaining_compressed,
- *joctx->remaining_uncompressed);
+ joctx->uncompressedsize, joctx->compressedsize, joctx->remaining_compressed, joctx->remaining_uncompressed);
return OTA_ERR_INIT;
}
// Verify calculated compressed file hash matches expected
uint8_t calculated_hash[SHA256_LEN];
- JADE_ZERO_VERIFY(mbedtls_sha256_finish(joctx->sha_ctx, calculated_hash));
+ JADE_ZERO_VERIFY(mbedtls_sha256_finish(&joctx->sha_ctx, calculated_hash));
JADE_ASSERT(joctx->expected_hash);
JADE_ASSERT(joctx->expected_hash_hexstr);
@@ -198,7 +204,7 @@ enum ota_status post_ota_check(jade_ota_ctx_t* joctx, bool* ota_end_called)
}
// All good, finalise the ota and set the partition to boot
- esp_err_t err = esp_ota_end(*joctx->ota_handle);
+ esp_err_t err = esp_ota_end(joctx->ota_handle);
*ota_end_called = true;
if (err != ESP_OK) {
@@ -224,7 +230,7 @@ static void to_lower(char* dest, const char* src)
*dest = '\0';
}
-enum ota_status ota_user_validation(jade_ota_ctx_t* joctx, const uint8_t* uncompressed)
+ota_status_t ota_user_validation(jade_ota_ctx_t* joctx, const uint8_t* uncompressed)
{
JADE_ASSERT(joctx);
JADE_ASSERT(uncompressed);
@@ -299,7 +305,7 @@ enum ota_status ota_user_validation(jade_ota_ctx_t* joctx, const uint8_t* uncomp
return OTA_SUCCESS;
}
-const char* ota_get_status_text(const enum ota_status status)
+const char* ota_get_status_text(const ota_status_t status)
{
switch (status) {
case OTA_SUCCESS:
diff --git a/main/process/ota_util.h b/main/process/ota_util.h
index f88984b..8234335 100644
--- a/main/process/ota_util.h
+++ b/main/process/ota_util.h
@@ -32,51 +32,53 @@ typedef struct {
typedef enum { HASHTYPE_FILEDATA, HASHTYPE_FULLFWDATA } hash_type_t;
+typedef enum {
+ OTA_SUCCESS = 0,
+ OTA_ERR_SETUP,
+ OTA_ERR_INIT,
+ OTA_ERR_BADPARTITION,
+ OTA_ERR_DECOMPRESS,
+ OTA_ERR_WRITE,
+ OTA_ERR_FINISH,
+ OTA_ERR_SETPARTITION,
+ OTA_ERR_BADDATA,
+ OTA_ERR_NODOWNGRADE,
+ OTA_ERR_INVALIDFW,
+ OTA_ERR_USERDECLINED,
+ OTA_ERR_BADHASH,
+ OTA_ERR_PATCH,
+} ota_status_t;
+
typedef struct {
+ // Context used to compute (compressed) firmware hash - ie. file as uploaded
+ mbedtls_sha256_context sha_ctx;
progress_bar_t progress_bar;
- mbedtls_sha256_context* sha_ctx;
hash_type_t hash_type;
char id[MAXLEN_ID + 1];
- bool extended_replies;
const uint8_t* expected_hash;
const char* expected_hash_hexstr;
const esp_partition_t* running_partition;
const esp_partition_t* update_partition;
- esp_ota_handle_t* ota_handle;
- enum ota_status* ota_return_status;
+ esp_ota_handle_t ota_handle;
+ ota_status_t ota_return_status;
struct deflate_ctx* dctx;
- const jade_msg_source_t* expected_source;
- bool* validated_confirmed;
- size_t* const remaining_uncompressed;
+ const jade_msg_source_t expected_source;
+ size_t remaining_uncompressed;
size_t remaining_compressed;
size_t uncompressedsize;
size_t compressedsize;
size_t firmwaresize;
size_t fwwritten;
+ bool extended_replies;
+ bool validated_confirmed;
} jade_ota_ctx_t;
-enum ota_status {
- OTA_SUCCESS = 0,
- OTA_ERR_SETUP,
- OTA_ERR_INIT,
- OTA_ERR_BADPARTITION,
- OTA_ERR_DECOMPRESS,
- OTA_ERR_WRITE,
- OTA_ERR_FINISH,
- OTA_ERR_SETPARTITION,
- OTA_ERR_BADDATA,
- OTA_ERR_NODOWNGRADE,
- OTA_ERR_INVALIDFW,
- OTA_ERR_USERDECLINED,
- OTA_ERR_BADHASH,
- OTA_ERR_PATCH,
-};
-
void handle_in_bin_data(void* ctx, uint8_t* data, size_t rawsize);
bool ota_init(jade_ota_ctx_t* joctx);
-enum ota_status post_ota_check(jade_ota_ctx_t* joctx, bool* ota_end_called);
-enum ota_status ota_user_validation(jade_ota_ctx_t* joctx, const uint8_t* uncompressed);
-const char* ota_get_status_text(enum ota_status status);
+void ota_free(jade_ota_ctx_t* joctx);
+ota_status_t post_ota_check(jade_ota_ctx_t* joctx, bool* ota_end_called);
+ota_status_t ota_user_validation(jade_ota_ctx_t* joctx, const uint8_t* uncompressed);
+const char* ota_get_status_text(ota_status_t status);
#endif /* JADE_OTA_UTIL_H_ */
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.