diff --git a/docs/design.md b/docs/design.md index 6301d91c..b1b47094 100644 --- a/docs/design.md +++ b/docs/design.md @@ -888,6 +888,24 @@ producing signed images, see: [signed_images](signed_images.md). If you want to enable and use encrypted images, see: [encrypted_images](encrypted_images.md). +### [Using Hardware Keys for Verification](#hw-key-support) + +By default, the whole public key is embedded in the bootloader code and its +hash is added to the image manifest as a KEYHASH TLV entry. As an alternative +the bootloader can be made independent of the keys by setting the +`MCUBOOT_HW_KEY` option. In this case the hash of the public key must be +provisioned to the target device and mcuboot must be able to retrieve the +key-hash from there. For this reason the target must provide a definition +for the `boot_retrieve_public_key_hash()` function which is declared in +`boot/bootutil/include/bootutil/sign_key.h`. It is also required to use +the `full` option for the `--public-key-format` imgtool argument in order to +add the whole public key (PUBKEY TLV) to the image manifest instead of its +hash (KEYHASH TLV). During boot the public key is validated before using it for +signature verification, mcuboot calculates the hash of the public key from the +TLV area and compares it with the key-hash that was retrieved from the device. +This way mcuboot is independent from the public key(s). The key(s) can be +provisioned any time and by different parties. + ## [Protected TLVs](#protected-tlvs) If the TLV area contains protected TLV entries, by beginning with a `struct @@ -966,14 +984,90 @@ is set). ### [HW Based Downgrade Prevention](#hw-downgrade-prevention) -Each signed image can contain a security counter in its protected TLV area. +Each signed image can contain a security counter in its protected TLV area, which +can be added to the image using the `-s` option of the [imgtool](imgtool.md) script. During the hardware based downgrade prevention (alias rollback protection) the new image's security counter will be compared with the currently active security counter value which must be stored in a non-volatile and trusted component of -the device. This feature is enabled with the `MCUBOOT_HW_ROLLBACK_PROT` option. -It is beneficial to handle this counter independently from image version -number: +the device. It is beneficial to handle this counter independently from image +version number: * It does not need to increase with each software release, * It makes it possible to do software downgrade to some extent: if the security counter has the same value in the older image then it is accepted. + +It is an optional step of the image validation process and can be enabled with +the `MCUBOOT_HW_ROLLBACK_PROT` config option. When enabled, the target must +provide an implementation of the security counter interface defined in +`boot/bootutil/include/security_cnt.h`. + +## [Measured boot and data sharing](#boot-data-sharing) + +MCUBoot defines a mechanism for sharing boot status information (also known as +measured boot) and an interface for sharing application specific information +with the runtime software. If any of these are enabled the target must provide +a shared data area between the bootloader and runtime firmware and define the +following parameters: + +```c +#define MCUBOOT_SHARED_DATA_BASE +#define MCUBOOT_SHARED_DATA_SIZE +``` + +In the shared memory area all data entries are stored in a type-length-value +(TLV) format. Before adding the first data entry, the whole area is overwritten +with zeros and a TLV header is added at the beginning of the area during an +initialization phase. This TLV header contains a `tlv_magic` field with a value +of `SHARED_DATA_TLV_INFO_MAGIC` and a `tlv_tot_len` field which is indicating +the total length of shared TLV area including this header. The header is +followed by the the data TLV entries which are composed from a +`shared_data_tlv_entry` header and the data itself. In the data header there is +a `tlv_type` field which identifies the consumer of the entry (in the runtime +software) and specifies the subtype of that data item. More information about +the `tlv_type` field and data types can be found in the +`boot/bootutil/include/bootutil/boot_status.h` file. The type is followed by a +`tlv_len` field which indicates the size of the data entry in bytes, not +including the entry header. After this header structure comes the actual data. + +```c +/** Shared data TLV header. All fields in little endian. */ +struct shared_data_tlv_header { + uint16_t tlv_magic; + uint16_t tlv_tot_len; /* size of whole TLV area (including this header) */ +}; + +/** Shared data TLV entry header format. All fields in little endian. */ +struct shared_data_tlv_entry { + uint16_t tlv_type; + uint16_t tlv_len; /* TLV data length (not including this header). */ +}; +``` + +The measured boot can be enabled with the `MCUBOOT_MEASURED_BOOT` config option. +When enabled, the `--boot_record` argument of the imgtool script must also be +used during the image signing process to add a BOOT_RECORD TLV to the image +manifest. This TLV contains the following attributes/measurements of the +image in CBOR encoded format: + + * Software type (role of the software component) + * Software version + * Signer ID (identifies the signing authority) + * Measurement value (hash of the image) + * Measurement type (algorithm used to calculate the measurement value) + +The `sw_type` string that is passed as the `--boot_record` option's parameter +will be the value of the "Software type" attribute in the generated BOOT_RECORD +TLV. The target must also define the `MAX_BOOT_RECORD_SZ` macro which indicates +the maximum size of the CBOR encoded boot record in bytes. +During boot, MCUBoot will look for these TLVs (in case of multiple images) in +the manifests of the active images (the latest and validated) and copy the CBOR +encoded binary data to the shared data area. Preserving all these image +attributes from the boot stage for use by later runtime services (such as an +attestation service) is known as a measured boot. + +Setting the `MCUBOOT_DATA_SHARING` option enables the sharing of application +specific data using the same shared data area as for the measured boot. For +this, the target must provide a definition for the `boot_save_shared_data()` +function which is declared in `boot/bootutil/include/bootutil/boot_record.h`. +The `boot_add_data_to_shared_area()` function can be used for adding new TLV +entries to the shared data area. diff --git a/docs/imgtool.md b/docs/imgtool.md index f9b46e04..97f32722 100644 --- a/docs/imgtool.md +++ b/docs/imgtool.md @@ -43,7 +43,8 @@ the key file. 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. +into the key file. However, when the `MCUBOOT_HW_KEY` config option is +enabled, this last step is unnecessary and can be skipped. ## [Signing images](#signing-images) @@ -54,24 +55,46 @@ primary slot and adds a header and trailer that the bootloader is expecting: Create a signed or unsigned image + INFILE and OUTFILE are parsed as Intel HEX if the params have .hex + extension, otherwise binary format is used + Options: -k, --key filename - --align [1|2|4|8] [required] - -v, --version TEXT [required] + --public-key-format [hash|full] + --align [1|2|4|8] [required] + -v, --version TEXT [required] + -s, --security-counter TEXT Specify the value of security counter. Use + the `auto` keyword to automatically generate + it from the image version. -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. + --pad-sig Add 0-2 bytes of padding to ECDSA signature + (for mcuboot <1.5) + -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 + --confirm When padding the image, mark it as confirmed + -M, --max-sectors INTEGER When padding allow for this amount of + sectors (defaults to 128) + --boot-record sw_type Create CBOR encoded boot record TLV. The + sw_type represents the role of the software + component (e.g. CoFM for coprocessor + firmware). [max. 12 characters] + --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 + --save-enctlv When upgrading, save encrypted key TLVs + instead of plain keys. Enable when + BOOT_SWAP_SAVE_ENCTLV config option was set. + -L, --load-addr INTEGER Load address for image when it should run + from RAM. + -x, --hex-addr INTEGER Adjust address in hex output file. + -R, --erased-val [0|0xff] The value that is read back from erased + flash. + -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 @@ -102,3 +125,11 @@ A dependency can be specified in the following way: 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. + +The `--public-key-format` argument can be used to distinguish where the public +key is stored for image authentication. The `hash` option is used by default, in +which case only the hash of the public key is added to the TLV area (the full +public key is incorporated into the bootloader). When the `full` option is used +instead, the TLV area will contain the whole public key and thus the bootloader +can be independent from the key(s). For more information on the additional +requirements of this option, see the [design](design.md) document. diff --git a/docs/signed_images.md b/docs/signed_images.md index 46d44152..22a6836c 100644 --- a/docs/signed_images.md +++ b/docs/signed_images.md @@ -33,6 +33,9 @@ be useful when you want to prevent production units from booting development images, but want development units to be able to boot both production images and development images. +For an alternative solution when the public key(s) doesn't need to be +included in the bootloader, see the [design](design.md) document. + ## Creating signing keys First you need a keypair to use for signing. You can create one with openssl command line tool.