55******************************************************************************
66*/
77/*
8- * Copyright (c) 2021 Firmware Modules Inc.
8+ * Copyright (c) 2021-2022 Firmware Modules Inc.
99 *
1010 * Permission is hereby granted, free of charge, to any person obtaining a copy
1111 * of this software and associated documentation files(the "Software"), to deal
@@ -51,34 +51,53 @@ typedef enum
5151} SE_StatusTypeDef ;
5252
5353/*!
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 -
6260* 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.
7891*
7992* @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.
82101*
83102* @a(Thread Safety)
84103* The APIs in this module are NOT thread-safe
@@ -112,6 +131,11 @@ typedef enum
112131* @value(StatusCode_INVALID_ORDER) Supplied data with incorrect order for the current state
113132* @value(StatusCode_TOO_FEW_BYTES) Supplied first data packet with less than minimum required bytes
114133* @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
115139*/
116140typedef enum
117141{
@@ -146,9 +170,9 @@ typedef enum
146170
147171
148172/*!
149- * High-level AMDM image types.
173+ * High-level patching engine image types.
150174 *
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 .
152176 */
153177typedef enum
154178{
@@ -175,7 +199,7 @@ typedef enum
175199/*!
176200* Update start setup data structure.
177201*
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 .
179203* This field may be set if known, or may be omitted (set to NONE) to use the firmware update image's
180204* embedded type determined on-the-fly.
181205* @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
286310
287311/*!
288312* Supply a portion of a stream of data to the firmware patching engine.
313+ * Accepts byte streams from .sfb or .sfbp files.
289314*
290315* This function blocks until the operation is completed which may consist of one or both of:
291316* @p(blist)
@@ -294,17 +319,18 @@ SE_ErrorStatus SE_PATCH_Init(SE_PATCH_Status* p_PatchStatus, const SE_PATCH_Star
294319* @p
295320*
296321* 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.
298326*
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.
304330*
305331* Additionally, the count of bytes is accumulated until the expected number
306332* 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 .
308334*
309335* @param(status) Supplied structure to be filled in with detailed API result status.
310336* @param(data) Pointer to firmware image data buffer
@@ -356,8 +382,8 @@ SE_ErrorStatus SE_PATCH_InstallAtNextReset(SE_PATCH_Status* status);
356382* the non-volatile memory can be detected by inspecting the returned status codes:
357383* @p(blist)
358384* - 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.
361387* (otherwise the currently running firmware image is booted again).
362388* @p
363389* @param(status) Supplied structure to be filled in with detailed API result status.
@@ -423,6 +449,19 @@ typedef struct
423449#define FW_VERSION_PATCH (x ) (((uint32_t)(x) >> 0) & 0x000000FF)
424450
425451SE_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+ */
426456SE_ErrorStatus SE_APP_GetSecureUserData (SE_StatusTypeDef * peSE_Status , void * p_Data , uint32_t len );
427457
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 );
428467
0 commit comments