mcuboot/docs/imgtool.md

4.6 KiB

Image tool

The Python program scripts/imgtool.py can be used to perform the operations that are necessary to manage keys and sign images. Using this script should be preferred to the manual steps described in doc/signed_images.md.

This program is written for Python3, and has several dependencies on Python libraries. These can be installed using 'pip3':

pip3 install --user -r scripts/requirements.txt

Managing keys

This tool currently supports rsa-2048, rsa-3072, ecdsa-p256 and ed25519 keys. You can generate a keypair for one of these types using the 'keygen' command:

./scripts/imgtool.py keygen -k filename.pem -t rsa-2048

or use rsa-3072, ecdsa-p256, or ed25519 for the type. The key type used should match what mcuboot is configured to verify.

This key file is what is used to sign images, this file should be protected, and not widely distributed.

You can add the -p argument to keygen, which will cause it to prompt for a password. You will need to enter this password in every time you use the private key.

Incorporating the public key into the code

There is a development key distributed with mcuboot that can be used for testing. Since this private key is widely distributed, it should never be used for production. Once you have generated a production key, as described above, you should replace the public key in the bootloader with the generated one.

For Zephyr, the keys live in the file boot/zephyr/keys.c. For mynewt, follow the instructions in doc/signed_images.md to generate the key file.

./scripts/imgtool.py getpub -k filename.pem

will extract the public key from the given private key file, and output it as a C data structure. You can replace or insert this code into the key file.

Signing images

Image signing takes an image in binary or Intel Hex format intended for the primary slot and adds a header and trailer that the bootloader is expecting:

Usage: imgtool.py sign [OPTIONS] INFILE OUTFILE

  Create a signed or unsigned image

Options:
  -k, --key filename
  --align [1|2|4|8]          [required]
  -v, --version TEXT         [required]
  -d, --dependencies TEXT
  -H, --header-size INTEGER  [required]
  --pad-header               Add --header-size zeroed bytes at the beginning
                             of the image
  -S, --slot-size INTEGER    Size of the slot where the image will be
                             written [required]
  --pad                      Pad image to --slot-size bytes, adding trailer
                             magic
  -M, --max-sectors INTEGER  When padding allow for this amount of sectors
                             (defaults to 128)
  --overwrite-only           Use overwrite-only instead of swap upgrades
  -e, --endian [little|big]  Select little or big endian
  -E, --encrypt filename     Encrypt image using the provided public key
  -h, --help                 Show this message and exit.

The main arguments given are the key file generated above, a version field to place in the header (1.2.3 for example), the alignment of the flash device in question, and the header size.

The header size depends on the operating system and the particular flash device. For Zephyr, it will be configured as part of the build, and will be a small power of two. By default, the Zephyr build system will already prepended a zeroed header to the image. If another build system is in use that does not automatically add this zeroed header, --pad-header can be passed and the --header-size will be added by imgtool. If --pad-header is used with an Intel Hex file, --header-size bytes will be subtracted from the load address (in Intel Hex terms, the Extended Linear Address record) to adjust for the new bytes prepended to the file. The load address of all data existing in the file should not change.

The --slot-size argument is required and used to check that the firmware does not overflow into the swap status area (metadata). If swap upgrades are not being used, --overwrite-only can be passed to avoid adding the swap status area size when calculating overflow.

The optional --pad argument will place a trailer on the image that indicates that the image should be considered an upgrade. Writing this image in the secondary slot will then cause the bootloader to upgrade to it.

A dependency can be specified in the following way: -d "(image_id, image_version)". The image_id is the number of the image which the current image depends on. The image_version is the minimum version of that image to satisfy compliance. For example -d "(1, 1.2.3+0)" means this image depends on Image 1 which version has to be at least 1.2.3+0.