• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2015 The Chromium OS Authors. All rights reserved.
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  */
5 #ifndef __EC_UTIL_SIGNER_COMMON_SIGNED_HEADER_H
6 #define __EC_UTIL_SIGNER_COMMON_SIGNED_HEADER_H
7 
8 #ifdef __cplusplus
9 #include <endian.h>
10 #include <stdio.h>
11 #include <time.h>
12 #endif
13 
14 #include <assert.h>
15 #include <inttypes.h>
16 #include <string.h>
17 
18 #define FUSE_MAX 128
19 #define INFO_MAX 128
20 #define FUSE_PADDING 0x55555555
21 
22 // B chips
23 #define FUSE_IGNORE_B 0xa3badaac  // baked in rom!
24 #define INFO_IGNORE_B 0xaa3c55c3  // baked in rom!
25 
26 // Citadel chips
27 #define FUSE_IGNORE_C 0x3aabadac  // baked in rom!
28 #define INFO_IGNORE_C 0xa5c35a3c  // baked in rom!
29 
30 // D2 chips
31 #define FUSE_IGNORE_D 0xdaa3baca  // baked in rom!
32 #define INFO_IGNORE_D 0x5a3ca5c3  // baked in rom!
33 
34 #if defined(CHIP_D)
35 #define FUSE_IGNORE FUSE_IGNORE_D
36 #define INFO_IGNORE INFO_IGNORE_D
37 #elif defined(CHIP_C)
38 #define FUSE_IGNORE FUSE_IGNORE_C
39 #define INFO_IGNORE INFO_IGNORE_C
40 #else
41 #define FUSE_IGNORE FUSE_IGNORE_B
42 #define INFO_IGNORE INFO_IGNORE_B
43 #endif
44 
45 #define SIGNED_HEADER_MAGIC_HAVEN (-1u)
46 #define SIGNED_HEADER_MAGIC_CITADEL (-2u)
47 #define SIGNED_HEADER_MAGIC_D2 (-3u)
48 
49 /* Default value for _pad[] words */
50 #define SIGNED_HEADER_PADDING 0x33333333
51 
52 typedef struct SignedHeader {
53 #ifdef __cplusplus
SignedHeaderSignedHeader54   SignedHeader()
55       : magic(SIGNED_HEADER_MAGIC_HAVEN),
56         image_size(0),
57         epoch_(0x1337),
58         major_(0),
59         minor_(0xbabe),
60         p4cl_(0),
61         applysec_(0),
62         config1_(0),
63         err_response_(0),
64         expect_response_(0),
65         swap_mark({0, 0}),
66         dev_id0_(0),
67         dev_id1_(0) {
68     memset(signature, 'S', sizeof(signature));
69     memset(tag, 'T', sizeof(tag));
70     memset(fusemap, 0, sizeof(fusemap));
71     memset(infomap, 0, sizeof(infomap));
72     memset(&_pad, SIGNED_HEADER_PADDING, sizeof(_pad));
73     // Below all evolved out of _pad, thus must also be initialized to '3'
74     // for backward compatibility.
75     memset(&rw_product_family_, SIGNED_HEADER_PADDING,
76            sizeof(rw_product_family_));
77     memset(&u, SIGNED_HEADER_PADDING, sizeof(u));
78     memset(&board_id_, SIGNED_HEADER_PADDING, sizeof(board_id_));
79   }
80 
markFuseSignedHeader81   void markFuse(uint32_t n) {
82     assert(n < FUSE_MAX);
83     fusemap[n / 32] |= 1 << (n & 31);
84   }
85 
markInfoSignedHeader86   void markInfo(uint32_t n) {
87     assert(n < INFO_MAX);
88     infomap[n / 32] |= 1 << (n & 31);
89   }
90 
fuseIgnoreSignedHeader91   static uint32_t fuseIgnore(bool c, bool d) {
92     return d ? FUSE_IGNORE_D : c ? FUSE_IGNORE_C : FUSE_IGNORE_B;
93   }
94 
infoIgnoreSignedHeader95   static uint32_t infoIgnore(bool c, bool d) {
96     return d ? INFO_IGNORE_D : c ? INFO_IGNORE_C : INFO_IGNORE_B;
97   }
98 
plausibleSignedHeader99   bool plausible() const {
100     switch (magic) {
101       case SIGNED_HEADER_MAGIC_HAVEN:
102       case SIGNED_HEADER_MAGIC_CITADEL:
103       case SIGNED_HEADER_MAGIC_D2:
104         break;
105       default:
106         return false;
107     }
108     if (keyid == -1u) return false;
109     if (ro_base >= ro_max) return false;
110     if (rx_base >= rx_max) return false;
111     if (_pad[0] != SIGNED_HEADER_PADDING) return false;
112     return true;
113   }
114 
printSignedHeader115   void print() const {
116     printf("hdr.magic          : %08x (", magic);
117     switch (magic) {
118       case SIGNED_HEADER_MAGIC_HAVEN:
119         printf("Haven B");
120         break;
121       case SIGNED_HEADER_MAGIC_CITADEL:
122         printf("Citadel");
123         break;
124       case SIGNED_HEADER_MAGIC_D2:
125         printf("D2");
126         break;
127       default:
128         printf("?");
129         break;
130     }
131     printf(")\n");
132     printf("hdr.ro_base        : %08x\n", ro_base);
133     printf("hdr.keyid          : %08x\n", keyid);
134     printf("hdr.tag            : ");
135     const uint8_t* p = reinterpret_cast<const uint8_t*>(&tag);
136     for (size_t i = 0; i < sizeof(tag); ++i) {
137       printf("%02x", p[i] & 255);
138     }
139     printf("\n");
140     printf("hdr.epoch          : %08x\n", epoch_);
141     printf("hdr.major          : %08x\n", major_);
142     printf("hdr.minor          : %08x\n", minor_);
143     printf("hdr.timestamp      : %016" PRIx64 ", %s", timestamp_,
144            asctime(localtime(reinterpret_cast<const time_t*>(&timestamp_))));
145     printf("hdr.img_chk        : %08x\n", be32toh(img_chk_));
146     printf("hdr.fuses_chk      : %08x\n", be32toh(fuses_chk_));
147     printf("hdr.info_chk       : %08x\n", be32toh(info_chk_));
148     printf("hdr.applysec       : %08x\n", applysec_);
149     printf("hdr.config1        : %08x\n", config1_);
150     printf("hdr.err_response   : %08x\n", err_response_);
151     printf("hdr.expect_response: %08x\n", expect_response_);
152 
153     if (dev_id0_) printf("hdr.dev_id0        : %08x (%d)\n", dev_id0_, dev_id0_);
154     if (dev_id1_) printf("hdr.dev_id1        : %08x (%d)\n", dev_id1_, dev_id1_);
155 
156     printf("hdr.fusemap        : ");
157     for (size_t i = 0; i < sizeof(fusemap) / sizeof(fusemap[0]); ++i) {
158       printf("%08X", fusemap[i]);
159     }
160     printf("\n");
161     printf("hdr.infomap        : ");
162     for (size_t i = 0; i < sizeof(infomap) / sizeof(infomap[0]); ++i) {
163       printf("%08X", infomap[i]);
164     }
165     printf("\n");
166   }
167 #endif  // __cplusplus
168 
169   uint32_t magic;  // -1 (thanks, boot_sys!)
170   uint32_t signature[96];
171   uint32_t img_chk_;  // top 32 bit of expected img_hash
172   // --------------------- everything below is part of img_hash
173   uint32_t tag[7];   // words 0-6 of RWR/FWR
174   uint32_t keyid;    // word 7 of RWR
175   uint32_t key[96];  // public key to verify signature with
176   uint32_t image_size;
177   uint32_t ro_base;  // readonly region
178   uint32_t ro_max;
179   uint32_t rx_base;  // executable region
180   uint32_t rx_max;
181   uint32_t fusemap[FUSE_MAX / (8 * sizeof(uint32_t))];
182   uint32_t infomap[INFO_MAX / (8 * sizeof(uint32_t))];
183   uint32_t epoch_;  // word 7 of FWR
184   uint32_t major_;  // keyladder count
185   uint32_t minor_;
186   uint64_t timestamp_;  // time of signing
187   uint32_t p4cl_;
188   uint32_t applysec_;      // bits to and with FUSE_FW_DEFINED_BROM_APPLYSEC
189   uint32_t config1_;       // bits to mesh with FUSE_FW_DEFINED_BROM_CONFIG1
190   uint32_t err_response_;  // bits to or with FUSE_FW_DEFINED_BROM_ERR_RESPONSE
191   uint32_t expect_response_;  // action to take when expectation is violated
192 
193   union {
194     // 2nd FIPS signature (gnubby RW)
195     struct {
196       uint32_t keyid;
197       uint32_t r[8];
198       uint32_t s[8];
199     } ext_sig;
200 
201     // FLASH trim override (D2 RO)
202     // iff config1_ & 65536
203     struct {
204       uint32_t FSH_SMW_SETTING_OPTION3;
205       uint32_t FSH_SMW_SETTING_OPTION2;
206       uint32_t FSH_SMW_SETTING_OPTIONA;
207       uint32_t FSH_SMW_SETTING_OPTIONB;
208       uint32_t FSH_SMW_SMP_WHV_OPTION1;
209       uint32_t FSH_SMW_SMP_WHV_OPTION0;
210       uint32_t FSH_SMW_SME_WHV_OPTION1;
211       uint32_t FSH_SMW_SME_WHV_OPTION0;
212     } fsh;
213   } u;
214 
215   // Spare space
216   uint32_t _pad[5];
217 
218   struct {
219     unsigned size : 12;
220     unsigned offset : 20;
221   } swap_mark;
222   uint32_t rw_product_family_;  // 0 == PRODUCT_FAMILY_ANY
223                                 // Stored as (^SIGNED_HEADER_PADDING)
224                                 // TODO(ntaha): add reference to product family
225                                 // enum when available.
226 
227   struct {
228     // CR50 board class locking
229     uint32_t type;       // Board type
230     uint32_t type_mask;  // Mask of board type bits to use.
231     uint32_t flags;      // Flags
232   } board_id_;
233 
234   uint32_t dev_id0_;  // node id, if locked
235   uint32_t dev_id1_;
236   uint32_t fuses_chk_;  // top 32 bit of expected fuses hash
237   uint32_t info_chk_;   // top 32 bit of expected info hash
238 } SignedHeader;
239 
240 #ifdef __cplusplus
241 static_assert(sizeof(SignedHeader) == 1024,
242               "SignedHeader should be 1024 bytes");
243 #ifndef GOOGLE3
244 static_assert(offsetof(SignedHeader, info_chk_) == 1020,
245               "SignedHeader should be 1024 bytes");
246 #endif  // GOOGLE3
247 #endif  // __cplusplus
248 
249 #endif  // __EC_UTIL_SIGNER_COMMON_SIGNED_HEADER_H
250