5
5
******************************************************************************
6
6
*/
7
7
/*
8
- * Copyright (c) 2021 Firmware Modules Inc.
8
+ * Copyright (c) 2021-2022 Firmware Modules Inc.
9
9
*
10
10
* Permission is hereby granted, free of charge, to any person obtaining a copy
11
11
* of this software and associated documentation files(the "Software"), to deal
@@ -51,34 +51,53 @@ typedef enum
51
51
} SE_StatusTypeDef ;
52
52
53
53
/*!
54
- * Provides services for applications to update firmware in accordance with
55
- * the Firmware Modules' Application Management and Deployment Model.
56
- *
57
- * The application (APP) and manufacturing test application (MTA) sections in
58
- * the target non-volatile storage may be updated by presenting an update firmware
59
- * image that was generated with FM_Release. The Update module takes care of
60
- * choosing the correct APP section (APP1 or APP2) so as to support over-the-air
61
- * streaming firmware updating that is highly tolerant to link or device failure -
54
+ * Provides services to access bootloader and application versions, perform
55
+ * in-application firmware updates and access the user-provisioned OTP secure data area.
56
+ *
57
+ * The patching engine is the core of the stm32-secure-patching-bootloader firmware
58
+ * update system. It supports over-the-air streaming in-application firmware updating
59
+ * that is highly tolerant to link or device failure -
62
60
* the target device's running application remains safe at all times during this
63
- * process.
64
- *
65
- * Update APIs will NOT update firmware to older versions. If an older version (i.e. a 'downgrade')
66
- * is required, the changes must be reverted/implemented then built with a new version number.
67
- * The Update and AMDM system uses only the version number to determine which application
68
- * to boot and which application to overwrite when updating.
69
- *
70
- * The Update module does not maintain its own RAM buffer but rather utilizes
71
- * the buffers provided by existing packet transport infrastructure. The only
72
- * requirement on these buffers is that the *first* buffer provided must contain
73
- * at least {@link #getMinUpdateImageDataLen} bytes. This value is platform
74
- * dependent, therefore transport buffer sizing must take this value into account as well.
75
- * The first buffer must contain enough bytes to verify that a firmware image is
76
- * indeed being supplied to the update engine. The actual firmware image length is
77
- * extracted from the content of the first buffer supplied to {@link #data}.
61
+ * process thanks to the dual slot architecture.
62
+ *
63
+ * Patching engine APIs (SE_PATCH_) are designed to process Secure Firmware Binary (.sfb)
64
+ * or Secure Firmware Binary Patch (.sfbp) files generated by the
65
+ * stm32-secure-patching-bootloader build system. The user is required to pass the
66
+ * file binary data in arbitrarily sized chunks through the Data() API.
67
+ *
68
+ * Full-image .sfb files contain the entire new firmware update image and therefore
69
+ * updates can be performed to any available newer version.
70
+ * Patch files .sfbp, on the other hand, only contain the differences between the
71
+ * current version on the device and the new version. Consequently, patch files
72
+ * only work if the required "from" version already exists on the device with a
73
+ * fully matching SHA256 digest. Attempting an update with an incorrect patch file
74
+ * has no effect on the system or running application - the patch file is immediately rejected
75
+ * due to "from" version or SHA256 mismatch (fields digitally signed in the file header).
76
+ * The choice of using full or patch file update images depends
77
+ * on delivery method bandwidth constraints and how much attention is paid
78
+ * to the firmware release and delivery process in your organization.
79
+ *
80
+ * The patching engine will NOT update firmware to older versions (security feature).
81
+ * If an older version (i.e. a 'downgrade') is required, the changes must be
82
+ * reverted/implemented then built with a new version number.
83
+ *
84
+ * The patching engine utilizes the buffers provided by the caller of the Data() API.
85
+ * There are no requirements on these buffers - they can contain as little as 1 byte
86
+ * of .sfb or .sfbp file data per invocation.
87
+ *
88
+ * The system employs multiple protections to ensure it is virtually impossible to
89
+ * inject wrong or malformed firmware update binary data and cause fault or failure in the
90
+ * system. Digital signatures with SHA256 integrity checking ensure correctness of binary data.
78
91
*
79
92
* @a(Security Policies)
80
- * It is strongly advised to use a secure transport for data (for both commands and firmware images)
81
- * provided over the air to the APIs in this module.
93
+ * Firmware images are protected from tampering (digitally signed) and from IP theft
94
+ * (encrypted). The methods selected to transport the firmware update images (.sfb, .sfbp)
95
+ * are not required to be secured and can be user-distributed (e.g. from a public web page).
96
+ * Chip-level readout protection (RDP level 2) option byte is recommended to be
97
+ * programmed for production devices to protect the digital signature public key (ECDSA) and
98
+ * the decryption private key (AES).
99
+ * Production versions of the stm32-secure-patching-bootloader enforce chip-level readout
100
+ * protection (RDP level 2) at each startup to help protect against possible physical attack vectors.
82
101
*
83
102
* @a(Thread Safety)
84
103
* The APIs in this module are NOT thread-safe
@@ -112,6 +131,11 @@ typedef enum
112
131
* @value(StatusCode_INVALID_ORDER) Supplied data with incorrect order for the current state
113
132
* @value(StatusCode_TOO_FEW_BYTES) Supplied first data packet with less than minimum required bytes
114
133
* @value(StatusCode_PARSER_ERROR) Update container format parser has encountered an unrecoverable error in the byte stream
134
+ * @value(StatusCode_DECRYPTION_ERROR) Update container format stream decryption has failed
135
+ * @value(StatusCode_INSTALL_ERROR) Error finalizing the newly written firmware in download slot (automatically or through SE_PATCH_InstallAtNextReset)
136
+ * @value(StatusCode_FLASH_ERROR) Flash (possibly external) initialization error
137
+ * @value(StatusCode_FLASH_SEGMENT_ERROR) Error initializing the SEGMENT read layer for external flash MultiSegment feature
138
+ * @value(StatusCode_FLASH_CIPHER_ERROR) Error initializing the CIPHER write layer for external flash MultiSegment feature
115
139
*/
116
140
typedef enum
117
141
{
@@ -146,9 +170,9 @@ typedef enum
146
170
147
171
148
172
/*!
149
- * High-level AMDM image types.
173
+ * High-level patching engine image types.
150
174
*
151
- * These are the types of firmware images that may be presented to the Update module .
175
+ * These are the types of firmware images that may be presented to the patching engine .
152
176
*/
153
177
typedef enum
154
178
{
@@ -175,7 +199,7 @@ typedef enum
175
199
/*!
176
200
* Update start setup data structure.
177
201
*
178
- * @field(type) Target update location of firmware image presented to Update module .
202
+ * @field(type) Target update location of firmware image presented to patching engine .
179
203
* This field may be set if known, or may be omitted (set to NONE) to use the firmware update image's
180
204
* embedded type determined on-the-fly.
181
205
* @field(rebootDelay) Specify the reboot delay that is to occur after a completed firmware update.
@@ -286,6 +310,7 @@ SE_ErrorStatus SE_PATCH_Init(SE_PATCH_Status* p_PatchStatus, const SE_PATCH_Star
286
310
287
311
/*!
288
312
* Supply a portion of a stream of data to the firmware patching engine.
313
+ * Accepts byte streams from .sfb or .sfbp files.
289
314
*
290
315
* This function blocks until the operation is completed which may consist of one or both of:
291
316
* @p(blist)
@@ -294,17 +319,18 @@ SE_ErrorStatus SE_PATCH_Init(SE_PATCH_Status* p_PatchStatus, const SE_PATCH_Star
294
319
* @p
295
320
*
296
321
* No action is taken against the non-volatile storage unless the provided
297
- * data was verified to contain the start of a valid firmware image.
322
+ * data was verified to contain the start of a valid firmware image whose
323
+ * signature verifies correctly by the public signing key embedded in the
324
+ * on-board stm32-secure-patching-bootloader. In the case of a patch file (.sfbp)
325
+ * the 'source' firmware's - that is, the firmware already on the device - sha256 tag must also match.
298
326
*
299
- * There is a requirement for data ordering - the first
300
- * {@link #getMinUpdateImageDataLen} bytes must be sent first and available as a unit
301
- * to the `data` function. These bytes contain enough information for the updater
302
- * to make a decision on whether to proceed. All subsequent bytes of the
303
- * firmware update image must also be delivered in order.
327
+ * There is no requirement on how many bytes can be delivered in each Data invocation:
328
+ * as little as 1 byte can be supplied and there is no upper limit other than the
329
+ * size of the buffer the application can supply.
304
330
*
305
331
* Additionally, the count of bytes is accumulated until the expected number
306
332
* of bytes is received, at which time the written firmware image will be fully verified.
307
- * There is no protection against duplicate data packets .
333
+ * Any subsequent bytes will be ignored .
308
334
*
309
335
* @param(status) Supplied structure to be filled in with detailed API result status.
310
336
* @param(data) Pointer to firmware image data buffer
@@ -356,8 +382,8 @@ SE_ErrorStatus SE_PATCH_InstallAtNextReset(SE_PATCH_Status* status);
356
382
* the non-volatile memory can be detected by inspecting the returned status codes:
357
383
* @p(blist)
358
384
* - StatusCode_SECTION_ERASE_FAILURE: could not invalidate image.
359
- * if an image was successfully written, upon next reboot it will be
360
- * booted, but only if it verifies successfully by the bootloader
385
+ * if an image was successfully written, upon next reboot the bootloader will
386
+ * attempt to install it but only if it verifies successfully.
361
387
* (otherwise the currently running firmware image is booted again).
362
388
* @p
363
389
* @param(status) Supplied structure to be filled in with detailed API result status.
@@ -423,6 +449,19 @@ typedef struct
423
449
#define FW_VERSION_PATCH (x ) (((uint32_t)(x) >> 0) & 0x000000FF)
424
450
425
451
SE_ErrorStatus SE_APP_GetActiveFwInfo (SE_StatusTypeDef * peSE_Status , SE_APP_ActiveFwInfo * p_FwInfo );
452
+
453
+ /* Copy the pre-provisoned secure user data into the provided pointer buffer.
454
+ * This is an OTP area inside the bootloader flash area containing a maximum of 128 bytes.
455
+ */
426
456
SE_ErrorStatus SE_APP_GetSecureUserData (SE_StatusTypeDef * peSE_Status , void * p_Data , uint32_t len );
427
457
458
+ /* Get the bootloader version as a string in the format "v<major>.<minor>.<patch>" e.g. "v1.2.0"
459
+ * The buffer is always null-terminated when the function returns.
460
+ * A user buffer of at least 16 bytes is suggested. A buffer smaller than the bootloader version string length
461
+ * will simply contain a truncated null-terminated string.
462
+ *
463
+ * @param p_Data buffer to copy bootloader version string into.
464
+ * @param len length of provided buffer.
465
+ */
466
+ SE_ErrorStatus SE_APP_GetBootVer (SE_StatusTypeDef * peSE_Status , char * p_Data , uint32_t len );
428
467
0 commit comments