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*>(×tamp_)))); 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