David Brown | d2fcc21 | 2017-09-11 14:47:48 -0600 | [diff] [blame] | 1 | # Image tool |
David Brown | e369fec | 2017-06-07 09:35:48 -0600 | [diff] [blame] | 2 | |
| 3 | The Python program `scripts/imgtool.py` can be used to perform the |
| 4 | operations that are necessary to manage keys and sign images. Using |
| 5 | this script should be preferred to the manual steps described in |
| 6 | `doc/signed_images.md`. |
| 7 | |
| 8 | This program is written for Python3, and has several dependencies on |
Carles Cufi | f242901 | 2018-01-30 16:45:50 +0100 | [diff] [blame] | 9 | Python libraries. These can be installed using 'pip3': |
David Brown | e369fec | 2017-06-07 09:35:48 -0600 | [diff] [blame] | 10 | |
Carles Cufi | f242901 | 2018-01-30 16:45:50 +0100 | [diff] [blame] | 11 | pip3 install --user -r scripts/requirements.txt |
David Brown | e369fec | 2017-06-07 09:35:48 -0600 | [diff] [blame] | 12 | |
Fabio Utzig | d37d877 | 2019-12-03 10:32:18 -0300 | [diff] [blame] | 13 | ## [Managing keys](#managing-keys) |
David Brown | e369fec | 2017-06-07 09:35:48 -0600 | [diff] [blame] | 14 | |
Fabio Utzig | 8101d1f | 2019-05-09 15:03:22 -0300 | [diff] [blame] | 15 | This tool currently supports rsa-2048, rsa-3072, ecdsa-p256 and ed25519 keys. |
| 16 | You can generate a keypair for one of these types using the 'keygen' command: |
David Brown | e369fec | 2017-06-07 09:35:48 -0600 | [diff] [blame] | 17 | |
| 18 | ./scripts/imgtool.py keygen -k filename.pem -t rsa-2048 |
| 19 | |
Fabio Utzig | 8101d1f | 2019-05-09 15:03:22 -0300 | [diff] [blame] | 20 | or use rsa-3072, ecdsa-p256, or ed25519 for the type. The key type used |
| 21 | should match what mcuboot is configured to verify. |
David Brown | e369fec | 2017-06-07 09:35:48 -0600 | [diff] [blame] | 22 | |
| 23 | This key file is what is used to sign images, this file should be |
| 24 | protected, and not widely distributed. |
| 25 | |
David Brown | 31d29c8 | 2017-11-21 15:38:56 -0700 | [diff] [blame] | 26 | You can add the `-p` argument to `keygen`, which will cause it to |
| 27 | prompt for a password. You will need to enter this password in every |
| 28 | time you use the private key. |
| 29 | |
Fabio Utzig | d37d877 | 2019-12-03 10:32:18 -0300 | [diff] [blame] | 30 | ## [Incorporating the public key into the code](#incorporating-the-public-key-into-the-code) |
David Brown | e369fec | 2017-06-07 09:35:48 -0600 | [diff] [blame] | 31 | |
| 32 | There is a development key distributed with mcuboot that can be used |
| 33 | for testing. Since this private key is widely distributed, it should |
| 34 | never be used for production. Once you have generated a production |
| 35 | key, as described above, you should replace the public key in the |
| 36 | bootloader with the generated one. |
| 37 | |
| 38 | For Zephyr, the keys live in the file `boot/zephyr/keys.c`. For |
| 39 | mynewt, follow the instructions in `doc/signed_images.md` to generate |
| 40 | the key file. |
| 41 | |
| 42 | ./scripts/imgtool.py getpub -k filename.pem |
| 43 | |
| 44 | will extract the public key from the given private key file, and |
| 45 | output it as a C data structure. You can replace or insert this code |
| 46 | into the key file. |
| 47 | |
Fabio Utzig | d37d877 | 2019-12-03 10:32:18 -0300 | [diff] [blame] | 48 | ## [Signing images](#signing-images) |
David Brown | e369fec | 2017-06-07 09:35:48 -0600 | [diff] [blame] | 49 | |
David Vincze | 2d736ad | 2019-02-18 11:50:22 +0100 | [diff] [blame] | 50 | Image signing takes an image in binary or Intel Hex format intended for the |
| 51 | primary slot and adds a header and trailer that the bootloader is expecting: |
David Brown | e369fec | 2017-06-07 09:35:48 -0600 | [diff] [blame] | 52 | |
Fabio Utzig | 5901fd5 | 2018-06-13 11:24:30 -0700 | [diff] [blame] | 53 | Usage: imgtool.py sign [OPTIONS] INFILE OUTFILE |
| 54 | |
| 55 | Create a signed or unsigned image |
| 56 | |
| 57 | Options: |
| 58 | -k, --key filename |
| 59 | --align [1|2|4|8] [required] |
| 60 | -v, --version TEXT [required] |
David Vincze | e32483f | 2019-06-13 10:46:24 +0200 | [diff] [blame] | 61 | -d, --dependencies TEXT |
Fabio Utzig | 5901fd5 | 2018-06-13 11:24:30 -0700 | [diff] [blame] | 62 | -H, --header-size INTEGER [required] |
Fabio Utzig | cdfa11a | 2018-10-01 09:45:54 -0300 | [diff] [blame] | 63 | --pad-header Add --header-size zeroed bytes at the beginning |
Fabio Utzig | 5901fd5 | 2018-06-13 11:24:30 -0700 | [diff] [blame] | 64 | of the image |
David Vincze | 2d736ad | 2019-02-18 11:50:22 +0100 | [diff] [blame] | 65 | -S, --slot-size INTEGER Size of the slot where the image will be |
| 66 | written [required] |
Fabio Utzig | 5901fd5 | 2018-06-13 11:24:30 -0700 | [diff] [blame] | 67 | --pad Pad image to --slot-size bytes, adding trailer |
| 68 | magic |
| 69 | -M, --max-sectors INTEGER When padding allow for this amount of sectors |
| 70 | (defaults to 128) |
| 71 | --overwrite-only Use overwrite-only instead of swap upgrades |
Fabio Utzig | cdfa11a | 2018-10-01 09:45:54 -0300 | [diff] [blame] | 72 | -e, --endian [little|big] Select little or big endian |
| 73 | -E, --encrypt filename Encrypt image using the provided public key |
Fabio Utzig | 5901fd5 | 2018-06-13 11:24:30 -0700 | [diff] [blame] | 74 | -h, --help Show this message and exit. |
David Brown | e369fec | 2017-06-07 09:35:48 -0600 | [diff] [blame] | 75 | |
| 76 | The main arguments given are the key file generated above, a version |
| 77 | field to place in the header (1.2.3 for example), the alignment of the |
| 78 | flash device in question, and the header size. |
| 79 | |
| 80 | The header size depends on the operating system and the particular |
| 81 | flash device. For Zephyr, it will be configured as part of the build, |
Fabio Utzig | 5901fd5 | 2018-06-13 11:24:30 -0700 | [diff] [blame] | 82 | and will be a small power of two. By default, the Zephyr build system will |
| 83 | already prepended a zeroed header to the image. If another build system is |
| 84 | in use that does not automatically add this zeroed header, `--pad-header` can |
Mark Schulte | b88b2c4 | 2018-07-17 07:47:03 -0700 | [diff] [blame] | 85 | be passed and the `--header-size` will be added by imgtool. If `--pad-header` |
| 86 | is used with an Intel Hex file, `--header-size` bytes will be subtracted from |
| 87 | the load address (in Intel Hex terms, the Extended Linear Address record) to |
| 88 | adjust for the new bytes prepended to the file. The load address of all data |
| 89 | existing in the file should not change. |
Fabio Utzig | 5901fd5 | 2018-06-13 11:24:30 -0700 | [diff] [blame] | 90 | |
| 91 | The `--slot-size` argument is required and used to check that the firmware |
| 92 | does not overflow into the swap status area (metadata). If swap upgrades are |
| 93 | not being used, `--overwrite-only` can be passed to avoid adding the swap |
| 94 | status area size when calculating overflow. |
David Brown | e369fec | 2017-06-07 09:35:48 -0600 | [diff] [blame] | 95 | |
Fabio Utzig | cdfa11a | 2018-10-01 09:45:54 -0300 | [diff] [blame] | 96 | The optional `--pad` argument will place a trailer on the image that |
David Vincze | 2d736ad | 2019-02-18 11:50:22 +0100 | [diff] [blame] | 97 | indicates that the image should be considered an upgrade. Writing this image |
| 98 | in the secondary slot will then cause the bootloader to upgrade to it. |
David Vincze | e32483f | 2019-06-13 10:46:24 +0200 | [diff] [blame] | 99 | |
| 100 | A dependency can be specified in the following way: |
| 101 | `-d "(image_id, image_version)"`. The `image_id` is the number of the image |
| 102 | which the current image depends on. The `image_version` is the minimum version |
| 103 | of that image to satisfy compliance. For example `-d "(1, 1.2.3+0)"` means this |
| 104 | image depends on Image 1 which version has to be at least 1.2.3+0. |