@@ -45,6 +45,9 @@ static arm_uc_buffer_t *back_buffer = NULL;
45
45
46
46
#define UCFM_DEBUG_OUTPUT 0
47
47
48
+ #ifndef MBED_CONF_UPDATE_CLIENT_IN_TRANSIT_HASH_VALIDATION
49
+ #define MBED_CONF_UPDATE_CLIENT_IN_TRANSIT_HASH_VALIDATION 0
50
+ #endif
48
51
49
52
static void arm_uc_signal_ucfm_handler (uintptr_t event );
50
53
@@ -124,6 +127,48 @@ static void debug_output_validation(arm_uc_hash_t *hash,
124
127
125
128
/******************************************************************************/
126
129
130
+ /* Hash comparison.
131
+ */
132
+ static void arm_uc_internal_compare_hash (void )
133
+ {
134
+ UC_FIRM_TRACE ("arm_uc_internal_compare_hash" );
135
+
136
+ /* use specific event for "invalid hash" */
137
+ uint32_t error_event = UCFM_EVENT_FINALIZE_INVALID_HASH_ERROR ;
138
+
139
+ /* finalize hash calculation */
140
+ uint8_t hash_output_ptr [2 * UCFM_MAX_BLOCK_SIZE ];
141
+ arm_uc_buffer_t hash_buffer = {
142
+ .size_max = sizeof (hash_output_ptr ),
143
+ .size = 0 ,
144
+ .ptr = hash_output_ptr
145
+ };
146
+
147
+ ARM_UC_cryptoHashFinish (& mdHandle , & hash_buffer );
148
+
149
+ /* size check before memcmp call */
150
+ if (hash_buffer .size == ARM_UC_SHA256_SIZE ) {
151
+ int diff = memcmp (hash_buffer .ptr , package_hash , ARM_UC_SHA256_SIZE );
152
+
153
+ #if UCFM_DEBUG_OUTPUT
154
+ debug_output_validation (package_hash , & hash_buffer );
155
+ #endif
156
+
157
+ if (diff == 0 ) {
158
+ /* hash matches */
159
+ UC_FIRM_TRACE ("image hash valid" );
160
+ error_event = UCFM_EVENT_FINALIZE_DONE ;
161
+ } else {
162
+ UC_FIRM_ERR_MSG ("image hash invalid" );
163
+ }
164
+
165
+ /* clear local hash */
166
+ memset (package_hash , 0 , ARM_UC_SHA256_SIZE );
167
+ }
168
+
169
+ arm_uc_signal_ucfm_handler (error_event );
170
+ }
171
+
127
172
/* Hash calculation is performed using the output buffer. This function fills
128
173
the output buffer with data from the PAL.
129
174
*/
@@ -132,7 +177,6 @@ static void arm_uc_internal_process_hash(void)
132
177
bool double_buffering = (front_buffer != back_buffer );
133
178
bool needs_more_data = (package_offset < package_configuration -> package_size );
134
179
arm_uc_error_t status = { .code = ERR_NONE };
135
- uint32_t error_event = UCFM_EVENT_FINALIZE_ERROR ;
136
180
137
181
if (double_buffering && needs_more_data ) {
138
182
#if UCFM_DEBUG_OUTPUT
@@ -175,45 +219,11 @@ static void arm_uc_internal_process_hash(void)
175
219
back_buffer );
176
220
}
177
221
} else {
178
- /* invert status code so that it has to be set explicitly for success */
179
- status .code = FIRM_ERR_INVALID_PARAMETER ;
180
-
181
- /* finalize hash calculation */
182
- uint8_t hash_output_ptr [2 * UCFM_MAX_BLOCK_SIZE ];
183
- arm_uc_buffer_t hash_buffer = {
184
- .size_max = sizeof (hash_output_ptr ),
185
- .size = 0 ,
186
- .ptr = hash_output_ptr
187
- };
188
-
189
- ARM_UC_cryptoHashFinish (& mdHandle , & hash_buffer );
190
-
191
- /* size check before memcmp call */
192
- if (hash_buffer .size == ARM_UC_SHA256_SIZE ) {
193
- int diff = memcmp (hash_buffer .ptr ,
194
- package_hash ,
195
- ARM_UC_SHA256_SIZE );
196
-
197
- #if UCFM_DEBUG_OUTPUT
198
- debug_output_validation (package_hash ,
199
- & hash_buffer );
200
- #endif
201
-
202
- /* hash matches */
203
- if (diff == 0 ) {
204
- UC_FIRM_TRACE ("UCFM_EVENT_FINALIZE_DONE" );
205
-
206
- arm_uc_signal_ucfm_handler (UCFM_EVENT_FINALIZE_DONE );
207
- status .code = ERR_NONE ;
208
- } else {
209
- /* use specific event for "invalid hash" */
210
- UC_FIRM_ERR_MSG ("Invalid image hash" );
211
-
212
- error_event = UCFM_EVENT_FINALIZE_INVALID_HASH_ERROR ;
213
- }
214
- // clear local hash
215
- memset (package_hash , 0 , ARM_UC_SHA256_SIZE );
216
- }
222
+ /* All data has been passed through hash calculation.
223
+ * Compare hash with manifest. This function will signal
224
+ * success/failure by itself.
225
+ */
226
+ arm_uc_internal_compare_hash ();
217
227
}
218
228
219
229
/* Front buffer is processed, back buffer might be reading more data.
@@ -227,7 +237,7 @@ static void arm_uc_internal_process_hash(void)
227
237
/* signal error if status is not clean */
228
238
if (status .error != ERR_NONE ) {
229
239
UC_FIRM_TRACE ("UCFM_EVENT_FINALIZE_ERROR" );
230
- arm_uc_signal_ucfm_handler (error_event );
240
+ arm_uc_signal_ucfm_handler (UCFM_EVENT_FINALIZE_ERROR );
231
241
}
232
242
}
233
243
@@ -239,28 +249,37 @@ static void event_handler_finalize(void)
239
249
{
240
250
UC_FIRM_TRACE ("event_handler_finalize" );
241
251
242
- /* setup mandatory hash */
243
- arm_uc_mdType_t mdtype = ARM_UC_CU_SHA256 ;
244
- arm_uc_error_t result = ARM_UC_cryptoHashSetup ( & mdHandle , mdtype );
252
+ /* Hash is calculated while in transit */
253
+ #if MBED_CONF_UPDATE_CLIENT_IN_TRANSIT_HASH_VALIDATION
254
+ UC_FIRM_TRACE ( "calculate hash in transit" );
245
255
246
- if (result .error == ERR_NONE ) {
247
- /* initiate hash calculation */
248
- package_offset = 0 ;
256
+ /* All data has been passed through hash calculation.
257
+ * Compare hash with manifest. This function will signal
258
+ * success/failure by itself.
259
+ */
260
+ arm_uc_internal_compare_hash ();
249
261
250
- /* indicate number of bytes needed */
251
- front_buffer -> size = ( package_configuration -> package_size < front_buffer -> size_max ) ?
252
- package_configuration -> package_size : front_buffer -> size_max ;
262
+ /* Hash is calculated by reading back payload from storage */
263
+ #else
264
+ UC_FIRM_TRACE ( "calculate hash from storage" ) ;
253
265
254
- /* initiate read from PAL */
255
- result = ARM_UCP_Read (package_configuration -> package_id ,
256
- package_offset ,
257
- front_buffer );
258
- }
266
+ /* initiate hash calculation */
267
+ package_offset = 0 ;
268
+
269
+ /* indicate number of bytes needed */
270
+ front_buffer -> size = (package_configuration -> package_size < front_buffer -> size_max ) ?
271
+ package_configuration -> package_size : front_buffer -> size_max ;
272
+
273
+ /* initiate read from PAL */
274
+ arm_uc_error_t result = ARM_UCP_Read (package_configuration -> package_id ,
275
+ package_offset ,
276
+ front_buffer );
259
277
260
278
if (result .error != ERR_NONE ) {
261
- UC_FIRM_ERR_MSG ("ARM_UC_cryptoHashSetup failed" );
279
+ UC_FIRM_ERR_MSG ("ARM_UCP_Read during hash check failed" );
262
280
arm_uc_signal_ucfm_handler (UCFM_EVENT_FINALIZE_ERROR );
263
281
}
282
+ #endif
264
283
}
265
284
266
285
/* Function for decoupling PAL callbacks using the internal task queue. */
@@ -416,13 +435,12 @@ static arm_uc_error_t ARM_UCFM_Prepare(ARM_UCFM_Setup_t *configuration,
416
435
arm_uc_signal_ucfm_handler (UCFM_EVENT_PREPARE_ERROR );
417
436
}
418
437
}
419
- #if UCFM_DEBUG_OUTPUT
438
+
420
439
/* Initialize hash to calculate downloaded fragments hash */
421
440
if (result .error == ERR_NONE ) {
422
441
arm_uc_mdType_t mdtype = ARM_UC_CU_SHA256 ;
423
442
result = ARM_UC_cryptoHashSetup (& mdHandle , mdtype );
424
443
}
425
- #endif
426
444
427
445
return result ;
428
446
}
@@ -478,8 +496,8 @@ static arm_uc_error_t ARM_UCFM_Write(const arm_uc_buffer_t *fragment)
478
496
fragment_offset += length_update ;
479
497
}
480
498
}
481
- #if UCFM_DEBUG_OUTPUT
482
- /* calculate hash on the fly for debugging purpose */
499
+ #if MBED_CONF_UPDATE_CLIENT_IN_TRANSIT_HASH_VALIDATION
500
+ /* calculate hash on the fly */
483
501
ARM_UC_cryptoHashUpdate (& mdHandle , fragment );
484
502
#endif
485
503
/* store fragment using PAL */
@@ -514,7 +532,7 @@ static arm_uc_error_t ARM_UCFM_ReadFromSlot(const arm_uc_buffer_t* output, uint3
514
532
return result ;
515
533
}
516
534
517
- static arm_uc_error_t ARM_UCFM_Read (arm_uc_buffer_t * buf , uint32_t offset )
535
+ static arm_uc_error_t ARM_UCFM_Read (const arm_uc_buffer_t * buf , uint32_t offset )
518
536
{
519
537
arm_uc_error_t result = (arm_uc_error_t ) { FIRM_ERR_UNINITIALIZED };
520
538
result = ARM_UCFM_ReadFromSlot (buf , package_configuration -> package_id , offset );
@@ -523,7 +541,7 @@ static arm_uc_error_t ARM_UCFM_Read(arm_uc_buffer_t *buf, uint32_t offset)
523
541
524
542
static arm_uc_error_t ARM_UCFM_Finalize (arm_uc_buffer_t * front , arm_uc_buffer_t * back )
525
543
{
526
- UC_FIRM_TRACE ("ARM_UCFM_Finish " );
544
+ UC_FIRM_TRACE ("ARM_UCFM_Finalize " );
527
545
528
546
arm_uc_error_t result = (arm_uc_error_t ) { ERR_NONE };
529
547
@@ -550,20 +568,6 @@ static arm_uc_error_t ARM_UCFM_Finalize(arm_uc_buffer_t *front, arm_uc_buffer_t
550
568
551
569
/* disable module until next setup call is received */
552
570
ready_to_receive = false;
553
-
554
- #if UCFM_DEBUG_OUTPUT
555
- /* finalize hash calculation */
556
- uint8_t hash_output_ptr [2 * UCFM_MAX_BLOCK_SIZE ];
557
- arm_uc_buffer_t hash_buffer = {
558
- .size_max = sizeof (hash_output_ptr ),
559
- .size = 0 ,
560
- .ptr = hash_output_ptr
561
- };
562
-
563
- ARM_UC_cryptoHashFinish (& mdHandle , & hash_buffer );
564
-
565
- debug_print_hash ("downloaded hash:" , hash_buffer .ptr , hash_buffer .size );
566
- #endif
567
571
}
568
572
569
573
return result ;
0 commit comments