-
Notifications
You must be signed in to change notification settings - Fork 726
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update Mbed OS CMake build file for Mbed CE #2152
Update Mbed OS CMake build file for Mbed CE #2152
Conversation
boot/bootutil/src/swap_scratch.c
Outdated
@@ -174,6 +174,13 @@ boot_slots_compatible(struct boot_loader_state *state) | |||
j = sz1 = secondary_slot_sz = 0; | |||
smaller = 0; | |||
while (i < num_sectors_primary || j < num_sectors_secondary) { | |||
// Make sure that the boot_img_sector_size() calls below don't access undefined memory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran into a rather nasty issue when testing where I didn't set BOOT_MAX_IMG_SECTORS large enough, so this for loop exhibited undefined behavior. Throwing in a check against this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't even make sense, this is already checked on line 156 above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I checked in the debugger, and if I set BOOT_MAX_IMG_SECTORS to 1000, on a device that uses 1536, I see:
.
Looking into it a bit more, it seems this may be an issue due to the Mbed version of flash_area_get_sectors() never returning a count
value greater than MCUBOOT_MAX_IMG_SECTORS
. That causes the existing warning (which I totally didn't notice X_X) to never trigger.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok pushed a fix!
boot/bootutil/src/swap_scratch.c
Outdated
@@ -174,6 +174,13 @@ boot_slots_compatible(struct boot_loader_state *state) | |||
j = sz1 = secondary_slot_sz = 0; | |||
smaller = 0; | |||
while (i < num_sectors_primary || j < num_sectors_secondary) { | |||
// Make sure that the boot_img_sector_size() calls below don't access undefined memory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't even make sense, this is already checked on line 156 above
boot/bootutil/src/swap_scratch.c
Outdated
// Make sure that the boot_img_sector_size() calls below don't access undefined memory. | ||
if(i >= BOOT_MAX_IMG_SECTORS || j >= BOOT_MAX_IMG_SECTORS) | ||
{ | ||
BOOT_LOG_WRN("Cannot upgrade: BOOT_MAX_IMG_SECTORS too small"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changes need to be squashed
boot/mbed/mcuboot_imgtool.cmake
Outdated
# Find or install imgtool ------------------------------------------------------------------------ | ||
|
||
if(NOT MCUBOOT_IMGTOOL_FOUND) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
boot/mbed/mcuboot_imgtool.cmake
Outdated
|
||
get_filename_component(IMGTOOL_SCRIPTS_DIR ${CMAKE_CURRENT_LIST_DIR}/../../scripts REALPATH) | ||
|
||
# Find or install imgtool ------------------------------------------------------------------------ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dashes not needed on comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
boot/mbed/mcuboot_imgtool.cmake
Outdated
|
||
if(NOT MCUBOOT_IMGTOOL_FOUND) | ||
|
||
# If we are using the Mbed venv, we can install asn1tools automatically |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cmake indent is 2 spaces not 4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
converted to 2
boot/mbed/mcuboot_imgtool.cmake
Outdated
# this function. Otherwise, it will default to ${CMAKE_CURRENT_BINARY_DIR}/<target name>-initial-image.hex | ||
# | ||
function(mcuboot_generate_initial_image TARGET) # optional 2nd arg: file name | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
boot/mbed/mcuboot_imgtool.cmake
Outdated
gen_upload_target(${TARGET}-${IMAGE_TYPE}-image ${IMAGE_BASE_PATH}.bin) | ||
add_dependencies(flash-${TARGET}-${IMAGE_TYPE}-image ${TARGET}) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
boot/mbed/src/flash_map_backend.cpp
Outdated
bd_size_t erase_size = bd->get_erase_size(offset); | ||
sectors[*count].fs_size = erase_size; | ||
|
||
if(*count < MCUBOOT_MAX_IMG_SECTORS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spaces needed in c code i.e. if (
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
boot/mbed/src/flash_map_backend.cpp
Outdated
sectors[*count].fs_size = erase_size; | ||
|
||
if(*count < MCUBOOT_MAX_IMG_SECTORS) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also as code above, bracket goes on same line as if
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
0fa393a
to
57c1b31
Compare
@multiplemonomials I tested encrypted image with 0fa393a as bootloader, and mcuboot v1.8.0 included in primary application on DISCO_F746NG. This feature seems working now. I guess there was a bug in v1.8.0 to upgrade from encrypted image. I will wait until you are done with this batch of revision to update documentation. A minor issue: is
The build bootloader hex file has content up till 0x1D034. Other than this I don't see other issues as far as bootloader is concerned. |
@zhiyong-ft If you use the new methodology with flash bank settings, then:
Size without Application header (0x1000) and Trailer TLV's (0x1000), total slot size 0xC0000 in my case. |
Could you point me the documentation on this? I tried to build the bootloader for NUCLEO_F767ZI, starting address in hex file is: |
Just to point out that v1.8.0 is 3 years old at this point, it should not be being used |
v1.8.0 from what? |
MCUboot: https://github.com/mcu-tools/mcuboot/releases/tag/v1.8.0 |
I am using the fork:
|
The unfortunate fact is that before @multiplemonomials started to work on it, v1.8.0 was the last working version that can build in Mbed Studio and upgrade unencrypted image from secondary slot, yet crashes when trying to upgrade from encrypted image. But this is behind us now. |
Using encrypted images will be my next step. And returning from using mbed-ce is no option anymore. My firmware is almost finished and I spent two years on it. |
I outlined steps needed to get encrypted image to work in another thread. Give it a try. It is rather straightforward once we know it is working. It took me a while to map out the kinks because it was not mentioned at all in Mr. Beckstein's original port. He too seems have had some trouble. |
Can you paste a link to that? |
e8017b7
to
ce340d5
Compare
@zhiyong-ft @nordicjm I have updated this PR in response to comments and to add a way to generate encrypted images. Should be ready for another look! |
@multiplemonomials I can confirm that mcuboot as of ce340d5 can boot primary application and upgrade encrypted images from secondary slot. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor nit. looks ok
6b84b5a
to
a4da87d
Compare
@nordicjm updated to add signed-off-by, could you trigger CI again? |
Any idea why the Zephyr check is failing? I don't believe it's related to anything I did... |
You need to rebase your branch, that issue has been fixed |
a4da87d
to
de8c4b0
Compare
Oh, gotcha. Done! |
491f9e9
to
49ea56a
Compare
Signed-off-by: Jamie Smith <jsmith@crackofdawn.onmicrosoft.com>
49ea56a
to
2894851
Compare
@nordicjm Would you be able to run the workflows? Also I pushed a minor update to fix a CMake issue and a multiple macro def error. |
Also, quick question. George Beckstein's original documentation said that the header size had to be set (via the argument to imgtool) to be one entire flash sector. However, there are some devices, such as STM32H7, where the flash sector size is so large (128kB) that imgtool cannot encode a header that large. Also, I tried not setting the header size just to see what would happen, and it seems like it works fine without making the header a complete flash sector. So, is this actually a requirement? It seems like it is not and I should remove this from our documentation. |
I also like clear instructions with no ambiguities. cfr my earlier questions: why giving key if prim image is not encryped? Why giving pem file which contains priv and public key? etc. |
Well, the pem file is used by the cmake scripts to export the puclic key. If you really wanted, you could just pass the public key as a C source file for the signing key. |
The unlogic thing is: And signing_keys.pem or enc_keys.pem is the source for priv and public key but in these files I only see:
|
I am a bit annoyed by this too. I think it all boils down to if bootloader needs to make any changes to header section after initial writing. If bootloader every needs to write something into header, then it has to erase at least an entire erasable sector. I don't know the source code of mcuboot enough to make a judgement call here. |
That is not correct, the header size should be a multiple of the vector table size, which on a cortex M4 default design is 512 bytes. The header is never rewritten |
Bootloader has public signing key and full key for encryption (encryption is symmetrical, there is no public key). Private signing key is needed to sign images, public key can only verify them, thus what is needed is correct |
Thanks for your clarification, this is such a relief. Some of MCUs I work with have 256KB sectors. Could you also comment on if we should use a separate key to encrypt images or we can safely use the public derived from the signing key for encryption as well? I have tried, just want to know which is better practice from security's perspective. |
You would need to use overwrite only mode for those devices since they cannot store the swap status information, so you have no ability to revert (or alternatively direct-xip). You can't use the same key no, signing is an asymmetrical key of RSA/ED25519/ECDSA-P256, encryption is a symmetrical AES key |
@multiplemonomials I can confirm that header doesn't have to occupy an entire erasable sector. On STM32F767ZI, the following parameters in 'mbed_app.json` of primary application works just fine:
First 4KB of that 32KB sector is reserved for header. With such setup, bootloader can boot primary application, primary application can call Btw, I think 4KB is still way more than necessary. In the signed hex file for initial download, only 32B is actually used. |
@nordicjm Thanks for the info, I have updated our docs. I'm good to merge if you are! |
@nordicjm I feel I didn't ask the question clearly. I meant to ask about the following two approaches:
In both cases, in a literal sense we are using two different keys for signing and encryption, because the length and content of keys are different. But in approach 1, the key used for encryption is derived/extracted from signing key, so in a logic sense, they are the same key. Do you still think approach 2 is preferred? Sorry to ask the question again, in the end it is probably not important, I just want to get it done right. |
Keys should be different for signing and encryption |
What you extract in this case is the public key which goes into the bootloader; the private key should remain, well, private!
This is not related to MCUboot, but there is a cryptography rule which states that every key has one purpose, and they should never be reused. This is described in this way by NIST:
You can read key management rules here (section 5.2): https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r5.pdf In the case of MCUboot it's even worse to re-use the keys, because then you'd have both private and public keys from the same keypair into the bootloader itself, completely defeating the security. |
Hi, I'm Jamie, maintainer of Mbed CE, the community fork of Mbed. As Mbed OS 6 has been end-of-lifed by ARM, we hope to keep support for the OS alive in our fork for a long time coming!
Several members of the project have expressed interest in getting mcuboot running with Mbed CE, so I took some time and put together a test project based off of George Beckstein's original work. I was able to get it working more or less out of the box, but I did have to make some build system changes to get things running.
In particular, I wasn't happy with how the original design required running manual commands after compiling the code. That was an unfortunate necessity with the original Mbed 5/6 build system, but with Mbed CE, we use standard CMake, so we can improve this situation! I added a CMake script which automates calling imgtool to generate initial images, update images, and the public key file needed to build the bootloader.
With these changes, I am able to get a rudimentary demo application booting and updating. I and the others on the mbed-ce project (including @lefebvresam and @zhiyong-ft) hope to test out (and document) more features in time!
On another note, we heard from this issue that there is discussion about removing the Mbed port of mcuboot. We at mbed-ce are happy to help maintain and test the port going forward, and really want it to stay in the main branch of mcuboot!
Compatibility note: This PR will maintain compatibility with Mbed OS 6 using the Mbed CLI build system and/or Mbed Studio. However, it will break compatibility with the Mbed CLI 2 CMake-based build system. This build system never really reached maturity before ARM Mbed shut down, so I doubt that too many people will be using it who do not use Mbed CE.