21
21
#include < platform/ESP32/ESP32Utils.h>
22
22
23
23
#include " OTAImageProcessorImpl.h"
24
+ #include " esp_app_format.h"
24
25
#include " esp_err.h"
25
26
#include " esp_log.h"
26
27
#include " esp_ota_ops.h"
31
32
#include < esp_encrypted_img.h>
32
33
#endif // CONFIG_ENABLE_ENCRYPTED_OTA
33
34
35
+ #ifdef CONFIG_ENABLE_DELTA_OTA
36
+ #include < esp_delta_ota.h>
37
+ #endif // CONFIG_ENABLE_DELTA_OTA
38
+
34
39
#define TAG " OTAImageProcessor"
40
+
41
+ #ifdef CONFIG_ENABLE_DELTA_OTA
42
+ #define PATCH_HEADER_SIZE 64
43
+ #define DIGEST_SIZE 32
44
+ #endif // CONFIG_ENABLE_DELTA_OTA
45
+
35
46
using namespace chip ::System;
36
47
using namespace ::chip::DeviceLayer::Internal;
37
48
@@ -123,6 +134,152 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & block)
123
134
return CHIP_NO_ERROR;
124
135
}
125
136
137
+ #ifdef CONFIG_ENABLE_DELTA_OTA
138
+ bool OTAImageProcessorImpl::VerifyChipId (esp_chip_id_t chipId)
139
+ {
140
+ if (chipId != CONFIG_IDF_FIRMWARE_CHIP_ID)
141
+ {
142
+ ESP_LOGE (TAG, " Mismatch chip id, expected %d, found %d" , CONFIG_IDF_FIRMWARE_CHIP_ID, chipId);
143
+ return false ;
144
+ }
145
+ return true ;
146
+ }
147
+
148
+ bool OTAImageProcessorImpl::VerifyPatchHeader (void * imgHeaderData)
149
+ {
150
+ const uint32_t espDeltaOtaMagic = 0xfccdde10 ;
151
+ if (!imgHeaderData)
152
+ {
153
+ return false ;
154
+ }
155
+ uint32_t recvMagic = *(uint32_t *) imgHeaderData;
156
+ uint8_t * digest = (uint8_t *) ((uint8_t *) imgHeaderData + 4 );
157
+ if (recvMagic != espDeltaOtaMagic)
158
+ {
159
+ ESP_LOGE (TAG, " Invalid magic word in patch" );
160
+ return false ;
161
+ }
162
+ uint8_t sha_256[DIGEST_SIZE] = { 0 };
163
+ esp_partition_get_sha256 (esp_ota_get_running_partition (), sha_256);
164
+ if (memcmp (sha_256, digest, DIGEST_SIZE) != 0 )
165
+ {
166
+ ESP_LOGE (TAG, " SHA256 of current firmware differs from than in patch header. Invalid patch for current firmware" );
167
+ return false ;
168
+ }
169
+ return true ;
170
+ }
171
+
172
+ esp_err_t OTAImageProcessorImpl::VerifyHeaderData (const uint8_t * buf, size_t size, int * index)
173
+ {
174
+ static char patchHeader[PATCH_HEADER_SIZE];
175
+ static int headerDataRead = 0 ;
176
+ if (!patchHeaderVerified)
177
+ {
178
+ if (headerDataRead + size < PATCH_HEADER_SIZE)
179
+ {
180
+ memcpy (patchHeader + headerDataRead, buf, size);
181
+ headerDataRead += size;
182
+ return ESP_OK;
183
+ }
184
+ else
185
+ {
186
+ *index = PATCH_HEADER_SIZE - headerDataRead;
187
+ memcpy (patchHeader + headerDataRead, buf, *index );
188
+ if (!VerifyPatchHeader (patchHeader))
189
+ {
190
+ return ESP_ERR_INVALID_VERSION;
191
+ }
192
+ headerDataRead = 0 ;
193
+ *index = PATCH_HEADER_SIZE;
194
+ patchHeaderVerified = true ;
195
+ }
196
+ }
197
+ return ESP_OK;
198
+ }
199
+
200
+ void OTAImageProcessorImpl::DeltaOTACleanUp (intptr_t context)
201
+ {
202
+ auto * imageProcessor = reinterpret_cast <OTAImageProcessorImpl *>(context);
203
+ if (imageProcessor == nullptr )
204
+ {
205
+ ChipLogError (SoftwareUpdate, " ImageProcessor context is null" );
206
+ return ;
207
+ }
208
+ imageProcessor->patchHeaderVerified = false ;
209
+ imageProcessor->chipIdVerified = false ;
210
+ return ;
211
+ }
212
+
213
+ esp_err_t OTAImageProcessorImpl::DeltaOTAReadCallback (uint8_t * buf, size_t size, int srcOffset)
214
+ {
215
+ if (size <= 0 || buf == NULL )
216
+ {
217
+ return ESP_ERR_INVALID_ARG;
218
+ }
219
+
220
+ const esp_partition_t * currentPartition = esp_ota_get_running_partition ();
221
+ if (currentPartition == NULL )
222
+ {
223
+ return ESP_FAIL;
224
+ }
225
+
226
+ esp_err_t err = esp_partition_read (currentPartition, srcOffset, buf, size);
227
+
228
+ if (err != ESP_OK)
229
+ {
230
+ ESP_LOGE (TAG, " esp_partition_read failed (%s)!" , esp_err_to_name (err));
231
+ }
232
+
233
+ return err;
234
+ }
235
+
236
+ esp_err_t OTAImageProcessorImpl::DeltaOTAWriteCallback (const uint8_t * buf, size_t size, void * arg)
237
+ {
238
+ auto * imageProcessor = reinterpret_cast <OTAImageProcessorImpl *>(arg);
239
+ if (size <= 0 || buf == NULL )
240
+ {
241
+ return ESP_ERR_INVALID_ARG;
242
+ }
243
+
244
+ int index = 0 ;
245
+ static int headerDataRead = 0 ;
246
+ static char headerData[IMG_HEADER_LEN];
247
+
248
+ if (!imageProcessor->chipIdVerified )
249
+ {
250
+ if (headerDataRead + size - index <= IMG_HEADER_LEN)
251
+ {
252
+ memcpy (headerData + headerDataRead, buf, size - index );
253
+ headerDataRead += size - index ;
254
+ return ESP_OK;
255
+ }
256
+ else
257
+ {
258
+ index = IMG_HEADER_LEN - headerDataRead;
259
+ memcpy (headerData + headerDataRead, buf, index );
260
+
261
+ esp_image_header_t * header = (esp_image_header_t *) headerData;
262
+ if (!VerifyChipId (header->chip_id ))
263
+ {
264
+ return ESP_ERR_INVALID_VERSION;
265
+ }
266
+ imageProcessor->chipIdVerified = true ;
267
+
268
+ // Write data in headerData buffer.
269
+ return esp_ota_write (imageProcessor->mOTAUpdateHandle , headerData, IMG_HEADER_LEN);
270
+ }
271
+ }
272
+
273
+ esp_err_t err = esp_ota_write (imageProcessor->mOTAUpdateHandle , buf + index , size - index );
274
+ if (err != ESP_OK)
275
+ {
276
+ ESP_LOGE (TAG, " esp_ota_write failed (%s)!" , esp_err_to_name (err));
277
+ }
278
+
279
+ return err;
280
+ }
281
+ #endif // CONFIG_ENABLE_DELTA_OTA
282
+
126
283
void OTAImageProcessorImpl::HandlePrepareDownload (intptr_t context)
127
284
{
128
285
auto * imageProcessor = reinterpret_cast <OTAImageProcessorImpl *>(context);
@@ -142,13 +299,32 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context)
142
299
ChipLogError (SoftwareUpdate, " OTA partition not found" );
143
300
return ;
144
301
}
302
+ #ifdef CONFIG_ENABLE_DELTA_OTA
303
+ // New image size is unknown for delta OTA, so we use OTA_SIZE_UNKNOWN flag.
304
+ esp_err_t err = esp_ota_begin (imageProcessor->mOTAUpdatePartition , OTA_SIZE_UNKNOWN, &(imageProcessor->mOTAUpdateHandle ));
305
+ #else
145
306
esp_err_t err =
146
307
esp_ota_begin (imageProcessor->mOTAUpdatePartition , OTA_WITH_SEQUENTIAL_WRITES, &(imageProcessor->mOTAUpdateHandle ));
308
+ #endif // CONFIG_ENABLE_DELTA_OTA
309
+
147
310
if (err != ESP_OK)
148
311
{
149
312
imageProcessor->mDownloader ->OnPreparedForDownload (ESP32Utils::MapError (err));
150
313
return ;
151
314
}
315
+ #ifdef CONFIG_ENABLE_DELTA_OTA
316
+ imageProcessor->deltaOtaCfg .user_data = imageProcessor,
317
+ imageProcessor->deltaOtaCfg .read_cb = &(imageProcessor->DeltaOTAReadCallback ),
318
+ imageProcessor->deltaOtaCfg .write_cb_with_user_data = &(imageProcessor->DeltaOTAWriteCallback ),
319
+
320
+ imageProcessor->mDeltaOTAUpdateHandle = esp_delta_ota_init (&imageProcessor->deltaOtaCfg );
321
+ if (imageProcessor->mDeltaOTAUpdateHandle == NULL )
322
+ {
323
+ ChipLogError (SoftwareUpdate, " esp_delta_ota_init failed" );
324
+ imageProcessor->mDownloader ->OnPreparedForDownload (CHIP_ERROR_INTERNAL);
325
+ return ;
326
+ }
327
+ #endif // CONFIG_ENABLE_DELTA_OTA
152
328
153
329
#ifdef CONFIG_ENABLE_ENCRYPTED_OTA
154
330
CHIP_ERROR chipError = imageProcessor->DecryptStart ();
@@ -182,7 +358,30 @@ void OTAImageProcessorImpl::HandleFinalize(intptr_t context)
182
358
}
183
359
#endif // CONFIG_ENABLE_ENCRYPTED_OTA
184
360
361
+ #ifdef CONFIG_ENABLE_DELTA_OTA
362
+ esp_err_t err = esp_delta_ota_finalize (imageProcessor->mDeltaOTAUpdateHandle );
363
+ if (err != ESP_OK)
364
+ {
365
+ ESP_LOGE (TAG, " esp_delta_ota_finalize() failed (%s)!" , esp_err_to_name (err));
366
+ esp_ota_abort (imageProcessor->mOTAUpdateHandle );
367
+ imageProcessor->ReleaseBlock ();
368
+ PostOTAStateChangeEvent (DeviceLayer::kOtaDownloadFailed );
369
+ }
370
+
371
+ err = esp_delta_ota_deinit (imageProcessor->mDeltaOTAUpdateHandle );
372
+ if (err != ESP_OK)
373
+ {
374
+ ESP_LOGE (TAG, " esp_delta_ota_deinit() failed (%s)!" , esp_err_to_name (err));
375
+ esp_ota_abort (imageProcessor->mOTAUpdateHandle );
376
+ imageProcessor->ReleaseBlock ();
377
+ PostOTAStateChangeEvent (DeviceLayer::kOtaDownloadFailed );
378
+ }
379
+
380
+ err = esp_ota_end (imageProcessor->mOTAUpdateHandle );
381
+ DeltaOTACleanUp (reinterpret_cast <intptr_t >(imageProcessor));
382
+ #else
185
383
esp_err_t err = esp_ota_end (imageProcessor->mOTAUpdateHandle );
384
+ #endif // CONFIG_ENABLE_DELTA_OTA
186
385
if (err != ESP_OK)
187
386
{
188
387
if (err == ESP_ERR_OTA_VALIDATE_FAILED)
@@ -217,6 +416,10 @@ void OTAImageProcessorImpl::HandleAbort(intptr_t context)
217
416
imageProcessor->DecryptAbort ();
218
417
#endif // CONFIG_ENABLE_ENCRYPTED_OTA
219
418
419
+ #ifdef CONFIG_ENABLE_DELTA_OTA
420
+ DeltaOTACleanUp (reinterpret_cast <intptr_t >(imageProcessor));
421
+ #endif // CONFIG_ENABLE_DELTA_OTA
422
+
220
423
if (esp_ota_abort (imageProcessor->mOTAUpdateHandle ) != ESP_OK)
221
424
{
222
425
ESP_LOGE (TAG, " ESP OTA abort failed" );
@@ -264,7 +467,24 @@ void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context)
264
467
}
265
468
#endif // CONFIG_ENABLE_ENCRYPTED_OTA
266
469
267
- err = esp_ota_write (imageProcessor->mOTAUpdateHandle , blockToWrite.data (), blockToWrite.size ());
470
+ #ifdef CONFIG_ENABLE_DELTA_OTA
471
+
472
+ int index = 0 ;
473
+ err = imageProcessor->VerifyHeaderData (blockToWrite.data (), blockToWrite.size (), &index );
474
+
475
+ if (err != ESP_OK)
476
+ {
477
+ ESP_LOGE (TAG, " Header data verification failed (%s)" , esp_err_to_name (err));
478
+ imageProcessor->mDownloader ->EndDownload (CHIP_ERROR_INVALID_SIGNATURE);
479
+ PostOTAStateChangeEvent (DeviceLayer::kOtaDownloadFailed );
480
+ return ;
481
+ }
482
+
483
+ // Apply the patch and writes that data to the passive partition.
484
+ err = esp_delta_ota_feed_patch (imageProcessor->mDeltaOTAUpdateHandle , blockToWrite.data () + index , blockToWrite.size () - index );
485
+ #else
486
+ err = esp_ota_write (imageProcessor->mOTAUpdateHandle , blockToWrite.data (), blockToWrite.size ());
487
+ #endif // CONFIG_ENABLE_DELTA_OTA
268
488
269
489
#ifdef CONFIG_ENABLE_ENCRYPTED_OTA
270
490
free ((void *) (blockToWrite.data ()));
0 commit comments