• 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 // Dauntless 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_DAUNTLESS (-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_DAUNTLESS:
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_DAUNTLESS:
125         printf("Dauntless");
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_size       : %08x\n", image_size);
146     printf("hdr.img_chk        : %08x\n", be32toh(img_chk_));
147     printf("hdr.fuses_chk      : %08x\n", be32toh(fuses_chk_));
148     printf("hdr.info_chk       : %08x\n", be32toh(info_chk_));
149     printf("hdr.applysec       : %08x\n", applysec_);
150     printf("hdr.config1        : %08x\n", config1_);
151     printf("hdr.err_response   : %08x\n", err_response_);
152     printf("hdr.expect_response: %08x\n", expect_response_);
153 
154     if (dev_id0_)
155       printf("hdr.dev_id0        : %08x (%d)\n", dev_id0_, dev_id0_);
156     if (dev_id1_)
157       printf("hdr.dev_id1        : %08x (%d)\n", dev_id1_, dev_id1_);
158 
159     printf("hdr.fusemap        : ");
160     for (size_t i = 0; i < sizeof(fusemap) / sizeof(fusemap[0]); ++i) {
161       printf("%08X", fusemap[i]);
162     }
163     printf("\n");
164     printf("hdr.infomap        : ");
165     for (size_t i = 0; i < sizeof(infomap) / sizeof(infomap[0]); ++i) {
166       printf("%08X", infomap[i]);
167     }
168     printf("\n");
169 
170     printf("hdr.board_id       : %08x %08x %08x\n",
171            SIGNED_HEADER_PADDING ^ board_id_.type,
172            SIGNED_HEADER_PADDING ^ board_id_.type_mask,
173            SIGNED_HEADER_PADDING ^ board_id_.flags);
174   }
175 #endif  // __cplusplus
176 
177   uint32_t magic;  // -1 (thanks, boot_sys!)
178   uint32_t signature[96];
179   uint32_t img_chk_;  // top 32 bit of expected img_hash
180   // --------------------- everything below is part of img_hash
181   uint32_t tag[7];   // words 0-6 of RWR/FWR
182   uint32_t keyid;    // word 7 of RWR
183   uint32_t key[96];  // public key to verify signature with
184   uint32_t image_size;
185   uint32_t ro_base;  // readonly region
186   uint32_t ro_max;
187   uint32_t rx_base;  // executable region
188   uint32_t rx_max;
189   uint32_t fusemap[FUSE_MAX / (8 * sizeof(uint32_t))];
190   uint32_t infomap[INFO_MAX / (8 * sizeof(uint32_t))];
191   uint32_t epoch_;  // word 7 of FWR
192   uint32_t major_;  // keyladder count
193   uint32_t minor_;
194   uint64_t timestamp_;  // time of signing
195   uint32_t p4cl_;
196   uint32_t applysec_;      // bits to and with FUSE_FW_DEFINED_BROM_APPLYSEC
197   uint32_t config1_;       // bits to mesh with FUSE_FW_DEFINED_BROM_CONFIG1
198   uint32_t err_response_;  // bits to or with FUSE_FW_DEFINED_BROM_ERR_RESPONSE
199   uint32_t expect_response_;  // action to take when expectation is violated
200 
201   union {
202     // 2nd FIPS signature (cr51/cr52 RW)
203     struct {
204       uint32_t keyid;
205       uint32_t r[8];
206       uint32_t s[8];
207     } ext_sig;
208   } u;
209 
210   // Spare space
211   uint32_t _pad[5];
212 
213   struct {
214     unsigned size : 12;
215     unsigned offset : 20;
216   } swap_mark;
217   uint32_t rw_product_family_;  // 0 == PRODUCT_FAMILY_ANY
218                                 // Stored as (^SIGNED_HEADER_PADDING)
219                                 // TODO(ntaha): add reference to product family
220                                 // enum when available.
221 
222   struct {
223     // CR50 board class locking
224     uint32_t type;       // Board type
225     uint32_t type_mask;  // Mask of board type bits to use.
226     uint32_t flags;      // Flags
227   } board_id_;
228 
229   uint32_t dev_id0_;  // node id, if locked
230   uint32_t dev_id1_;
231   uint32_t fuses_chk_;  // top 32 bit of expected fuses hash
232   uint32_t info_chk_;   // top 32 bit of expected info hash
233 } SignedHeader;
234 
235 #ifdef __cplusplus
236 static_assert(sizeof(SignedHeader) == 1024,
237               "SignedHeader should be 1024 bytes");
238 #ifndef GOOGLE3
239 static_assert(offsetof(SignedHeader, info_chk_) == 1020,
240               "SignedHeader should be 1024 bytes");
241 #endif  // GOOGLE3
242 #else
243 _Static_assert(sizeof(SignedHeader) == 1024,
244               "SignedHeader should be 1024 bytes");
245 #endif  // __cplusplus
246 
247 #endif  // __EC_UTIL_SIGNER_COMMON_SIGNED_HEADER_H
248