-
Notifications
You must be signed in to change notification settings - Fork 1
/
tim.h
310 lines (278 loc) · 6.11 KB
/
tim.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
/* SPDX-License-Identifier: Beerware */
/*
* 2018 by Marek Behun <marek.behun@nic.cz>
*/
#ifndef _TIM_H_
#define _TIM_H_
#include <stdio.h>
#include <stdlib.h>
#include <openssl/ec.h>
#include "utils.h"
#include "images.h"
#define TIMH_ID name2id("TIMH")
#define TIMN_ID name2id("TIMN")
#define WTMI_ID name2id("WTMI")
#define OBMI_ID name2id("OBMI")
#define BOOTFS_SPINOR 0x5350490a
#define BOOTFS_SPINAND 0x5350491a
#define BOOTFS_EMMC 0x454d4d08
#define BOOTFS_EMMCALT 0x454d4d0b
#define BOOTFS_SATA 0x53415432
#define BOOTFS_UART 0x55415223
typedef struct {
u32 version;
u32 identifier;
u32 trusted;
u32 issuedate;
u32 oemuid;
u32 reserved[5];
u32 bootflashsign;
u32 numimages;
u32 numkeys;
u32 sizeofreserved;
} timhdr_t;
#define HASH_SHA160 20
#define HASH_SHA256 32
#define HASH_SHA512 64
#define ENC_AESCTS_ECB128 0x0001e000
#define ENC_AESCTS_ECB256 0x0001e001
#define ENC_AESCTS_ECB192 0x0001e002
#define ENC_AESCTS_CBC128 0x0001e004
#define ENC_AESCTS_CBC256 0x0001e005
#define ENC_AESCTS_CBC192 0x0001e006
typedef struct {
u32 id;
u32 nextid;
u32 flashentryaddr;
u32 loadaddr;
u32 size;
u32 sizetohash;
u32 hashalg;
u32 hash[16];
u32 partitionnumber;
u32 encalg;
u32 encryptoffset;
u32 encryptsize;
} imginfo_t;
typedef struct {
u32 id;
u32 hashalg;
u32 size;
u32 publickeysize;
u32 encryptalg;
union {
u32 data[128];
struct {
u32 RSAexp[64];
u32 RSAmod[64];
};
struct {
u32 ECDSAcompx[17];
u32 ECDSAcompy[17];
};
};
u32 hash[16];
} keyinfo_t;
#define RES_ID name2id("OPTH")
typedef struct {
u32 id;
u32 pkgs;
} reshdr_t;
#define PKG_CIDP name2id("CIDP")
#define PKG_IMAP name2id("IMAP")
#define PKG_PINP name2id("PINP")
#define PKG_Term name2id("Term")
#define SIZEOF_RESPKG_HDR 8
typedef struct {
u32 id;
u32 size;
union {
u32 data[0];
struct {
u32 nmaps;
struct imap_map {
u32 id;
u32 type;
u32 flashentryaddr[2];
u32 partitionnumber;
} maps[0];
} imap;
struct {
u32 nconsumers;
struct cidp_t {
u32 id;
u32 npkgs;
u32 pkgs[0];
} consumers[0];
} cidp;
struct {
u32 nops;
u32 ninst;
struct gpp_op {
u32 id;
u32 value;
} ops[0];
u32 instructions[0];
} gpp;
};
} respkg_t;
#define DSALG_PKCS1_V1_5 3
#define DSALG_ECDSA_256 5
#define DSALG_ECDSA_521 6
#define DSALG_PKCS1_V2_2 7
#define SIG_SCHEME_ECDSA_P521_SHA256 0x0000b311
#define SIG_SCHEME_ECDSA_P521_SHA512 0x0000b341
typedef struct {
u32 dsalg;
u32 hashalg;
u32 keysize;
u32 hash[8];
union {
u32 data[192];
struct {
struct {
u32 exp[64];
u32 mod[64];
} pub;
u32 sig[64];
} RSA;
struct {
struct {
u32 x[17];
u32 y[17];
} pub;
struct {
u32 r[17];
u32 s[17];
} sig;
} ECDSA;
};
} platds_t;
static inline const char *hash2name(u32 hash)
{
switch (hash) {
case HASH_SHA160:
return "sha-160";
case HASH_SHA256:
return "sha-256";
case HASH_SHA512:
return "sha-512";
case 0:
return "none";
default:
return "unknown";
}
}
static inline const char *enc2name(u32 enc)
{
switch (enc) {
case ENC_AESCTS_ECB128:
return "aes-tb-cts-ecb128";
case ENC_AESCTS_ECB256:
return "aes-tb-cts-ecb128";
case ENC_AESCTS_ECB192:
return "aes-tb-cts-ecb128";
case ENC_AESCTS_CBC128:
return "aes-tb-cts-cbc128";
case ENC_AESCTS_CBC256:
return "aes-tb-cts-cbc256";
case ENC_AESCTS_CBC192:
return "aes-tb-cts-cbc192";
case 0:
return "none";
default:
return "unknown";
}
}
static inline const char *dsalg2name(u32 dsalg)
{
switch (dsalg) {
case DSALG_PKCS1_V1_5:
return "PKCS1 v1.5";
case DSALG_ECDSA_256:
return "ECDSA 256";
case DSALG_ECDSA_521:
return "ECDSA 521";
case DSALG_PKCS1_V2_2:
return "PKCS1 v2.2";
default:
return "unknown";
}
}
static inline const char *bootfs2name(u32 bootfs)
{
switch (bootfs) {
case BOOTFS_SPINOR:
return "SPI NOR";
case BOOTFS_SPINAND:
return "SPI NAND";
case BOOTFS_EMMC:
return "eMMC";
case BOOTFS_EMMCALT:
return "eMMC alternative";
case BOOTFS_SATA:
return "SATA";
case BOOTFS_UART:
return "UART";
default:
return "unknown";
}
}
static inline int tim_nimages(const timhdr_t *timhdr)
{
return le32toh(timhdr->numimages);
}
static inline imginfo_t *tim_image(timhdr_t *timhdr, int i)
{
if (i < 0 || i >= tim_nimages(timhdr))
return NULL;
return ((imginfo_t *) (timhdr + 1)) + i;
}
static inline int tim_nkeys(const timhdr_t *timhdr)
{
return le32toh(timhdr->numkeys);
}
static inline keyinfo_t *tim_key(timhdr_t *timhdr, int i)
{
imginfo_t *lastimg;
if (i < 0 || i >= tim_nkeys(timhdr))
return NULL;
lastimg = tim_image(timhdr, tim_nimages(timhdr) - 1);
return ((keyinfo_t *) (lastimg + 1)) + i;
}
static inline size_t tim_size(timhdr_t *timhdr)
{
size_t res;
res = sizeof(timhdr_t);
res += tim_nimages(timhdr) * sizeof(imginfo_t);
res += le32toh(timhdr->numkeys) * sizeof(keyinfo_t);
res += le32toh(timhdr->sizeofreserved);
if (timhdr->trusted)
res += sizeof(platds_t);
return res;
}
static inline int tim_is_trusted(const image_t *tim)
{
const timhdr_t *timhdr = (void *)tim->data;
return !!timhdr->trusted;
}
extern void tim_image_set_loadaddr(image_t *tim, u32 id, u32 loadaddr);
extern void tim_image_set_flashaddr(image_t *tim, u32 id, u32 flashaddr, u32 partition);
extern u32 tim_imap_pkg_addr(image_t *tim, u32 id);
extern void tim_imap_pkg_addr_set(image_t *tim, u32 id, u32 flashentry,
u32 partition);
extern void tim_parse(image_t *tim, int disasm, int *supports_baudrate_change, FILE *fp);
extern void tim_enable_hash(image_t *tim, u32 id, int enable);
extern void tim_rehash(image_t *tim);
extern void tim_inject_baudrate_change_support(image_t *tim);
extern void tim_get_otp_hash(image_t *tim, u32 *hash);
extern void tim_sign(image_t *tim, EC_KEY *key);
extern void tim_set_boot(image_t *tim, u32 boot);
extern void tim_set_id(image_t *tim, u32 new_id);
extern void tim_remove_image(image_t *tim, u32 id);
extern void tim_add_image(image_t *tim, image_t *image, u32 after, u32 loadaddr,
u32 flashaddr, u32 partition, int hash);
extern void tim_add_key(image_t *tim, u32 id, EC_KEY *key);
extern void tim_minimal_image(image_t *tim, int trusted, u32 id,
int support_fastmode);
#endif /* _TIM_H_ */