1<!-- 2 - 3 - Licensed to the Apache Software Foundation (ASF) under one 4 - or more contributor license agreements. See the NOTICE file 5 - distributed with this work for additional information 6 - regarding copyright ownership. The ASF licenses this file 7 - to you under the Apache License, Version 2.0 (the 8 - "License"); you may not use this file except in compliance 9 - with the License. You may obtain a copy of the License at 10 - 11 - http://www.apache.org/licenses/LICENSE-2.0 12 - 13 - Unless required by applicable law or agreed to in writing, 14 - software distributed under the License is distributed on an 15 - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 - KIND, either express or implied. See the License for the 17 - specific language governing permissions and limitations 18 - under the License. 19 - 20--> 21 22# Encrypted images 23 24## [Rationale](#rationale) 25 26To provide confidentiality of image data while in transport to the 27device or while residing on an external flash, `MCUboot` has support 28for encrypting/decrypting images on-the-fly while upgrading. 29 30The image header needs to flag this image as `ENCRYPTED` (0x04) and 31a TLV with the key must be present in the image. When upgrading the 32image from the `secondary slot` to the `primary slot` it is automatically 33decrypted (after validation). If swap upgrades are enabled, the image 34located in the `primary slot`, also having the `ENCRYPTED` flag set and the 35TLV present, is re-encrypted while swapping to the `secondary slot`. 36 37## [Threat model](#threat-model) 38 39The encrypted image support is supposed to allow for confidentiality 40if the image is not residing on the device or is written to external 41storage, eg a SPI flash being used for the secondary slot. 42 43It does not protect against the possibility of attaching a JTAG and 44reading the internal flash memory, or using some attack vector that 45enables dumping the internal flash in any way. 46 47Since decrypting requires a private key (or secret if using symmetric 48crypto) to reside inside the device, it is the responsibility of the 49device manufacturer to guarantee that this key is already in the device 50and not possible to extract. 51 52## [Design](#design) 53 54When encrypting an image, only the payload (FW) is encrypted. The header, 55TLVs are still sent as plain data. 56 57Hashing and signing also remain functionally the same way as before, 58applied over the un-encrypted data. Validation on encrypted images, checks 59that the encrypted flag is set and TLV data is OK, then it decrypts each 60image block before sending the data to the hash routines. 61 62The image is encrypted using AES-CTR-128 or AES-CTR-256, with a counter 63that starts from zero (over the payload blocks) and increments by 1 for each 6416-byte block. AES-CTR was chosen for speed/simplicity and allowing for any 65block to be encrypted/decrypted without requiring knowledge of any other 66block (allowing for simple resume operations on swap interruptions). 67 68The key used is a randomized when creating a new image, by `imgtool` or 69`newt`. This key should never be reused and no checks are done for this, 70but randomizing a 16-byte block with a TRNG should make it highly 71improbable that duplicates ever happen. 72 73To distribute this AES-CTR key, new TLVs were defined. The key can be 74encrypted using either RSA-OAEP, AES-KW (128 or 256 bits depending on the 75AES-CTR key length), ECIES-P256 or ECIES-X25519. 76 77For RSA-OAEP a new TLV with value `0x30` is added to the image, for 78AES-KW a new TLV with value `0x31` is added to the image, for 79ECIES-P256 a new TLV with value `0x32` is added, and for ECIES-X25519 a 80newt TLV with value `0x33` is added. The contents of those TLVs 81are the results of applying the given operations over the AES-CTR key. 82 83## [ECIES encryption](#ecies-encryption) 84 85ECIES follows a well defined protocol to generate an encryption key. There are 86multiple standards which differ only on which building blocks are used; for 87MCUboot we settled on some primitives that are easily found on our crypto 88libraries. The whole key encryption can be summarized as: 89 90* Generate a new private key and derive the public key; when using ECIES-P256 91 this is a secp256r1 keypair, when using ECIES-X25519 this will be a x25519 92 keypair. Those keys will be our ephemeral keys. 93* Generate a new secret (DH) using the ephemeral private key and the public key 94 that corresponds to the private key embedded in the HW. 95* Derive the new keys from the secret using HKDF (built on HMAC-SHA256). We 96 are not using a `salt` and using an `info` of `MCUBoot_ECIES_v1`, generating 97 48 bytes of key material. 98* A new random encryption key is generated (for AES). This is 99 the AES key used to encrypt the images. 100* The key is encrypted with AES-128-CTR or AES-256-CTR and a `nonce` of 0 using 101 the first 16 bytes of key material generated previously by the HKDF. 102* The encrypted key now goes through a HMAC-SHA256 using the remaining 32 103 bytes of key material from the HKDF. 104 105The final TLV is built from the 65 bytes for ECIES-P256 or 32 bytes for 106ECIES-X25519, which correspond to the ephemeral public key, followed by the 10732 bytes of MAC tag and the 16 or 32 bytes of the encrypted key, resulting in 108a TLV of 113 or 129 bytes for ECIES-P256 and 80 or 96 bytes for ECIES-X25519. 109 110The implemenation of ECIES-P256 is named ENC_EC256 in the source code and 111artifacts while ECIES-X25519 is named ENC_X25519. 112 113## [Upgrade process](#upgrade-process) 114 115When starting a new upgrade process, `MCUboot` checks that the image in the 116`secondary slot` has the `ENCRYPTED` flag set and has the required TLV with the 117encrypted key. It then uses its internal private/secret key to decrypt 118the TLV containing the key. Given that no errors are found, it will then 119start the validation process, decrypting the blocks before check. A good 120image being determined, the upgrade consists in reading the blocks from 121the `secondary slot`, decrypting and writing to the `primary slot`. 122 123If swap is used for the upgrade process, the encryption happens when 124copying the sectors of the `secondary slot` to the scratch area. 125 126The `scratch` area is not encrypted, so it must reside in the internal 127flash of the MCU to avoid attacks that could interrupt the upgrade and 128dump the data. 129 130Also when swap is used, the image in the `primary slot` is checked for 131presence of the `ENCRYPTED` flag and the key TLV. If those are present the 132sectors are re-encrypted when copying from the `primary slot` to 133the `secondary slot`. 134 135--- 136***Note*** 137 138*Each encrypted image must have its own key TLV that should be unique* 139*and used only for this particular image.* 140 141--- 142 143Also when swap method is employed, the sizes of both images are saved to 144the status area just before starting the upgrade process, because it 145would be very hard to determine this information when an interruption 146occurs and the information is spread across multiple areas. 147 148## [Creating your keys with imgtool](#creating-your-keys-with-imgtool) 149 150`imgtool` can generate keys by using `imgtool keygen -k <output.pem> -t <type>`, 151 where type can be one of `rsa-2048`, `rsa-3072`, `ecdsa-p256` 152or `ed25519`. This will generate a keypair or private key. 153 154To extract the public key in source file form, use 155`imgtool getpub -k <input.pem> -e <encoding>`, where `encoding` can be one of 156`lang-c` or `lang-rust` (defaults to `lang-c`). To extract a public key in PEM 157format, use `imgtool getpub -k <input.pem> -e pem`. 158 159If using AES-KW, follow the steps in the next section to generate the 160required keys. 161 162## [Creating your keys with Unix tooling](#creating-your-keys-with-unix-tooling) 163 164* If using RSA-OAEP, generate a keypair following steps similar to those 165 described in [signed_images](signed_images.md) to create RSA keys. 166* If using ECIES-P256, generate a keypair following steps similar to those 167 described in [signed_images](signed_images.md) to create ECDSA256 keys. 168* If using ECIES-X25519, generate a private key passing the option `-t x25519` 169 to `imgtool keygen` command. To generate public key PEM file the following 170 command can be used: `openssl pkey -in <generated-private-key.pem> -pubout` 171* If using AES-KW (`newt` only), the `kek` can be generated with a 172 command like (change count to 32 for a 256 bit key) 173 `dd if=/dev/urandom bs=1 count=16 | base64 > my_kek.b64` 174