Bill Richardson | 58672c1 | 2017-10-20 23:44:17 -0700 | [diff] [blame] | 1 | /* Copyright 2017 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 | /* This is citadel */ |
| 9 | #define CHIP_C |
Bill Richardson | b1c6e70 | 2018-01-17 20:24:52 -0800 | [diff] [blame] | 10 | #define MAGIC_DEFAULT (-1u) |
| 11 | #define MAGIC_VALID (-2u) |
Bill Richardson | 58672c1 | 2017-10-20 23:44:17 -0700 | [diff] [blame] | 12 | |
| 13 | #ifdef __cplusplus |
| 14 | #include <endian.h> |
| 15 | #include <stdio.h> |
| 16 | #include <time.h> |
| 17 | #endif |
| 18 | |
| 19 | #include <assert.h> |
nagendra modadugu | cd3871d | 2018-01-04 16:46:21 -0800 | [diff] [blame] | 20 | #include <inttypes.h> |
Bill Richardson | 58672c1 | 2017-10-20 23:44:17 -0700 | [diff] [blame] | 21 | #include <stdint.h> |
| 22 | #include <string.h> |
| 23 | |
| 24 | #define FUSE_MAX 128 |
| 25 | #define INFO_MAX 128 |
| 26 | #define FUSE_PADDING 0x55555555 |
| 27 | |
| 28 | // B chips |
| 29 | #define FUSE_IGNORE_B 0xa3badaac // baked in rom! |
| 30 | #define INFO_IGNORE_B 0xaa3c55c3 // baked in rom! |
| 31 | |
| 32 | // Citadel chips |
| 33 | #define FUSE_IGNORE_C 0x3aabadac // baked in rom! |
| 34 | #define INFO_IGNORE_C 0xa5c35a3c // baked in rom! |
| 35 | |
| 36 | #if defined(CHIP_C) |
| 37 | #define FUSE_IGNORE FUSE_IGNORE_C |
| 38 | #define INFO_IGNORE INFO_IGNORE_C |
| 39 | #else |
| 40 | #define FUSE_IGNORE FUSE_IGNORE_B |
| 41 | #define INFO_IGNORE INFO_IGNORE_B |
| 42 | #endif |
| 43 | |
| 44 | typedef struct SignedHeader { |
| 45 | #ifdef __cplusplus |
| 46 | SignedHeader() |
| 47 | : magic(-1), |
| 48 | image_size(0), |
| 49 | epoch_(0x1337), |
| 50 | major_(0), |
| 51 | minor_(0xbabe), |
| 52 | p4cl_(0), |
| 53 | applysec_(0), |
| 54 | config1_(0), |
| 55 | err_response_(0), |
| 56 | expect_response_(0), |
| 57 | dev_id0_(0), |
| 58 | dev_id1_(0) { |
| 59 | memset(signature, 'S', sizeof(signature)); |
| 60 | memset(tag, 'T', sizeof(tag)); |
| 61 | memset(fusemap, 0, sizeof(fusemap)); |
| 62 | memset(infomap, 0, sizeof(infomap)); |
| 63 | memset(&_pad, '3', sizeof(_pad)); |
| 64 | } |
| 65 | |
| 66 | void markFuse(uint32_t n) { |
| 67 | assert(n < FUSE_MAX); |
| 68 | fusemap[n / 32] |= 1 << (n & 31); |
| 69 | } |
| 70 | |
| 71 | void markInfo(uint32_t n) { |
| 72 | assert(n < INFO_MAX); |
| 73 | infomap[n / 32] |= 1 << (n & 31); |
| 74 | } |
| 75 | |
| 76 | static uint32_t fuseIgnore(bool c) { |
| 77 | return c ? FUSE_IGNORE_C : FUSE_IGNORE_B; |
| 78 | } |
| 79 | |
| 80 | static uint32_t infoIgnore(bool c) { |
| 81 | return c ? INFO_IGNORE_C : INFO_IGNORE_B; |
| 82 | } |
| 83 | |
| 84 | void print() const { |
| 85 | printf("hdr.keyid : %08x\n", keyid); |
| 86 | printf("hdr.tag : "); |
| 87 | const uint8_t* p = reinterpret_cast<const uint8_t*>(&tag); |
| 88 | for (size_t i = 0; i < sizeof(tag); ++i) { |
| 89 | printf("%02x", p[i] & 255); |
| 90 | } |
| 91 | printf("\n"); |
| 92 | printf("hdr.epoch : %08x\n", epoch_); |
| 93 | printf("hdr.major : %08x\n", major_); |
| 94 | printf("hdr.minor : %08x\n", minor_); |
Andrew Scull | 3890493 | 2018-05-23 10:35:49 +0000 | [diff] [blame] | 95 | printf("hdr.timestamp : %016" PRIu64 "x, %s", timestamp_, |
Bill Richardson | 58672c1 | 2017-10-20 23:44:17 -0700 | [diff] [blame] | 96 | asctime(localtime(reinterpret_cast<const time_t*>(×tamp_)))); |
| 97 | printf("hdr.img_chk : %08x\n", be32toh(img_chk_)); |
| 98 | printf("hdr.fuses_chk : %08x\n", be32toh(fuses_chk_)); |
| 99 | printf("hdr.info_chk : %08x\n", be32toh(info_chk_)); |
| 100 | printf("hdr.applysec : %08x\n", applysec_); |
| 101 | printf("hdr.config1 : %08x\n", config1_); |
| 102 | printf("hdr.err_response : %08x\n", err_response_); |
| 103 | printf("hdr.expect_response: %08x\n", expect_response_); |
| 104 | |
| 105 | if (dev_id0_) printf("hdr.dev_id0 : %08x\n", dev_id0_); |
| 106 | if (dev_id1_) printf("hdr.dev_id1 : %08x\n", dev_id1_); |
| 107 | |
| 108 | printf("hdr.fusemap : "); |
| 109 | for (size_t i = 0; i < sizeof(fusemap) / sizeof(fusemap[0]); ++i) { |
| 110 | printf("%08X", fusemap[i]); |
| 111 | } |
| 112 | printf("\n"); |
| 113 | printf("hdr.infomap : "); |
| 114 | for (size_t i = 0; i < sizeof(infomap) / sizeof(infomap[0]); ++i) { |
| 115 | printf("%08X", infomap[i]); |
| 116 | } |
| 117 | printf("\n"); |
Bill Richardson | 58672c1 | 2017-10-20 23:44:17 -0700 | [diff] [blame] | 118 | } |
| 119 | #endif // __cplusplus |
| 120 | |
| 121 | uint32_t magic; // -1 (thanks, boot_sys!) |
| 122 | uint32_t signature[96]; |
| 123 | uint32_t img_chk_; // top 32 bit of expected img_hash |
| 124 | // --------------------- everything below is part of img_hash |
| 125 | uint32_t tag[7]; // words 0-6 of RWR/FWR |
| 126 | uint32_t keyid; // word 7 of RWR |
| 127 | uint32_t key[96]; // public key to verify signature with |
| 128 | uint32_t image_size; |
| 129 | uint32_t ro_base; // readonly region |
| 130 | uint32_t ro_max; |
| 131 | uint32_t rx_base; // executable region |
| 132 | uint32_t rx_max; |
| 133 | uint32_t fusemap[FUSE_MAX / (8 * sizeof(uint32_t))]; |
| 134 | uint32_t infomap[INFO_MAX / (8 * sizeof(uint32_t))]; |
| 135 | uint32_t epoch_; // word 7 of FWR |
| 136 | uint32_t major_; // keyladder count |
| 137 | uint32_t minor_; |
| 138 | uint64_t timestamp_; // time of signing |
| 139 | uint32_t p4cl_; |
| 140 | uint32_t applysec_; // bits to and with FUSE_FW_DEFINED_BROM_APPLYSEC |
| 141 | uint32_t config1_; // bits to mesh with FUSE_FW_DEFINED_BROM_CONFIG1 |
| 142 | uint32_t err_response_; // bits to or with FUSE_FW_DEFINED_BROM_ERR_RESPONSE |
| 143 | uint32_t expect_response_; // action to take when expectation is violated |
| 144 | union { |
| 145 | uint32_t |
| 146 | _pad[256 - 1 - 96 - 1 - 7 - 1 - 96 - 5 * 1 - 4 - 4 - 9 * 1 - 2 - 1 - 2]; |
| 147 | struct { |
| 148 | // 2nd FIPS signature (gnubby RW) |
| 149 | uint32_t keyid; |
| 150 | uint32_t r[8]; |
| 151 | uint32_t s[8]; |
| 152 | } ext_sig; |
| 153 | } _pad; |
| 154 | uint32_t dev_id0_; // node id, if locked |
| 155 | uint32_t dev_id1_; |
| 156 | uint32_t fuses_chk_; // top 32 bit of expected fuses hash |
| 157 | uint32_t info_chk_; // top 32 bit of expected info hash |
| 158 | } SignedHeader; |
| 159 | |
| 160 | #ifdef __cplusplus |
| 161 | static_assert(sizeof(SignedHeader) == 1024, |
| 162 | "SignedHeader should be 1024 bytes"); |
| 163 | #ifndef GOOGLE3 |
| 164 | static_assert(offsetof(SignedHeader, info_chk_) == 1020, |
| 165 | "SignedHeader should be 1024 bytes"); |
| 166 | #endif // GOOGLE3 |
| 167 | #endif // __cplusplus |
| 168 | |
| 169 | #endif // __EC_UTIL_SIGNER_COMMON_SIGNED_HEADER_H |