1 /*
2  * SPDX-License-Identifier: Apache-2.0
3  *
4  * Copyright (c) 2016-2019 Linaro LTD
5  * Copyright (c) 2016-2019 JUUL Labs
6  * Copyright (c) 2019-2023 Arm Limited
7  *
8  * Original license:
9  *
10  * Licensed to the Apache Software Foundation (ASF) under one
11  * or more contributor license agreements.  See the NOTICE file
12  * distributed with this work for additional information
13  * regarding copyright ownership.  The ASF licenses this file
14  * to you under the Apache License, Version 2.0 (the
15  * "License"); you may not use this file except in compliance
16  * with the License.  You may obtain a copy of the License at
17  *
18  *  http://www.apache.org/licenses/LICENSE-2.0
19  *
20  * Unless required by applicable law or agreed to in writing,
21  * software distributed under the License is distributed on an
22  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
23  * KIND, either express or implied.  See the License for the
24  * specific language governing permissions and limitations
25  * under the License.
26  */
27 
28 #ifndef H_IMAGE_
29 #define H_IMAGE_
30 
31 #include <inttypes.h>
32 #include <stdbool.h>
33 #include "bootutil/fault_injection_hardening.h"
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 #if defined(__IAR_SYSTEMS_ICC__)
40     #define STRUCT_PACKED   __packed struct
41 #else
42     #define STRUCT_PACKED   struct __attribute__((__packed__))
43 #endif
44 
45 struct flash_area;
46 
47 #define IMAGE_MAGIC                 0x96f3b83d
48 #define IMAGE_MAGIC_V1              0x96f3b83c
49 #define IMAGE_MAGIC_NONE            0xffffffff
50 #define IMAGE_TLV_INFO_MAGIC        0x6907
51 #define IMAGE_TLV_PROT_INFO_MAGIC   0x6908
52 
53 #define IMAGE_HEADER_SIZE           32
54 #define IMAGE_HASH_LEN              32 /* Size of SHA256 TLV hash */
55 
56 /*
57  * Image header flags.
58  */
59 #define IMAGE_F_PIC                      0x00000001 /* Not supported. */
60 #define IMAGE_F_ENCRYPTED_AES128         0x00000004 /* Encrypted using AES128. */
61 #define IMAGE_F_ENCRYPTED_AES256         0x00000008 /* Encrypted using AES256. */
62 #define IMAGE_F_NON_BOOTABLE             0x00000010 /* Split image app. */
63 /*
64  * Indicates that this image should be loaded into RAM instead of run
65  * directly from flash.  The address to load should be in the
66  * ih_load_addr field of the header.
67  */
68 #define IMAGE_F_RAM_LOAD                 0x00000020
69 
70 /*
71  * Indicates that ih_load_addr stores information on flash/ROM address the
72  * image has been built for.
73  */
74 #define IMAGE_F_ROM_FIXED                0x00000100
75 
76 /*
77  * Flags that indicate if the image data is compressed
78  */
79 #define IMAGE_F_COMPRESSED_LZMA1         0x00000200
80 #define IMAGE_F_COMPRESSED_LZMA2         0x00000400
81 #define IMAGE_F_COMPRESSED_ARM_THUMB_FLT 0x00000800
82 
83 /*
84  * ECSDA224 is with NIST P-224
85  * ECSDA256 is with NIST P-256
86  */
87 
88 /*
89  * Image trailer TLV types.
90  *
91  * Signature is generated by computing signature over the image hash.
92  *
93  * Signature comes in the form of 2 TLVs.
94  *   1st on identifies the public key which should be used to verify it.
95  *   2nd one is the actual signature.
96  */
97 #define IMAGE_TLV_KEYHASH           0x01   /* hash of the public key */
98 #define IMAGE_TLV_PUBKEY            0x02   /* public key */
99 #define IMAGE_TLV_SHA256            0x10   /* SHA256 of image hdr and body */
100 #define IMAGE_TLV_SHA384            0x11   /* SHA384 of image hdr and body */
101 #define IMAGE_TLV_SHA512            0x12   /* SHA512 of image hdr and body */
102 #define IMAGE_TLV_RSA2048_PSS       0x20   /* RSA2048 of hash output */
103 #define IMAGE_TLV_ECDSA224          0x21   /* ECDSA of hash output - Not supported anymore */
104 #define IMAGE_TLV_ECDSA_SIG         0x22   /* ECDSA of hash output */
105 #define IMAGE_TLV_RSA3072_PSS       0x23   /* RSA3072 of hash output */
106 #define IMAGE_TLV_ED25519           0x24   /* ed25519 of hash output */
107 #define IMAGE_TLV_SIG_PURE          0x25   /* Indicator that attached signature has been prepared
108                                             * over image rather than its digest.
109                                             */
110 #define IMAGE_TLV_ENC_RSA2048       0x30   /* Key encrypted with RSA-OAEP-2048 */
111 #define IMAGE_TLV_ENC_KW            0x31   /* Key encrypted with AES-KW 128 or 256*/
112 #define IMAGE_TLV_ENC_EC256         0x32   /* Key encrypted with ECIES-EC256 */
113 #define IMAGE_TLV_ENC_X25519        0x33   /* Key encrypted with ECIES-X25519 */
114 #define IMAGE_TLV_DEPENDENCY        0x40   /* Image depends on other image */
115 #define IMAGE_TLV_SEC_CNT           0x50   /* security counter */
116 #define IMAGE_TLV_BOOT_RECORD       0x60   /* measured boot record */
117 /* The following flags relate to compressed images and are for the decompressed image data */
118 #define IMAGE_TLV_DECOMP_SIZE       0x70   /* Decompressed image size excluding header/TLVs */
119 #define IMAGE_TLV_DECOMP_SHA        0x71   /*
120                                             * Decompressed image shaX hash, this field must match
121                                             * the format and size of the raw slot (compressed)
122                                             * shaX hash
123                                             */
124 #define IMAGE_TLV_DECOMP_SIGNATURE  0x72   /*
125                                             * Decompressed image signature, this field must match
126                                             * the format and size of the raw slot (compressed)
127                                             * signature
128                                             */
129 #define IMAGE_TLV_COMP_DEC_SIZE     0x73   /* Compressed decrypted image size */
130 					   /*
131 					    * vendor reserved TLVs at xxA0-xxFF,
132 					    * where xx denotes the upper byte
133 					    * range.  Examples:
134 					    * 0x00a0 - 0x00ff
135 					    * 0x01a0 - 0x01ff
136 					    * 0x02a0 - 0x02ff
137 					    * ...
138 					    * 0xffa0 - 0xfffe
139 					    */
140 #define IMAGE_TLV_ANY               0xffff /* Used to iterate over all TLV */
141 
142 STRUCT_PACKED image_version {
143     uint8_t iv_major;
144     uint8_t iv_minor;
145     uint16_t iv_revision;
146     uint32_t iv_build_num;
147 };
148 
149 struct image_dependency {
150     uint8_t image_id;                       /* Image index (from 0) */
151     uint8_t _pad1;
152     uint16_t _pad2;
153     struct image_version image_min_version; /* Indicates at minimum which
154                                              * version of firmware must be
155                                              * available to satisfy compliance
156                                              */
157 };
158 
159 /** Image header.  All fields are in little endian byte order. */
160 STRUCT_PACKED image_header {
161     uint32_t ih_magic;
162     uint32_t ih_load_addr;
163     uint16_t ih_hdr_size;           /* Size of image header (bytes). */
164     uint16_t ih_protect_tlv_size;   /* Size of protected TLV area (bytes). */
165     uint32_t ih_img_size;           /* Does not include header. */
166     uint32_t ih_flags;              /* IMAGE_F_[...]. */
167     struct image_version ih_ver;
168     uint32_t _pad1;
169 };
170 
171 /** Image TLV header.  All fields in little endian. */
172 STRUCT_PACKED image_tlv_info {
173     uint16_t it_magic;
174     uint16_t it_tlv_tot;  /* size of TLV area (including tlv_info header) */
175 };
176 
177 /** Image trailer TLV format. All fields in little endian. */
178 STRUCT_PACKED image_tlv {
179     uint16_t it_type;   /* IMAGE_TLV_[...]. */
180     uint16_t it_len;    /* Data length (not including TLV header). */
181 };
182 
183 #define ENCRYPTIONFLAGS (IMAGE_F_ENCRYPTED_AES128 | IMAGE_F_ENCRYPTED_AES256)
184 #define IS_ENCRYPTED(hdr) (((hdr)->ih_flags & IMAGE_F_ENCRYPTED_AES128) \
185                         || ((hdr)->ih_flags & IMAGE_F_ENCRYPTED_AES256))
186 #define MUST_DECRYPT(fap, idx, hdr) \
187     (flash_area_get_id(fap) == FLASH_AREA_IMAGE_SECONDARY(idx) && IS_ENCRYPTED(hdr))
188 
189 #define COMPRESSIONFLAGS (IMAGE_F_COMPRESSED_LZMA1 | IMAGE_F_COMPRESSED_LZMA2 \
190                           | IMAGE_F_COMPRESSED_ARM_THUMB_FLT)
191 #define IS_COMPRESSED(hdr) ((hdr)->ih_flags & COMPRESSIONFLAGS)
192 #define MUST_DECOMPRESS(fap, idx, hdr) \
193     (flash_area_get_id(fap) == FLASH_AREA_IMAGE_SECONDARY(idx) && IS_COMPRESSED(hdr))
194 
195 _Static_assert(sizeof(struct image_header) == IMAGE_HEADER_SIZE,
196                "struct image_header not required size");
197 
198 struct enc_key_data;
199 struct boot_loader_state;
200 fih_ret bootutil_img_validate(struct boot_loader_state *state,
201                               struct image_header *hdr,
202                               const struct flash_area *fap,
203                               uint8_t *tmp_buf, uint32_t tmp_buf_sz,
204                               uint8_t *seed, int seed_len, uint8_t *out_hash
205 #if defined(MCUBOOT_SWAP_USING_OFFSET) && defined(MCUBOOT_SERIAL_RECOVERY)
206                               , uint32_t start_off
207 #endif
208 );
209 
210 struct image_tlv_iter {
211     const struct image_header *hdr;
212     const struct flash_area *fap;
213     uint16_t type;
214     bool prot;
215     uint32_t prot_end;
216     uint32_t tlv_off;
217     uint32_t tlv_end;
218 #if defined(MCUBOOT_SWAP_USING_OFFSET)
219     uint32_t start_off;
220 #endif
221 };
222 
223 int bootutil_tlv_iter_begin(struct image_tlv_iter *it,
224                             const struct image_header *hdr,
225                             const struct flash_area *fap, uint16_t type,
226                             bool prot);
227 int bootutil_tlv_iter_next(struct image_tlv_iter *it, uint32_t *off,
228                            uint16_t *len, uint16_t *type);
229 int bootutil_tlv_iter_is_prot(struct image_tlv_iter *it, uint32_t off);
230 
231 int32_t bootutil_get_img_security_cnt(struct boot_loader_state *state, int slot,
232                                       const struct flash_area *fap,
233                                       uint32_t *img_security_cnt);
234 
235 #ifdef __cplusplus
236 }
237 #endif
238 
239 #endif
240