blob: 9ce33e65548522b227d29a49e64d4614d6ec198a [file] [log] [blame]
Bill Richardson58672c12017-10-20 23:44:17 -07001/* 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 Richardsonb1c6e702018-01-17 20:24:52 -080010#define MAGIC_DEFAULT (-1u)
11#define MAGIC_VALID (-2u)
Bill Richardson58672c12017-10-20 23:44:17 -070012
13#ifdef __cplusplus
14#include <endian.h>
15#include <stdio.h>
16#include <time.h>
17#endif
18
19#include <assert.h>
nagendra modadugucd3871d2018-01-04 16:46:21 -080020#include <inttypes.h>
Bill Richardson58672c12017-10-20 23:44:17 -070021#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
44typedef 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 Scull38904932018-05-23 10:35:49 +000095 printf("hdr.timestamp : %016" PRIu64 "x, %s", timestamp_,
Bill Richardson58672c12017-10-20 23:44:17 -070096 asctime(localtime(reinterpret_cast<const time_t*>(&timestamp_))));
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 Richardson58672c12017-10-20 23:44:17 -0700118 }
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
161static_assert(sizeof(SignedHeader) == 1024,
162 "SignedHeader should be 1024 bytes");
163#ifndef GOOGLE3
164static_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