1 /*
2 * Copyright 2015 The ChromiumOS Authors
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7 #include <asm/byteorder.h>
8 #include <ctype.h>
9 #include <endian.h>
10 #include <errno.h>
11 #include <fcntl.h>
12 #include <getopt.h>
13 #include <libusb.h>
14 #include <openssl/evp.h>
15 #include <openssl/sha.h>
16 #include <stdarg.h>
17 #include <stdbool.h>
18 #include <stdint.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <termios.h>
25 #include <unistd.h>
26
27 #include "config.h"
28
29 #include "ap_ro_integrity_check.h"
30 #include "ccd_config.h"
31 #include "compile_time_macros.h"
32 #include "dauntless_event.h"
33 #include "flash_log.h"
34 #include "generated_version.h"
35 #include "gsctool.h"
36 #include "misc_util.h"
37 #include "signed_header.h"
38 #include "signed_manifest.h"
39 #include "tpm_registers.h"
40 #include "tpm_vendor_cmds.h"
41 #include "upgrade_fw.h"
42 #include "u2f.h"
43 #include "usb_descriptor.h"
44 #include "verify_ro.h"
45
46 /*
47 * This enum must match CcdCap enum in applications/sys_mgr/src/ccd.rs in the
48 * Ti50 common git tree.
49 */
50 enum Ti50CcdCapabilities {
51 TI50_CCD_CAP_UART_GSC_RX_AP_TX = 0,
52 TI50_CCD_CAP_UART_GSC_TX_AP_RX,
53 TI50_CCD_CAP_UART_GSC_RX_EC_TX,
54 TI50_CCD_CAP_UART_GSC_TX_EC_RX,
55 TI50_CCD_CAP_UART_GSC_RX_FPMCU_TX,
56 TI50_CCD_CAP_UART_GSC_TX_FPMCU_RX,
57 TI50_CCD_CAP_FLASH_AP,
58 TI50_CCD_CAP_FLASH_EC,
59 TI50_CCD_CAP_OVERRIDE_WP,
60 TI50_CCD_CAP_REBOOT_ECAP,
61 TI50_CCD_CAP_GSC_FULL_CONSOLE,
62 TI50_CCD_CAP_UNLOCK_NO_REBOOT,
63 TI50_CCD_CAP_UNLOCK_NO_SHORT_PP,
64 TI50_CCD_CAP_OPEN_NO_TPM_WIPE,
65 TI50_CCD_CAP_OPEN_NO_LONG_PP,
66 TI50_CCD_CAP_REMOVE_BATTERY_BYPASS_PP,
67 TI50_CCD_CAP_I2_C,
68 TI50_CCD_CAP_FLASH_READ,
69 TI50_CCD_CAP_OPEN_NO_DEV_MODE,
70 TI50_CCD_CAP_OPEN_FROM_USB,
71 TI50_CCD_CAP_OVERRIDE_BATT,
72 TI50_CCD_CAP_BOOT_UNVERIFIED_RO,
73 TI50_CCD_CAP_COUNT,
74 };
75
76 static const struct ccd_capability_info ti50_cap_info[] = {
77 { "UartGscRxAPTx", CCD_CAP_STATE_ALWAYS },
78 { "UartGscTxAPRx", CCD_CAP_STATE_ALWAYS },
79 { "UartGscRxECTx", CCD_CAP_STATE_ALWAYS },
80 { "UartGscTxECRx", CCD_CAP_STATE_IF_OPENED },
81 { "UartGscRxFpmcuTx", CCD_CAP_STATE_ALWAYS },
82 { "UartGscTxFpmcuRx", CCD_CAP_STATE_IF_OPENED },
83 { "FlashAP", CCD_CAP_STATE_IF_OPENED },
84 { "FlashEC", CCD_CAP_STATE_IF_OPENED },
85 { "OverrideWP", CCD_CAP_STATE_IF_OPENED },
86 { "RebootECAP", CCD_CAP_STATE_IF_OPENED },
87 { "GscFullConsole", CCD_CAP_STATE_IF_OPENED },
88 { "UnlockNoReboot", CCD_CAP_STATE_ALWAYS },
89 { "UnlockNoShortPP", CCD_CAP_STATE_ALWAYS },
90 { "OpenNoTPMWipe", CCD_CAP_STATE_IF_OPENED },
91 { "OpenNoLongPP", CCD_CAP_STATE_IF_OPENED },
92 { "RemoveBatteryBypassPP", CCD_CAP_STATE_ALWAYS },
93 { "I2C", CCD_CAP_STATE_IF_OPENED },
94 { "FlashRead", CCD_CAP_STATE_ALWAYS },
95 /*
96 * The below two settings do not match ccd.rs value, which is
97 * controlled at compile time.
98 */
99 { "OpenNoDevMode", CCD_CAP_STATE_IF_OPENED },
100 { "OpenFromUSB", CCD_CAP_STATE_IF_OPENED },
101 { "OverrideBatt", CCD_CAP_STATE_IF_OPENED },
102 /* The below capability is presently set to 'never' in ccd.rs. */
103 { "AllowUnverifiedRo", CCD_CAP_STATE_IF_OPENED },
104 };
105
106 #define CR50_CCD_CAP_COUNT CCD_CAP_COUNT
107
108 /*
109 * One of the basic assumptions of the code handling multiple ccd_info layouts
110 * is that the number of words in the capabilities array is the same for all
111 * layouts. Let's verify this at compile time.
112 */
113 BUILD_ASSERT((CR50_CCD_CAP_COUNT / 32) == (TI50_CCD_CAP_COUNT / 32));
114
115 /*
116 * Version 0 CCD info packet does not include the header, the actual packet
117 * size is used to conclude that the received payload is of version 0.
118 *
119 * Let's hardcode this size to make sure that it is fixed even if the
120 * underlying structure (struct ccd_info_response) size changes in the future.
121 */
122 #define CCD_INFO_V0_SIZE 23
123
124 /*
125 * This file contains the source code of a Linux application used to update
126 * CR50 device firmware.
127 *
128 * The CR50 firmware image consists of multiple sections, of interest to this
129 * app are the RO and RW code sections, two of each. When firmware update
130 * session is established, the CR50 device reports locations of backup RW and RO
131 * sections (those not used by the device at the time of transfer).
132 *
133 * Based on this information this app carves out the appropriate sections form
134 * the full CR50 firmware binary image and sends them to the device for
135 * programming into flash. Once the new sections are programmed and the device
136 * is restarted, the new RO and RW are used if they pass verification and are
137 * logically newer than the existing sections.
138 *
139 * There are two ways to communicate with the CR50 device: USB and /dev/tpm0
140 * (when this app is running on a chromebook with the CR50 device). Originally
141 * different protocols were used to communicate over different channels,
142 * starting with version 3 the same protocol is used.
143 *
144 * This app provides backwards compatibility to ensure that earlier CR50
145 * devices still can be updated.
146 *
147 *
148 * The host (either a local AP or a workstation) is controlling the firmware
149 * update protocol, it sends data to the cr50 device, which proceeses it and
150 * responds.
151 *
152 * The encapsultation format is different between the /dev/tpm0 and USB cases:
153 *
154 * 4 bytes 4 bytes 4 bytes variable size
155 * +-----------+--------------+---------------+----------~~--------------+
156 * + total size| block digest | dest address | data |
157 * +-----------+--------------+---------------+----------~~--------------+
158 * \ \ /
159 * \ \ /
160 * \ +----- FW update PDU sent over /dev/tpm0 -----------+
161 * \ /
162 * +--------- USB frame, requires total size field ------------+
163 *
164 * The update protocol data unints (PDUs) are passed over /dev/tpm0, the
165 * encapsulation includes integritiy verification and destination address of
166 * the data (more of this later). /dev/tpm0 transactions pretty much do not
167 * have size limits, whereas the USB data is sent in chunks of the size
168 * determined when the USB connestion is set up. This is why USB requires an
169 * additional encapsulation into frames to communicate the PDU size to the
170 * client side so that the PDU can be reassembled before passing to the
171 * programming function.
172 *
173 * In general, the protocol consists of two phases: connection establishment
174 * and actual image transfer.
175 *
176 * The very first PDU of the transfer session is used to establish the
177 * connection. The first PDU does not have any data, and the dest. address
178 * field is set to zero. Receiving such a PDU signals the programming function
179 * that the host intends to transfer a new image.
180 *
181 * The response to the first PDU varies depending on the protocol version.
182 *
183 * Note that protocol versions before 5 are described here for completeness,
184 * but are not supported any more by this utility.
185 *
186 * Version 1 is used over /dev/tpm0. The response is either 4 or 1 bytes in
187 * size. The 4 byte response is the *base address* of the backup RW section,
188 * no support for RO updates. The one byte response is an error indication,
189 * possibly reporting flash erase failure, command format error, etc.
190 *
191 * Version 2 is used over USB. The response is 8 bytes in size. The first four
192 * bytes are either the *base address* of the backup RW section (still no RO
193 * updates), or an error code, the same as in Version 1. The second 4 bytes
194 * are the protocol version number (set to 2).
195 *
196 * All versions above 2 behave the same over /dev/tpm0 and USB.
197 *
198 * Version 3 response is 16 bytes in size. The first 4 bytes are the error code
199 * the second 4 bytes are the protocol version (set to 3) and then 4 byte
200 * *offset* of the RO section followed by the 4 byte *offset* of the RW section.
201 *
202 * Version 4 response in addition to version 3 provides header revision fields
203 * for active RO and RW images running on the target.
204 *
205 * Once the connection is established, the image to be programmed into flash
206 * is transferred to the CR50 in 1K PDUs. In versions 1 and 2 the address in
207 * the header is the absolute address to place the block to, in version 3 and
208 * later it is the offset into the flash.
209 *
210 * Protocol version 5 includes RO and RW key ID information into the first PDU
211 * response. The key ID could be used to tell between prod and dev signing
212 * modes, among other things.
213 *
214 * Protocol version 6 does not change the format of the first PDU response,
215 * but it indicates the target's ablitiy to channel TPM vendor commands
216 * through USB connection.
217 *
218 * When channeling TPM vendor commands the USB frame looks as follows:
219 *
220 * 4 bytes 4 bytes 4 bytes 2 bytes variable size
221 * +-----------+--------------+---------------+-----------+------~~~-------+
222 * + total size| block digest | EXT_CMD | Vend. sub.| data |
223 * +-----------+--------------+---------------+-----------+------~~~-------+
224 *
225 * Where 'Vend. sub' is the vendor subcommand, and data field is subcommand
226 * dependent. The target tells between update PDUs and encapsulated vendor
227 * subcommands by looking at the EXT_CMD value - it is set to 0xbaccd00a and
228 * as such is guaranteed not to be a valid update PDU destination address.
229 *
230 * The vendor command response size is not fixed, it is subcommand dependent.
231 *
232 * The CR50 device responds to each update PDU with a confirmation which is 4
233 * bytes in size in protocol version 2, and 1 byte in size in all other
234 * versions. Zero value means success, non zero value is the error code
235 * reported by CR50.
236 *
237 * Again, vendor command responses are subcommand specific.
238 */
239
240 /* Look for Cr50 FW update interface */
241 #define H1_PID 0x5014
242 #define D2_PID 0x504A
243 #define NT_PID 0x5066
244 #define SUBCLASS USB_SUBCLASS_GOOGLE_CR50
245 #define PROTOCOL USB_PROTOCOL_GOOGLE_CR50_NON_HC_FW_UPDATE
246
247 /*
248 * CCD Info from GSC is communicated using different structure layouts.
249 * Version 0 does not have a header and includes just the payload information.
250 * Version 2 is prepended by a header which has a distinct value in the first
251 * word, and the version number and the total size in the two halfwords after
252 * that.
253 *
254 * Once the payload is received, the absence of the distinct value in the
255 * first word and the match of the payload size to the expected size of the
256 * version 0 payload indicates that this is indeed a version 0 packet. The
257 * distinct first header value and the match of the size field indicates that
258 * this is a later version packet.
259 */
260 #define CCD_INFO_MAGIC 0x49444343 /* This is 'CCDI' in little endian. */
261 #define CCD_VERSION 1 /* Ti50 CCD INFO layout. */
262
263 struct ccd_info_response_header {
264 uint32_t ccd_magic;
265 uint16_t ccd_version;
266 uint16_t ccd_size;
267 } __packed;
268
269 struct ccd_info_response_packet {
270 struct ccd_info_response_header cir_header;
271 struct ccd_info_response cir_body;
272 };
273
274 /*
275 * Need to create an entire TPM PDU when upgrading over /dev/tpm0 and need to
276 * have space to prepare the entire PDU.
277 */
278 struct upgrade_pkt {
279 __be16 tag;
280 __be32 length;
281 __be32 ordinal;
282 __be16 subcmd;
283 union {
284 /*
285 * Upgrade PDUs as opposed to all other vendor and extension
286 * commands include two additional fields in the header.
287 */
288 struct {
289 __be32 digest;
290 __be32 address;
291 char data[0];
292 } upgrade;
293 struct {
294 char data[0];
295 } command;
296 };
297 } __packed;
298
299 /*
300 * Structure used to simplify mapping command line options into Boolean
301 * variables. If an option is present, the corresponding integer value is set
302 * to 1.
303 */
304 struct options_map {
305 char opt;
306 int *flag;
307 };
308
309 /*
310 * Type of the GSC device. This is used to represent which type of GSC we are
311 * connected to and to tag an image file for compatibility.
312 * for downloading.
313 */
314 enum gsc_device {
315 GSC_DEVICE_H1,
316 GSC_DEVICE_DT,
317 GSC_DEVICE_NT,
318 };
319
320 /* Index to refer to a section within sections array */
321 enum section {
322 RO_A,
323 RW_A,
324 RO_B,
325 RW_B,
326 NUM_SECTIONS,
327 };
328
329 /* Human-readable section names */
330 const char *SECTION_NAMES[NUM_SECTIONS] = { [RO_A] = "RO_A",
331 [RW_A] = "RW_A",
332 [RO_B] = "RO_B",
333 [RW_B] = "RW_B" };
334
335 /* Describes each of the sections found in the GSC image */
336 struct section_t {
337 uint32_t offset;
338 uint32_t size;
339 bool update_needed;
340 struct signed_header_version shv;
341 uint32_t keyid;
342 };
343
344 /* Holds a GSC image from disk that can be transfer to a GSC as an update */
345 struct image {
346 uint8_t *data;
347 size_t data_len;
348 enum gsc_device type;
349 const char *file_path;
350 struct section_t sections[NUM_SECTIONS];
351 };
352
353 /* A header with a GSC device type */
354 struct typed_image_header {
355 enum gsc_device type;
356 union {
357 struct SignedHeader *h;
358 struct SignedManifest *m;
359 };
360 };
361
362 /*
363 * Structure used to combine option description used by getopt_long() and help
364 * text for the option.
365 */
366 struct option_container {
367 struct option opt;
368 const char *help_text;
369 };
370
371 static void sha_init(EVP_MD_CTX *ctx);
372 static void sha_update(EVP_MD_CTX *ctx, const void *data, size_t len);
373 static void sha_final_into_block_digest(EVP_MD_CTX *ctx, void *block_digest,
374 size_t size);
375
376 /* Type of the GSC device we are talking to, determined at run time. */
377 static enum gsc_device gsc_dev = GSC_DEVICE_H1;
378
379 /*
380 * Current AP RO verification config setting version
381 */
382 #define ARV_CONFIG_SETTING_CURRENT_VERSION 0x01
383
384 /*
385 * AP RO verification config setting command choices
386 */
387 enum arv_config_setting_command_e {
388 arv_config_setting_command_spi_addressing_mode = 0,
389 arv_config_setting_command_write_protect_descriptors = 1,
390 };
391
392 /*
393 * AP RO verification config setting state
394 */
395 enum arv_config_setting_state_e {
396 arv_config_setting_state_present = 0,
397 arv_config_setting_state_not_present = 1,
398 arv_config_setting_state_corrupted = 2,
399 arv_config_setting_state_invalid = 3,
400 };
401
402 /*
403 * AP RO verification SPI read/write addressing mode configuration choices
404 */
405 enum arv_config_spi_addr_mode_e {
406 arv_config_spi_addr_mode_none = 0,
407 arv_config_spi_addr_mode_get = 1,
408 arv_config_spi_addr_mode_set_3byte = 2,
409 arv_config_spi_addr_mode_set_4byte = 3,
410 };
411
412 /*
413 * AP RO verification write protect descriptor configuration choices
414 */
415 enum arv_config_wpsr_choice_e {
416 arv_config_wpsr_choice_none = 0,
417 arv_config_wpsr_choice_get = 1,
418 arv_config_wpsr_choice_set = 2,
419 };
420
421 /*
422 * AP RO verification write protect descriptor information
423 */
424 struct __attribute__((__packed__)) arv_config_wpd {
425 /* See `arv_config_setting_state_e` */
426 uint8_t state;
427 uint8_t expected_value;
428 uint8_t mask;
429 };
430
431 /*
432 * AP RO verification write protect descriptors. This is a helper type to
433 * represent the three write protect descriptors.
434 */
435 struct __attribute__((__packed__)) arv_config_wpds {
436 struct arv_config_wpd data[3];
437 };
438
439 /*
440 * This matches the largest vendor command response size we ever expect.
441 */
442 #define MAX_RX_BUF_SIZE 2048
443
444 /*
445 * Maximum update payload block size plus packet header size.
446 */
447 #define MAX_TX_BUF_SIZE (SIGNED_TRANSFER_SIZE + sizeof(struct upgrade_pkt))
448
449 /*
450 * Max. length of the board ID string representation.
451 *
452 * Board ID is either a 4-character ASCII alphanumeric string or an 8-digit
453 * hex.
454 */
455 #define MAX_BOARD_ID_LENGTH 9
456
457 /*
458 * Length, in bytes, of the SN Bits serial number bits.
459 */
460 #define SN_BITS_SIZE (96 >> 3)
461
462 /*
463 * Max. length of FW version in the format of <epoch>.<major>.<minor>
464 * (3 uint32_t string representation + 2 separators + NULL terminator).
465 */
466 #define MAX_FW_VER_LENGTH 33
467
468 static int verbose_mode;
469 static uint32_t protocol_version;
470 static char *progname;
471
472 /*
473 * List of command line options, ***sorted by the short form***.
474 *
475 * The help_text field does not include the short and long option strings,
476 * they are retrieved from the opt structure. In case the help text needs to
477 * have something printed immediately after the option strings (for example,
478 * an optional parameter), it should be included in the beginning of help_text
479 * string separated by the % character.
480 *
481 * usage() function which prints out the help message will concatenate the
482 * short and long options and the optional parameter, if present, and then
483 * print the rest of the text message at a fixed indentation.
484 */
485 static const struct option_container cmd_line_options[] = {
486 /* {{name has_arg *flag val} long_desc dev_type} */
487 { { "get_apro_hash", no_argument, NULL, 'A' },
488 "get the stored ap ro hash" },
489 { { "any", no_argument, NULL, 'a' },
490 "Try any interfaces to find Cr50"
491 " (-d, -s, -t are all ignored)" },
492 { { "apro_boot", optional_argument, NULL, 'B' },
493 "[start] get the stored ap ro boot state or start ap ro verify" },
494 { { "binvers", no_argument, NULL, 'b' },
495 "Report versions of Cr50 image's "
496 "RW and RO headers, do not update" },
497 { { "apro_config_spi_mode", optional_argument, NULL, 'C' },
498 "Get/set the ap ro verify spi mode either to `3byte` or `4byte`" },
499 { { "corrupt", no_argument, NULL, 'c' }, "Corrupt the inactive rw" },
500 { { "dauntless", no_argument, NULL, 'D' },
501 "Deprecated. No longer needed as runtime selection is used." },
502 { { "device", required_argument, NULL, 'd' },
503 "VID:PID%USB device (default 18d1:5014 or 18d1:504a based on"
504 " image)" },
505 { { "apro_config_write_protect", optional_argument, NULL, 'E' },
506 "Get/set the ap ro verify write protect descriptors with hex "
507 "bytes (ex: 0x01, 0x1, 01 or 1) in the following format: "
508 "[sr1 mask1 [sr2 mask2] [sr3 mask3]]" },
509 { { "endorsement_seed", optional_argument, NULL, 'e' },
510 "[state]%get/set the endorsement key seed" },
511 { { "factory", required_argument, NULL, 'F' },
512 "[enable|disable]%Control factory mode" },
513 { { "fwver", no_argument, NULL, 'f' },
514 "Report running Cr50 firmware versions" },
515 { { "get_time", no_argument, NULL, 'G' },
516 "Get time since last cold reset" },
517 { { "getbootmode", no_argument, NULL, 'g' },
518 "Get the system boot mode" },
519 { { "erase_ap_ro_hash", no_argument, NULL, 'H' },
520 "Erase AP RO hash (possible only if Board ID is not set)" },
521 { { "help", no_argument, NULL, 'h' }, "Show this message" },
522 { { "ccd_info", optional_argument, NULL, 'I' },
523 "[capability:value]%Get information about CCD state or set capability"
524 " value if allowed" },
525 { { "board_id", optional_argument, NULL, 'i' },
526 "[ID[:FLAGS]]%Get or set Info1 board ID fields. ID could be 32 bit "
527 "hex or 4 character string." },
528 { { "boot_trace", optional_argument, NULL, 'J' },
529 "[erase]%Retrieve boot trace from the chip, optionally erasing "
530 "the trace buffer" },
531 { { "get_value", required_argument, NULL, 'K' },
532 "[chassis_open|dev_ids]%Get properties values" },
533 { { "ccd_lock", no_argument, NULL, 'k' }, "Lock CCD" },
534 { { "flog", optional_argument, NULL, 'L' },
535 "[prev entry]%Retrieve contents of the flash log"
536 " (newer than <prev entry> if specified)" },
537 { { "console", no_argument, NULL, 'l' },
538 "Get console logs. This may need to be run multiple times to collect "
539 "all available logs." },
540 { { "machine", no_argument, NULL, 'M' },
541 "Output in a machine-friendly way. "
542 "Effective with -b, -f, -i, -J, -r, and -O." },
543 { { "tpm_mode", optional_argument, NULL, 'm' },
544 "[enable|disable]%Change or query tpm_mode" },
545 { { "serial", required_argument, NULL, 'n' }, "GSC USB serial number" },
546 { { "openbox_rma", required_argument, NULL, 'O' },
547 "<desc_file>%Verify other device's RO integrity using information "
548 "provided in <desc file>" },
549 { { "ccd_open", no_argument, NULL, 'o' }, "Start CCD open sequence" },
550 { { "password", no_argument, NULL, 'P' },
551 "Set or clear CCD password. Use 'clear:<cur password>' to clear it" },
552 { { "post_reset", no_argument, NULL, 'p' },
553 "Request post reset after transfer" },
554 { { "force_ro", no_argument, NULL, 'q' }, "Force inactive RO update" },
555 { { "sn_rma_inc", required_argument, NULL, 'R' },
556 "RMA_INC%Increment SN RMA count by RMA_INC. RMA_INC should be 0-7." },
557 { { "rma_auth", optional_argument, NULL, 'r' },
558 "[auth_code]%Request RMA challenge, process "
559 "RMA authentication code" },
560 { { "sn_bits", required_argument, NULL, 'S' },
561 "SN_BITS%Set Info1 SN bits fields. SN_BITS should be 96 bit hex." },
562 { { "systemdev", no_argument, NULL, 's' },
563 "Use /dev/tpm0 (-d is ignored)" },
564 { { "tstamp", optional_argument, NULL, 'T' },
565 "[<tstamp>]%Get or set flash log timestamp base" },
566 { { "trunks_send", no_argument, NULL, 't' },
567 "Use `trunks_send --raw' (-d is ignored)" },
568 { { "ccd_unlock", no_argument, NULL, 'U' },
569 "Start CCD unlock sequence" },
570 { { "upstart", no_argument, NULL, 'u' },
571 "Upstart mode (strict header checks)" },
572 { { "verbose", no_argument, NULL, 'V' }, "Enable debug messages" },
573 { { "version", no_argument, NULL, 'v' },
574 "Report this utility version" },
575 { { "metrics", no_argument, NULL, 'W' }, "Get GSC metrics" },
576 { { "wp", optional_argument, NULL, 'w' },
577 "[enable|disable|follow]%Get or set the write protect setting" },
578 { { "clog", no_argument, NULL, 'x' },
579 "Retrieve contents of the most recent crash log." },
580 { { "factory_config", optional_argument, NULL, 'y' },
581 "[value]%Sets the factory config bits in INFO. value should be 64 "
582 "bit hex." },
583 { { "reboot", optional_argument, NULL, 'z' },
584 "Tell the GSC to reboot with an optional reset timeout parameter "
585 "in milliseconds" },
586 };
587
588 /* Helper to print debug messages when verbose flag is specified. */
debug(const char * fmt,...)589 static void debug(const char *fmt, ...)
590 {
591 va_list args;
592
593 if (verbose_mode) {
594 va_start(args, fmt);
595 vprintf(fmt, args);
596 va_end(args);
597 }
598 }
599
600 /* Helpers to convert between binary and hex ascii and back. */
to_hexascii(uint8_t c)601 static char to_hexascii(uint8_t c)
602 {
603 if (c <= 9)
604 return '0' + c;
605 return 'a' + c - 10;
606 }
607
from_hexascii(char c)608 static int from_hexascii(char c)
609 {
610 /* convert to lower case. */
611 c = tolower(c);
612
613 if (c < '0' || c > 'f' || ((c > '9') && (c < 'a')))
614 return -1; /* Not an ascii character. */
615
616 if (c <= '9')
617 return c - '0';
618
619 return c - 'a' + 10;
620 }
621
622 /* Returns true if the connected GSC device has Ti50-based firmware. */
is_ti50_device(void)623 static bool is_ti50_device(void)
624 {
625 /* Assume Ti50 is not H1 device. */
626 return gsc_dev != GSC_DEVICE_H1;
627 }
628
629 /* Functions to communicate with the TPM over the trunks_send --raw channel. */
630
631 /* File handle to share between write and read sides. */
632 static FILE *tpm_output;
ts_write(const void * out,size_t len)633 static int ts_write(const void *out, size_t len)
634 {
635 const char *cmd_head = "PATH=\"${PATH}:/usr/sbin:/vendor/bin/hw\" "
636 "${TRUNKS_SEND_BIN:-trunks_send} --raw ";
637 size_t head_size = strlen(cmd_head);
638 char full_command[head_size + 2 * len + 1];
639 size_t i;
640
641 strcpy(full_command, cmd_head);
642 /*
643 * Need to convert binary input into hex ascii output to pass to the
644 * trunks_send command.
645 */
646 for (i = 0; i < len; i++) {
647 uint8_t c = ((const uint8_t *)out)[i];
648
649 full_command[head_size + 2 * i] = to_hexascii(c >> 4);
650 full_command[head_size + 2 * i + 1] = to_hexascii(c & 0xf);
651 }
652
653 /* Make it a proper zero terminated string. */
654 full_command[sizeof(full_command) - 1] = 0;
655 debug("cmd: %s\n", full_command);
656 tpm_output = popen(full_command, "r");
657 if (tpm_output)
658 return len;
659
660 fprintf(stderr, "Error: failed to launch trunks_send --raw\n");
661 return -1;
662 }
663
ts_read(void * buf,size_t max_rx_size)664 static int ts_read(void *buf, size_t max_rx_size)
665 {
666 int i;
667 int pclose_rv;
668 int rv;
669 /* +1 to account for '\n' added by trunks_send. */
670 char response[max_rx_size * 2 + 1];
671
672 if (!tpm_output) {
673 fprintf(stderr, "Error: attempt to read empty output\n");
674 return -1;
675 }
676
677 rv = fread(response, 1, sizeof(response), tpm_output);
678 if (rv > 0)
679 rv -= 1; /* Discard the \n character added by trunks_send. */
680
681 debug("response of size %d, max rx size %zd: %s\n", rv, max_rx_size,
682 response);
683
684 pclose_rv = pclose(tpm_output);
685 if (pclose_rv < 0) {
686 fprintf(stderr, "Error: pclose failed: error %d (%s)\n", errno,
687 strerror(errno));
688 return -1;
689 }
690
691 tpm_output = NULL;
692
693 if (rv & 1) {
694 fprintf(stderr,
695 "Error: trunks_send returned odd number of bytes: %s\n",
696 response);
697 return -1;
698 }
699
700 for (i = 0; i < rv / 2; i++) {
701 uint8_t byte;
702 char c;
703 int nibble;
704
705 c = response[2 * i];
706 nibble = from_hexascii(c);
707 if (nibble < 0) {
708 fprintf(stderr,
709 "Error: "
710 "trunks_send returned non hex character %c\n",
711 c);
712 return -1;
713 }
714 byte = nibble << 4;
715
716 c = response[2 * i + 1];
717 nibble = from_hexascii(c);
718 if (nibble < 0) {
719 fprintf(stderr,
720 "Error: "
721 "trunks_send returned non hex character %c\n",
722 c);
723 return -1;
724 }
725 byte |= nibble;
726
727 ((uint8_t *)buf)[i] = byte;
728 }
729
730 return rv / 2;
731 }
732
733 /*
734 * Prepare and transfer a block to either to /dev/tpm0 or through trunks_send
735 * --raw, get a reply.
736 */
tpm_send_pkt(struct transfer_descriptor * td,unsigned int digest,unsigned int addr,const void * data,int size,void * response,size_t * response_size,uint16_t subcmd)737 static int tpm_send_pkt(struct transfer_descriptor *td, unsigned int digest,
738 unsigned int addr, const void *data, int size,
739 void *response, size_t *response_size, uint16_t subcmd)
740 {
741 /* Used by transfer to /dev/tpm0 */
742 static uint8_t outbuf[MAX_TX_BUF_SIZE];
743 static uint8_t
744 raw_response[MAX_RX_BUF_SIZE + sizeof(struct upgrade_pkt)];
745 struct upgrade_pkt *out = (struct upgrade_pkt *)outbuf;
746 int len, done;
747 int response_offset = offsetof(struct upgrade_pkt, command.data);
748 void *payload;
749 size_t header_size;
750 uint32_t rv;
751 const size_t rx_size = sizeof(raw_response);
752
753 debug("%s: sending to %#x %d bytes\n", __func__, addr, size);
754
755 out->tag = htobe16(0x8001);
756 out->subcmd = htobe16(subcmd);
757
758 if (subcmd <= LAST_EXTENSION_COMMAND)
759 out->ordinal = htobe32(CONFIG_EXTENSION_COMMAND);
760 else
761 out->ordinal = htobe32(TPM_CC_VENDOR_BIT_MASK);
762
763 if (subcmd == EXTENSION_FW_UPGRADE) {
764 /* FW Upgrade PDU header includes a couple of extra fields. */
765 out->upgrade.digest = digest;
766 out->upgrade.address = htobe32(addr);
767 header_size = offsetof(struct upgrade_pkt, upgrade.data);
768 } else {
769 header_size = offsetof(struct upgrade_pkt, command.data);
770 }
771
772 payload = outbuf + header_size;
773 len = size + header_size;
774
775 out->length = htobe32(len);
776 memcpy(payload, data, size);
777
778 if (verbose_mode) {
779 int i;
780
781 debug("Writing %d bytes to TPM at %x\n", len, addr);
782 for (i = 0; i < MIN(len, 20); i++)
783 debug("%2.2x ", outbuf[i]);
784 debug("\n");
785 }
786
787 switch (td->ep_type) {
788 case dev_xfer:
789 done = write(td->tpm_fd, out, len);
790 break;
791 case ts_xfer:
792 done = ts_write(out, len);
793 break;
794 default:
795 fprintf(stderr, "Error: %s:%d: unknown transfer type %d\n",
796 __func__, __LINE__, td->ep_type);
797 return -1;
798 }
799
800 if (done < 0) {
801 perror("Could not write to TPM");
802 return -1;
803 } else if (done != len) {
804 fprintf(stderr, "Error: Wrote %d bytes, expected to write %d\n",
805 done, len);
806 return -1;
807 }
808
809 switch (td->ep_type) {
810 case dev_xfer: {
811 int read_count;
812
813 len = 0;
814 do {
815 uint8_t *rx_buf = raw_response + len;
816 size_t rx_to_go = rx_size - len;
817
818 read_count = read(td->tpm_fd, rx_buf, rx_to_go);
819
820 len += read_count;
821 } while (read_count);
822 break;
823 }
824 case ts_xfer:
825 len = ts_read(raw_response, rx_size);
826 break;
827 default:
828 /*
829 * This sure will never happen, type is verifed in the
830 * previous switch statement.
831 */
832 len = -1;
833 break;
834 }
835
836 debug("Read %d bytes from TPM\n", len);
837 if (len > 0) {
838 int i;
839
840 for (i = 0; i < len; i++)
841 debug("%2.2x ", raw_response[i]);
842 debug("\n");
843 }
844 len = len - response_offset;
845 if (len < 0) {
846 fprintf(stderr, "Problems reading from TPM, got %d bytes\n",
847 len + response_offset);
848 return -1;
849 }
850
851 if (response && response_size) {
852 len = MIN(len, *response_size);
853 memcpy(response, raw_response + response_offset, len);
854 *response_size = len;
855 }
856
857 /* Return the actual return code from the TPM response header. */
858 memcpy(&rv, &((struct upgrade_pkt *)raw_response)->ordinal, sizeof(rv));
859 rv = be32toh(rv);
860
861 /* Clear out vendor command return value offset.*/
862 if ((rv & VENDOR_RC_ERR) == VENDOR_RC_ERR)
863 rv &= ~VENDOR_RC_ERR;
864
865 return rv;
866 }
867
868 /* Release USB device and return error to the OS. */
shut_down(struct usb_endpoint * uep)869 static void shut_down(struct usb_endpoint *uep)
870 {
871 usb_shut_down(uep);
872 exit(update_error);
873 }
874
usage(int errs)875 static void usage(int errs)
876 {
877 size_t i;
878 const int indent = 27; /* This is the size used by gsctool all along. */
879
880 printf("\nUsage: %s [options] [<binary image>]\n"
881 "\n"
882 "This utility allows to update Cr50 RW firmware, configure\n"
883 "various aspects of Cr50 operation, analyze Cr50 binary\n"
884 "images, etc.\n\n"
885 "<binary image> is the file name of a full RO+RW binary image.\n"
886 "\n"
887 "Options:\n\n",
888 progname);
889
890 for (i = 0; i < ARRAY_SIZE(cmd_line_options); i++) {
891 const char *help_text = cmd_line_options[i].help_text;
892 int printed_length;
893 const char *separator;
894
895 /*
896 * First print the short and long forms of the command line
897 * option.
898 */
899 printed_length = printf(" -%c,--%s",
900 cmd_line_options[i].opt.val,
901 cmd_line_options[i].opt.name);
902
903 /*
904 * If there is something to print immediately after the
905 * options, print it.
906 */
907 separator = strchr(help_text, '%');
908 if (separator) {
909 char buffer[80];
910 size_t extra_size;
911
912 extra_size = separator - help_text;
913 if (extra_size >= sizeof(buffer)) {
914 fprintf(stderr, "misformatted help text: %s\n",
915 help_text);
916 exit(-1);
917 }
918 memcpy(buffer, help_text, extra_size);
919 buffer[extra_size] = '\0';
920 printed_length += printf(" %s", buffer);
921 help_text = separator + 1;
922 }
923
924 /*
925 * If printed length exceeds or is too close to indent, print
926 * help text on the next line.
927 */
928 if (printed_length >= (indent - 1)) {
929 printf("\n");
930 printed_length = 0;
931 }
932
933 while (printed_length++ < indent)
934 printf(" ");
935 printf("%s\n", help_text);
936 }
937 printf("\n");
938 exit(errs ? update_error : noop);
939 }
940
941 /* Read file into buffer */
get_file_or_die(const char * filename,size_t * len_ptr)942 static uint8_t *get_file_or_die(const char *filename, size_t *len_ptr)
943 {
944 FILE *fp;
945 struct stat st;
946 uint8_t *data;
947 size_t len;
948
949 fp = fopen(filename, "rb");
950 if (!fp) {
951 perror(filename);
952 exit(update_error);
953 }
954 if (fstat(fileno(fp), &st)) {
955 perror("stat");
956 exit(update_error);
957 }
958
959 len = st.st_size;
960
961 data = malloc(len);
962 if (!data) {
963 perror("malloc");
964 exit(update_error);
965 }
966
967 if (1 != fread(data, st.st_size, 1, fp)) {
968 perror("fread");
969 exit(update_error);
970 }
971
972 fclose(fp);
973
974 *len_ptr = len;
975 return data;
976 }
977
978 /* Returns true if parsed. */
parse_vidpid(const char * input,uint16_t * vid_ptr,uint16_t * pid_ptr)979 static int parse_vidpid(const char *input, uint16_t *vid_ptr, uint16_t *pid_ptr)
980 {
981 char *copy, *s, *e = 0;
982
983 copy = strdup(input);
984
985 s = strchr(copy, ':');
986 if (!s)
987 return 0;
988 *s++ = '\0';
989
990 *vid_ptr = (uint16_t)strtoul(copy, &e, 16);
991 if (!*optarg || (e && *e))
992 return 0;
993
994 *pid_ptr = (uint16_t)strtoul(s, &e, 16);
995 if (!*optarg || (e && *e))
996 return 0;
997
998 return 1;
999 }
1000
1001 struct update_pdu {
1002 uint32_t block_size; /* Total block size, include this field's size. */
1003 struct upgrade_command cmd;
1004 /* The actual payload goes here. */
1005 };
1006
do_xfer(struct usb_endpoint * uep,void * outbuf,int outlen,void * inbuf,int inlen,int allow_less,size_t * rxed_count)1007 static void do_xfer(struct usb_endpoint *uep, void *outbuf, int outlen,
1008 void *inbuf, int inlen, int allow_less, size_t *rxed_count)
1009 {
1010 if (usb_trx(uep, outbuf, outlen, inbuf, inlen, allow_less, rxed_count))
1011 shut_down(uep);
1012 }
1013
transfer_block(struct usb_endpoint * uep,struct update_pdu * updu,uint8_t * transfer_data_ptr,size_t payload_size)1014 static int transfer_block(struct usb_endpoint *uep, struct update_pdu *updu,
1015 uint8_t *transfer_data_ptr, size_t payload_size)
1016 {
1017 size_t transfer_size;
1018 uint32_t reply;
1019 int actual;
1020 int r;
1021
1022 /* First send the header. */
1023 do_xfer(uep, updu, sizeof(*updu), NULL, 0, 0, NULL);
1024
1025 /* Now send the block, chunk by chunk. */
1026 for (transfer_size = 0; transfer_size < payload_size;) {
1027 int chunk_size;
1028
1029 chunk_size = MIN(uep->chunk_len, payload_size - transfer_size);
1030 do_xfer(uep, transfer_data_ptr, chunk_size, NULL, 0, 0, NULL);
1031 transfer_data_ptr += chunk_size;
1032 transfer_size += chunk_size;
1033 }
1034
1035 /* Now get the reply. */
1036 r = libusb_bulk_transfer(uep->devh, uep->ep_num | 0x80, (void *)&reply,
1037 sizeof(reply), &actual, 1000);
1038 if (r) {
1039 if (r == -7) {
1040 fprintf(stderr, "Timeout!\n");
1041 return r;
1042 }
1043 USB_ERROR("libusb_bulk_transfer", r);
1044 shut_down(uep);
1045 }
1046
1047 reply = *((uint8_t *)&reply);
1048 if (reply) {
1049 fprintf(stderr, "Error: status %#x\n", reply);
1050 exit(update_error);
1051 }
1052
1053 return 0;
1054 }
1055
1056 /**
1057 * Transfer an image section (typically RW or RO).
1058 *
1059 * td - transfer descriptor to use to communicate with the target
1060 * data_ptr - pointer at the section base in the image
1061 * section_addr - address of the section in the target memory space
1062 * data_len - section size
1063 */
transfer_section(struct transfer_descriptor * td,uint8_t * data_ptr,uint32_t section_addr,size_t data_len)1064 static void transfer_section(struct transfer_descriptor *td, uint8_t *data_ptr,
1065 uint32_t section_addr, size_t data_len)
1066 {
1067 /*
1068 * Actually, we can skip trailing chunks of 0xff, as the entire
1069 * section space must be erased before the update is attempted.
1070 */
1071 while (data_len && (data_ptr[data_len - 1] == 0xff))
1072 data_len--;
1073
1074 /*
1075 * Make sure total size is 4 bytes aligned, this is required for
1076 * successful flashing.
1077 */
1078 data_len = (data_len + 3) & ~3;
1079
1080 printf("sending 0x%zx bytes to %#x\n", data_len, section_addr);
1081 while (data_len) {
1082 size_t payload_size;
1083 EVP_MD_CTX *ctx;
1084 int max_retries;
1085 struct update_pdu updu;
1086
1087 /* prepare the header to prepend to the block. */
1088 payload_size = MIN(data_len, SIGNED_TRANSFER_SIZE);
1089 updu.block_size =
1090 htobe32(payload_size + sizeof(struct update_pdu));
1091
1092 updu.cmd.block_base = htobe32(section_addr);
1093
1094 /* Calculate the digest. */
1095 ctx = EVP_MD_CTX_new();
1096 sha_init(ctx);
1097 sha_update(ctx, &updu.cmd.block_base,
1098 sizeof(updu.cmd.block_base));
1099 sha_update(ctx, data_ptr, payload_size);
1100 sha_final_into_block_digest(ctx, &updu.cmd.block_digest,
1101 sizeof(updu.cmd.block_digest));
1102 EVP_MD_CTX_free(ctx);
1103
1104 if (td->ep_type == usb_xfer) {
1105 for (max_retries = 10; max_retries; max_retries--)
1106 if (!transfer_block(&td->uep, &updu, data_ptr,
1107 payload_size))
1108 break;
1109
1110 if (!max_retries) {
1111 fprintf(stderr,
1112 "Failed to transfer block, %zd to go\n",
1113 data_len);
1114 exit(update_error);
1115 }
1116 } else {
1117 uint8_t error_code[4];
1118 size_t rxed_size = sizeof(error_code);
1119 uint32_t block_addr;
1120
1121 block_addr = section_addr;
1122
1123 /*
1124 * A single byte response is expected, but let's give
1125 * the driver a few extra bytes to catch cases when a
1126 * different amount of data is transferred (which
1127 * would indicate a synchronization problem).
1128 */
1129 if (tpm_send_pkt(td, updu.cmd.block_digest, block_addr,
1130 data_ptr, payload_size, error_code,
1131 &rxed_size,
1132 EXTENSION_FW_UPGRADE) < 0) {
1133 fprintf(stderr,
1134 "Failed to trasfer block, %zd to go\n",
1135 data_len);
1136 exit(update_error);
1137 }
1138 if (rxed_size != 1) {
1139 fprintf(stderr, "Unexpected return size %zd\n",
1140 rxed_size);
1141 exit(update_error);
1142 }
1143
1144 if (error_code[0]) {
1145 fprintf(stderr, "Error %d\n", error_code[0]);
1146 exit(update_error);
1147 }
1148 }
1149 data_len -= payload_size;
1150 data_ptr += payload_size;
1151 section_addr += payload_size;
1152 }
1153 }
1154
1155 /* Information about the target */
1156 static struct first_response_pdu targ;
1157
1158 /* The well known CR50 section location and sizes. These are not scanned for. */
1159 const struct section_t CR50_SECTIONS[NUM_SECTIONS] = {
1160 [RO_A] = { CONFIG_RO_MEM_OFF, CONFIG_RO_SIZE },
1161 [RW_A] = { CONFIG_RW_MEM_OFF, CONFIG_RW_SIZE },
1162 [RO_B] = { CHIP_RO_B_MEM_OFF, CONFIG_RO_SIZE },
1163 [RW_B] = { CONFIG_RW_B_MEM_OFF, CONFIG_RW_SIZE }
1164 };
1165
1166 /*
1167 * Remove these definitions so a developer doesn't accidentally use them in
1168 * the future. All lookups should go through the sections array.
1169 */
1170 #undef CONFIG_RO_MEM_OFF
1171 #undef CONFIG_RW_MEM_OFF
1172 #undef CHIP_RO_B_MEM_OFF
1173 #undef CONFIG_RW_B_MEM_OFF
1174 #undef CONFIG_RO_SIZE
1175 #undef CONFIG_RW_SIZE
1176 #undef CONFIG_FLASH_SIZE
1177
1178 /* Returns true if the specified signed header is valid */
valid_signed_header(const struct SignedHeader * const h,const size_t size)1179 static bool valid_signed_header(const struct SignedHeader *const h,
1180 const size_t size)
1181 {
1182 if (size < sizeof(struct SignedHeader))
1183 return false;
1184
1185 /* Only H1 and D2 are currently supported. */
1186 if (h->magic != MAGIC_HAVEN && h->magic != MAGIC_DAUNTLESS)
1187 return false;
1188
1189 if (h->image_size > size)
1190 return false;
1191
1192 if (h->image_size < CONFIG_FLASH_BANK_SIZE)
1193 return false;
1194
1195 /*
1196 * Both Rx base and Ro base are the memory mapped address, but they
1197 * should have the same offset. The rx section starts after the header.
1198 */
1199 if (h->rx_base != h->ro_base + sizeof(struct SignedHeader))
1200 return false;
1201
1202 /* Ensure each section falls within full size */
1203 if (h->ro_max - h->ro_base > size)
1204 return false;
1205
1206 if (h->rx_max - h->rx_base > size)
1207 return false;
1208
1209 return true;
1210 }
1211
1212 /* Returns true if the specified opentitan manifest header is valid */
valid_nt_manifest(const struct SignedManifest * const m,const size_t size)1213 static bool valid_nt_manifest(const struct SignedManifest *const m,
1214 const size_t size)
1215 {
1216 if (size < sizeof(struct SignedManifest))
1217 return false;
1218
1219 if (m->identifier != ID_ROM_EXT && m->identifier != ID_OWNER_FW)
1220 return false;
1221
1222 if (m->length > size)
1223 return false;
1224
1225 if (m->code_start > m->code_end)
1226 return false;
1227
1228 if (m->code_start > m->length)
1229 return false;
1230
1231 if (m->code_end > m->length)
1232 return false;
1233
1234 if (m->entry_point > m->code_end)
1235 return false;
1236
1237 if (m->entry_point < m->code_start)
1238 return false;
1239
1240 return true;
1241 }
1242
1243 /* Returns true if the specified image header is valid */
valid_image_header(const struct typed_image_header h,const size_t size,enum gsc_device * out_device)1244 static bool valid_image_header(const struct typed_image_header h,
1245 const size_t size, enum gsc_device *out_device)
1246 {
1247 if (valid_nt_manifest(h.m, size)) {
1248 enum gsc_device type = GSC_DEVICE_NT;
1249
1250 if (out_device) {
1251 *out_device = type;
1252 return true;
1253 } else {
1254 return h.type == type;
1255 }
1256 }
1257 if (valid_signed_header(h.h, size)) {
1258 enum gsc_device type = GSC_DEVICE_H1;
1259
1260 if (h.h->magic == MAGIC_DAUNTLESS) {
1261 type = GSC_DEVICE_DT;
1262 } else if (h.h->magic != MAGIC_HAVEN) {
1263 fprintf(stderr,
1264 "Error: Cannot determine image type.\n");
1265 /* Unsupported image type */
1266 exit(update_error);
1267 }
1268 if (out_device) {
1269 *out_device = type;
1270 return true;
1271 } else {
1272 return h.type == type;
1273 }
1274 }
1275 return false;
1276 }
1277
1278 /* Returns the image size from the header. This assumes it is valid */
get_size_from_header(const struct typed_image_header h)1279 static uint32_t get_size_from_header(const struct typed_image_header h)
1280 {
1281 if (h.type == GSC_DEVICE_H1 || h.type == GSC_DEVICE_DT)
1282 return h.h->image_size;
1283
1284 if (h.type == GSC_DEVICE_NT)
1285 return h.m->length;
1286
1287 fprintf(stderr, "Error: Cannot determine image type.\n");
1288 /* Unsupported image type */
1289 exit(update_error);
1290 return 0;
1291 }
1292
1293 /* Rounds and address up to the next 2KB boundary if not one already */
round_up_2kb(const uint32_t addr)1294 static inline uint32_t round_up_2kb(const uint32_t addr)
1295 {
1296 const uint32_t mask = (2 * 1024) - 1;
1297
1298 return (addr + mask) & ~mask;
1299 }
1300
as_header(const struct image * image,uint32_t offset)1301 static struct typed_image_header as_header(const struct image *image,
1302 uint32_t offset)
1303 {
1304 struct typed_image_header ret = {
1305 image->type,
1306 { (void *)((uintptr_t)image->data + offset) },
1307 };
1308 return ret;
1309 }
1310
1311 /* Returns the RW header or -1 if one cannot be found */
find_rw_header(const struct image * image,uint32_t offset,const uint32_t end)1312 static int32_t find_rw_header(const struct image *image, uint32_t offset,
1313 const uint32_t end)
1314 {
1315 offset = round_up_2kb(offset);
1316
1317 while (offset < end) {
1318 if (valid_image_header(as_header(image, offset), end - offset,
1319 NULL))
1320 return offset;
1321 offset = round_up_2kb(offset + 1);
1322 }
1323
1324 return -1;
1325 }
1326
1327 /* Return true if we located headers and set sections correctly */
locate_headers(struct image * image)1328 static bool locate_headers(struct image *image)
1329 {
1330 const uint32_t slot_a_end = image->data_len / 2;
1331 struct section_t *sections = image->sections;
1332 int32_t rw_offset;
1333
1334 /*
1335 * We assume that all 512KB images are "valid" H1 images. The DBG images
1336 * from the signer do not set the magic to -1 and no not set valid
1337 * section offsets. We do not want to break this case as it is used in
1338 * testing. The H1 offsets are also static, so we don't need to scan
1339 * for RW headers.
1340 */
1341 if (image->data_len == (512 * 1024)) {
1342 image->type = GSC_DEVICE_H1;
1343 memcpy(sections, CR50_SECTIONS, sizeof(CR50_SECTIONS));
1344 return true;
1345 }
1346
1347 /*
1348 * We know that all other image types supported (i.e. Dauntless,
1349 * NuvoTitan) are 1MB in size.
1350 */
1351 if (image->data_len != (1024 * 1024)) {
1352 fprintf(stderr, "\nERROR: Image size (%zd KB) is invalid\n",
1353 image->data_len / 1024);
1354 return false;
1355 }
1356
1357 /* Validate the RO_A header */
1358 if (!valid_image_header(as_header(image, 0), slot_a_end,
1359 &image->type)) {
1360 fprintf(stderr, "\nERROR: RO_A header is invalid\n");
1361 return false;
1362 }
1363
1364 sections[RO_A].offset = 0;
1365 sections[RO_A].size = get_size_from_header(as_header(image, 0));
1366
1367 /* Find RW_A */
1368 rw_offset = find_rw_header(
1369 image, sections[RO_A].offset + sections[RO_A].size, slot_a_end);
1370 if (rw_offset == -1) {
1371 fprintf(stderr, "\nERROR: RW_A header cannot be found\n");
1372 return false;
1373 }
1374 sections[RW_A].offset = rw_offset;
1375 sections[RW_A].size = get_size_from_header(as_header(image, rw_offset));
1376
1377 /* Validate the RO_B header */
1378 if (!valid_image_header(as_header(image, slot_a_end),
1379 image->data_len - slot_a_end, NULL)) {
1380 fprintf(stderr, "\nERROR: RO_B header is invalid\n");
1381 return false;
1382 }
1383 sections[RO_B].offset = slot_a_end;
1384 sections[RO_B].size =
1385 get_size_from_header(as_header(image, slot_a_end));
1386
1387 /* Find RW_B */
1388 rw_offset = find_rw_header(image,
1389 sections[RO_B].offset + sections[RO_B].size,
1390 image->data_len);
1391 if (rw_offset == -1) {
1392 fprintf(stderr, "\nERROR: RW_B header cannot be found\n");
1393 return false;
1394 }
1395 sections[RW_B].offset = rw_offset;
1396 sections[RW_B].size = get_size_from_header(as_header(image, rw_offset));
1397
1398 /* We found all of the headers and updated offset/size in sections */
1399 return true;
1400 }
1401
1402 /*
1403 * Scan the new image and retrieve versions of all four sections, two RO and
1404 * two RW, verifying that image size is not too short along the way.
1405 */
fetch_header_versions(struct image * image)1406 static bool fetch_header_versions(struct image *image)
1407 {
1408 size_t i;
1409 struct section_t *const sections = image->sections;
1410
1411 for (i = 0; i < NUM_SECTIONS; i++) {
1412 const struct typed_image_header h =
1413 as_header(image, sections[i].offset);
1414
1415 if (get_size_from_header(h) < CONFIG_FLASH_BANK_SIZE) {
1416 /*
1417 * Return an error for incorrectly signed images. If
1418 * it's a RO image with 0 as its size, ignore the error.
1419 *
1420 * TODO(b/273510573): revisit after dbg versioning is
1421 * figured out.
1422 */
1423 if (get_size_from_header(h) || sections[i].offset) {
1424 fprintf(stderr,
1425 "Image at offset %#5x too short "
1426 "(%d bytes)\n",
1427 sections[i].offset, h.h->image_size);
1428 return false;
1429 }
1430
1431 printf("warning: invalid RO_A (size 0)\n");
1432 }
1433 if (h.type == GSC_DEVICE_H1 || h.type == GSC_DEVICE_DT) {
1434 sections[i].shv.epoch = h.h->epoch_;
1435 sections[i].shv.major = h.h->major_;
1436 sections[i].shv.minor = h.h->minor_;
1437 sections[i].keyid = h.h->keyid;
1438 } else if (h.type == GSC_DEVICE_NT) {
1439 sections[i].shv.epoch = h.m->security_version;
1440 sections[i].shv.major = h.m->version_major;
1441 sections[i].shv.minor = h.m->version_minor;
1442 sections[i].keyid = 0;
1443 } else {
1444 fprintf(stderr, "\nERROR: Unknown image type.\n");
1445 exit(update_error);
1446 }
1447 }
1448 return true;
1449 }
1450
1451 /* Compare to signer headers and determine which one is newer. */
a_newer_than_b(const struct signed_header_version * a,const struct signed_header_version * b)1452 static int a_newer_than_b(const struct signed_header_version *a,
1453 const struct signed_header_version *b)
1454 {
1455 uint32_t fields[][3] = {
1456 { a->epoch, a->major, a->minor },
1457 { b->epoch, b->major, b->minor },
1458 };
1459 size_t i;
1460
1461 for (i = 0; i < ARRAY_SIZE(fields[0]); i++) {
1462 uint32_t a_value;
1463 uint32_t b_value;
1464
1465 a_value = fields[0][i];
1466 b_value = fields[1][i];
1467
1468 /*
1469 * Let's filter out images where the section is not
1470 * initialized and the version field value is set to all ones.
1471 */
1472 if (a_value == 0xffffffff)
1473 a_value = 0;
1474
1475 if (b_value == 0xffffffff)
1476 b_value = 0;
1477
1478 if (a_value != b_value)
1479 return a_value > b_value;
1480 }
1481
1482 return 0; /* All else being equal A is no newer than B. */
1483 }
1484
1485 /*
1486 * Pick sections to transfer based on information retrieved from the target,
1487 * the new image, and the protocol version the target is running.
1488 */
pick_sections(struct transfer_descriptor * td,struct image * image)1489 static void pick_sections(struct transfer_descriptor *td, struct image *image)
1490 {
1491 size_t i;
1492 struct section_t *sections = image->sections;
1493
1494 for (i = 0; i < NUM_SECTIONS; i++) {
1495 uint32_t offset = sections[i].offset;
1496
1497 if ((i == RW_A) || (i == RW_B)) {
1498 /* Skip currently active RW section. */
1499 bool active_rw_slot_b = td->rw_offset <
1500 sections[RO_B].offset;
1501 if ((i == RW_B) == active_rw_slot_b)
1502 continue;
1503 /*
1504 * Ok, this would be the RW section to transfer to the
1505 * device. Is it newer in the new image than the
1506 * running RW section on the device?
1507 *
1508 * If not in 'upstart' mode - transfer even if
1509 * versions are the same, timestamps could be
1510 * different.
1511 */
1512
1513 if (a_newer_than_b(§ions[i].shv, &targ.shv[1]) ||
1514 !td->upstart_mode) {
1515 sections[i].update_needed = true;
1516 }
1517 /* Rest of loop is RO */
1518 continue;
1519 }
1520
1521 /* Skip currently active RO section. */
1522 if (offset != td->ro_offset)
1523 continue;
1524 /*
1525 * Ok, this would be the RO section to transfer to the device.
1526 * Is it newer in the new image than the running RO section on
1527 * the device?
1528 */
1529 if (a_newer_than_b(§ions[i].shv, &targ.shv[0]) ||
1530 td->force_ro)
1531 sections[i].update_needed = true;
1532 }
1533 }
1534
1535 /*
1536 * Indicate to the target that update image transfer has been completed. Upon
1537 * receiving of this message the target state machine transitions into the
1538 * 'rx_idle' state. The host may send an extension command to reset the target
1539 * after this.
1540 */
send_done(struct usb_endpoint * uep)1541 static void send_done(struct usb_endpoint *uep)
1542 {
1543 uint32_t out;
1544
1545 /* Send stop request, ignoring reply. */
1546 out = htobe32(UPGRADE_DONE);
1547 do_xfer(uep, &out, sizeof(out), &out, 1, 0, NULL);
1548 }
1549
1550 /*
1551 * Gets and caches the GSC version information from the currently connected
1552 * device.
1553 */
get_version(struct transfer_descriptor * td,bool leave_pending)1554 static void get_version(struct transfer_descriptor *td, bool leave_pending)
1555 {
1556 size_t rxed_size;
1557 size_t i;
1558 uint32_t error_code;
1559
1560 /*
1561 * Need to be backwards compatible, communicate with targets running
1562 * different protocol versions.
1563 */
1564 union {
1565 struct first_response_pdu rpdu;
1566 uint32_t legacy_resp;
1567 } start_resp;
1568
1569 if (td->ep_type == usb_xfer) {
1570 struct update_pdu updu;
1571
1572 memset(&updu, 0, sizeof(updu));
1573 updu.block_size = htobe32(sizeof(updu));
1574 do_xfer(&td->uep, &updu, sizeof(updu), &start_resp,
1575 sizeof(start_resp), 1, &rxed_size);
1576 } else {
1577 rxed_size = sizeof(start_resp);
1578 if (tpm_send_pkt(td, 0, 0, NULL, 0, &start_resp, &rxed_size,
1579 EXTENSION_FW_UPGRADE) < 0) {
1580 fprintf(stderr, "Failed to start transfer\n");
1581 exit(update_error);
1582 }
1583 }
1584
1585 /* We got something. Check for errors in response */
1586 if (rxed_size < 8) {
1587 fprintf(stderr, "Unexpected response size %zd: ", rxed_size);
1588 for (i = 0; i < rxed_size; i++)
1589 fprintf(stderr, " %02x", ((uint8_t *)&start_resp)[i]);
1590 fprintf(stderr, "\n");
1591 exit(update_error);
1592 }
1593
1594 protocol_version = be32toh(start_resp.rpdu.protocol_version);
1595 if (protocol_version < 5) {
1596 fprintf(stderr, "Unsupported protocol version %d\n",
1597 protocol_version);
1598 exit(update_error);
1599 }
1600
1601 error_code = be32toh(start_resp.rpdu.return_value);
1602
1603 if (error_code) {
1604 fprintf(stderr, "Target reporting error %d\n", error_code);
1605 if (td->ep_type == usb_xfer)
1606 shut_down(&td->uep);
1607 exit(update_error);
1608 }
1609
1610 td->rw_offset = be32toh(start_resp.rpdu.backup_rw_offset);
1611 td->ro_offset = be32toh(start_resp.rpdu.backup_ro_offset);
1612
1613 /* Running header versions. */
1614 for (i = 0; i < ARRAY_SIZE(targ.shv); i++) {
1615 targ.shv[i].minor = be32toh(start_resp.rpdu.shv[i].minor);
1616 targ.shv[i].major = be32toh(start_resp.rpdu.shv[i].major);
1617 targ.shv[i].epoch = be32toh(start_resp.rpdu.shv[i].epoch);
1618 }
1619
1620 for (i = 0; i < ARRAY_SIZE(targ.keyid); i++)
1621 targ.keyid[i] = be32toh(start_resp.rpdu.keyid[i]);
1622
1623 if (!leave_pending && td->ep_type == usb_xfer)
1624 send_done(&td->uep);
1625 }
1626
setup_connection(struct transfer_descriptor * td)1627 static void setup_connection(struct transfer_descriptor *td)
1628 {
1629 /* Send start request. */
1630 printf("start\n");
1631
1632 get_version(td, true);
1633
1634 printf("keyids: RO 0x%08x, RW 0x%08x\n", targ.keyid[0], targ.keyid[1]);
1635 printf("offsets: backup RO at %#x, backup RW at %#x\n", td->ro_offset,
1636 td->rw_offset);
1637 }
1638
1639 /*
1640 * Channel TPM extension/vendor command over USB. The payload of the USB frame
1641 * in this case consists of the 2 byte subcommand code concatenated with the
1642 * command body. The caller needs to indicate if a response is expected, and
1643 * if it is - of what maximum size.
1644 */
ext_cmd_over_usb(struct usb_endpoint * uep,uint16_t subcommand,const void * cmd_body,size_t body_size,void * resp,size_t * resp_size)1645 static int ext_cmd_over_usb(struct usb_endpoint *uep, uint16_t subcommand,
1646 const void *cmd_body, size_t body_size, void *resp,
1647 size_t *resp_size)
1648 {
1649 struct update_frame_header *ufh;
1650 uint16_t *frame_ptr;
1651 size_t usb_msg_size;
1652 EVP_MD_CTX *ctx;
1653
1654 usb_msg_size = sizeof(struct update_frame_header) + sizeof(subcommand) +
1655 body_size;
1656
1657 ufh = malloc(usb_msg_size);
1658 if (!ufh) {
1659 fprintf(stderr, "%s: failed to allocate %zd bytes\n", __func__,
1660 usb_msg_size);
1661 return -1;
1662 }
1663
1664 ufh->block_size = htobe32(usb_msg_size);
1665 ufh->cmd.block_base = htobe32(CONFIG_EXTENSION_COMMAND);
1666 frame_ptr = (uint16_t *)(ufh + 1);
1667 *frame_ptr = htobe16(subcommand);
1668
1669 if (body_size)
1670 memcpy(frame_ptr + 1, cmd_body, body_size);
1671
1672 /* Calculate the digest. */
1673 ctx = EVP_MD_CTX_new();
1674 sha_init(ctx);
1675 sha_update(ctx, &ufh->cmd.block_base,
1676 usb_msg_size - offsetof(struct update_frame_header,
1677 cmd.block_base));
1678 sha_final_into_block_digest(ctx, &ufh->cmd.block_digest,
1679 sizeof(ufh->cmd.block_digest));
1680 EVP_MD_CTX_free(ctx);
1681
1682 do_xfer(uep, ufh, usb_msg_size, resp, resp_size ? *resp_size : 0, 1,
1683 resp_size);
1684
1685 free(ufh);
1686 return 0;
1687 }
1688
1689 /*
1690 * Old cr50 images fail the update if sections are sent out of order. They
1691 * require each block to have an offset greater than the block that was sent
1692 * before. RO has a lower offset than RW, so old cr50 images reject RO if it's
1693 * sent right after RW.
1694 * This offset restriction expires after 60 seconds. Delay the RO update long
1695 * enough for cr50 to not care that it has a lower offset than RW.
1696 *
1697 * Make the delay 65 seconds instead of 60 to cover differences in the speed of
1698 * H1's clock and the host clock.
1699 */
1700 #define NEXT_SECTION_DELAY 65
1701
1702 /*
1703 * H1 support for flashing RO immediately after RW added in 0.3.20/0.4.20.
1704 * D2 support exists in all versions.
1705 * NT support exists in all versions.
1706 */
supports_reordered_section_updates(struct signed_header_version * rw)1707 static int supports_reordered_section_updates(struct signed_header_version *rw)
1708 {
1709 switch (gsc_dev) {
1710 case GSC_DEVICE_H1:
1711 return (rw->epoch || rw->major > 4 ||
1712 (rw->major >= 3 && rw->minor >= 20));
1713 case GSC_DEVICE_DT:
1714 return true;
1715 case GSC_DEVICE_NT:
1716 return true;
1717 default:
1718 return false;
1719 }
1720 }
1721
1722 /* Returns number of successfully transmitted image sections. */
transfer_image(struct transfer_descriptor * td,struct image * image)1723 static int transfer_image(struct transfer_descriptor *td, struct image *image)
1724 {
1725 size_t i;
1726 int num_txed_sections = 0;
1727 int needs_delay = !supports_reordered_section_updates(&targ.shv[1]);
1728 struct section_t *sections = image->sections;
1729
1730 /*
1731 * In case both RO and RW updates are required, make sure the RW
1732 * section is updated before the RO. The array below keeps sections
1733 * offsets in the required order.
1734 */
1735 const enum section update_order[] = { RW_A, RW_B, RO_A, RO_B };
1736
1737 /* Now that we have an active connection and an image, pick sections */
1738 pick_sections(td, image);
1739 for (i = 0; i < ARRAY_SIZE(update_order); i++) {
1740 const enum section sect = update_order[i];
1741
1742 if (!sections[sect].update_needed)
1743 continue;
1744 if (num_txed_sections && needs_delay) {
1745 /*
1746 * Delays more than 5 seconds cause the update
1747 * to timeout. End the update before the delay
1748 * and set it up after to recover from the
1749 * timeout.
1750 */
1751 if (td->ep_type == usb_xfer)
1752 send_done(&td->uep);
1753 printf("Waiting %ds for %s update.\n",
1754 NEXT_SECTION_DELAY, SECTION_NAMES[sect]);
1755 sleep(NEXT_SECTION_DELAY);
1756 setup_connection(td);
1757 /* Pick sections again in case GSC versions changed. */
1758 pick_sections(td, image);
1759 }
1760
1761 transfer_section(td, image->data + sections[sect].offset,
1762 sections[sect].offset, sections[sect].size);
1763 num_txed_sections++;
1764 }
1765
1766 if (!num_txed_sections)
1767 printf("nothing to do\n");
1768 else
1769 printf("-------\nupdate complete\n");
1770 return num_txed_sections;
1771 }
1772
send_vendor_command(struct transfer_descriptor * td,uint16_t subcommand,const void * command_body,size_t command_body_size,void * response,size_t * response_size)1773 uint32_t send_vendor_command(struct transfer_descriptor *td,
1774 uint16_t subcommand, const void *command_body,
1775 size_t command_body_size, void *response,
1776 size_t *response_size)
1777 {
1778 int32_t rv;
1779
1780 if (td->ep_type == usb_xfer) {
1781 /*
1782 * When communicating over USB the response is always supposed
1783 * to have the result code in the first byte of the response,
1784 * to be stripped from the actual response body by this
1785 * function.
1786 */
1787 uint8_t temp_response[MAX_RX_BUF_SIZE];
1788 size_t max_response_size;
1789
1790 if (!response_size) {
1791 max_response_size = 1;
1792 } else if (*response_size < (sizeof(temp_response))) {
1793 max_response_size = *response_size + 1;
1794 } else {
1795 fprintf(stderr,
1796 "Error: Expected response too large (%zd)\n",
1797 *response_size);
1798 /* Should happen only when debugging. */
1799 exit(update_error);
1800 }
1801
1802 ext_cmd_over_usb(&td->uep, subcommand, command_body,
1803 command_body_size, temp_response,
1804 &max_response_size);
1805 if (!max_response_size) {
1806 /*
1807 * we must be talking to an older Cr50 firmware, which
1808 * does not return the result code in the first byte
1809 * on success, nothing to do.
1810 */
1811 if (response_size)
1812 *response_size = 0;
1813 rv = 0;
1814 } else {
1815 rv = temp_response[0];
1816 if (response_size) {
1817 *response_size = max_response_size - 1;
1818 memcpy(response, temp_response + 1,
1819 *response_size);
1820 }
1821 }
1822 } else {
1823 rv = tpm_send_pkt(td, 0, 0, command_body, command_body_size,
1824 response, response_size, subcommand);
1825
1826 if (rv == -1) {
1827 fprintf(stderr,
1828 "Error: Failed to send vendor command %d\n",
1829 subcommand);
1830 exit(update_error);
1831 }
1832 }
1833
1834 return rv; /* This will be converted into uint32_t */
1835 }
1836
1837 /*
1838 * Corrupt the header of the inactive rw image to make sure the system can't
1839 * rollback
1840 */
invalidate_inactive_rw(struct transfer_descriptor * td)1841 static void invalidate_inactive_rw(struct transfer_descriptor *td)
1842 {
1843 /* Corrupt the rw image that is not running. */
1844 uint32_t rv;
1845
1846 rv = send_vendor_command(td, VENDOR_CC_INVALIDATE_INACTIVE_RW, NULL, 0,
1847 NULL, NULL);
1848 if (!rv) {
1849 printf("Inactive header invalidated\n");
1850 return;
1851 }
1852
1853 fprintf(stderr, "*%s: Error %#x\n", __func__, rv);
1854 exit(update_error);
1855 }
1856
1857 /*
1858 * Try setting CCD capability.
1859 *
1860 * The 'parameter' string includes capability and desired new state separated
1861 * by a ':', both parts could be abbreviated and checked for the match as case
1862 * insensitive.
1863 *
1864 * The result of the attempt depends on the policies installed on
1865 * Ti50. The result could be on of the following:
1866 *
1867 * - success (capability is successfully changed, or is already at the
1868 * requested level),
1869 * - various errors if setting the capability is not allowed or something
1870 * goes wrong on Ti50
1871 * - request for physical presence confirmation
1872 */
process_set_capabililty(struct transfer_descriptor * td,const char * parameter)1873 static enum exit_values process_set_capabililty(struct transfer_descriptor *td,
1874 const char *parameter)
1875 {
1876 const char *colon;
1877 size_t len;
1878 size_t cap_index;
1879 size_t i;
1880 uint8_t rc;
1881 const char *error_text;
1882 const char *cr50_err =
1883 "Note: setting capabilities not available on Cr50\n";
1884 /*
1885 * The payload is three bytes, command version, capability, and
1886 * desired state, all expressed as u8.
1887 */
1888 struct __attribute__((__packed__)) {
1889 uint8_t version;
1890 uint8_t cap;
1891 uint8_t value;
1892 } command;
1893 /*
1894 * Translation table of possible desired capabilities, Cr50 values
1895 * and duplicated in common/syscalls/src/ccd.rs::CcdCapState.
1896 */
1897 struct {
1898 const char *state_name;
1899 enum ccd_capability_state desired_state;
1900 } states[] = {
1901 { "default", CCD_CAP_STATE_DEFAULT },
1902 { "always", CCD_CAP_STATE_ALWAYS },
1903 { "if_opened", CCD_CAP_STATE_IF_OPENED },
1904 };
1905
1906 /*
1907 * Possible responses from Ti50 when trying to modify AllowUnverifiedRo
1908 * capability. The values come from
1909 * common/libs/tpm2/extension/src/lib.rs::TpmvReturnCode.
1910 */
1911 enum set_allow_unverified_ro_responses {
1912 AUR_SUCCESS = 0,
1913 AUR_BOGUS_ARGS = 1,
1914 AUR_INTERNAL_ERROR = 6,
1915 AUR_NOT_ALLOWED = 7,
1916 AUR_IN_PROGRESS = 9,
1917 };
1918
1919 /*
1920 * Validate the parameter, for starters make sure that the colon
1921 * symbol is present and is neither the first nor the last character
1922 * in the string.
1923 */
1924 colon = strchr(parameter, ':');
1925 if (!colon || (colon == parameter) || (colon[1] == '\0')) {
1926 fprintf(stderr, "Misformatted capability parameter: %s\n",
1927 parameter);
1928 exit(update_error);
1929 }
1930
1931 /*
1932 * Find the capability index in the table, reject ambiguous
1933 * abbreviations.
1934 */
1935 len = colon - parameter;
1936 for (i = 0, cap_index = ARRAY_SIZE(ti50_cap_info);
1937 i < ARRAY_SIZE(ti50_cap_info); i++) {
1938 if (!strncasecmp(ti50_cap_info[i].name, parameter, len)) {
1939 if (cap_index != ARRAY_SIZE(ti50_cap_info)) {
1940 fprintf(stderr, "Ambiguous capability name\n");
1941 exit(update_error);
1942 }
1943 cap_index = i;
1944 }
1945 }
1946 if (cap_index == ARRAY_SIZE(ti50_cap_info)) {
1947 fprintf(stderr, "Unknown capability name\n%s", cr50_err);
1948 exit(update_error);
1949 }
1950
1951 /* Calculate length of the desired value. */
1952 len = strlen(parameter) - len - 1;
1953
1954 /* Find the value index in the table. */
1955 for (i = 0; i < ARRAY_SIZE(states); i++) {
1956 if (!strncasecmp(states[i].state_name, colon + 1, len))
1957 break;
1958 }
1959 if (i == ARRAY_SIZE(states)) {
1960 fprintf(stderr, "Unsupported capability value\n");
1961 return update_error;
1962 }
1963
1964 /* Prepare and send vendor command to request setting capability. */
1965 command.version = CCD_VERSION;
1966 command.cap = (uint8_t)cap_index;
1967 command.value = (uint8_t)states[i].desired_state;
1968
1969 i = 0;
1970 len = 1;
1971 send_vendor_command(td, VENDOR_CC_SET_CAPABILITY, &command,
1972 sizeof(command), &rc, &len);
1973
1974 if (len != 1) {
1975 fprintf(stderr, "Unexpected return message size %zd\n", len);
1976 if (len == 0)
1977 fprintf(stderr, "%s", cr50_err);
1978 return update_error;
1979 }
1980
1981 switch (rc) {
1982 case AUR_IN_PROGRESS:
1983 /*
1984 * Physical presence poll is required, note fall through to
1985 * the next case.
1986 */
1987 poll_for_pp(td, VENDOR_CC_CCD, CCDV_PP_POLL_SET_CAPABILITY);
1988 case AUR_SUCCESS:
1989 return noop; /* All is well, no need to do anything. */
1990 case AUR_BOGUS_ARGS:
1991 error_text = "BogusArgs";
1992 break;
1993 case AUR_INTERNAL_ERROR:
1994 error_text = "InternalError";
1995 break;
1996 case AUR_NOT_ALLOWED:
1997 error_text = "NotAllowed";
1998 break;
1999 default:
2000 error_text = "Unknown";
2001 break;
2002 }
2003 fprintf(stderr, "Got error %d(%s)\n", rc, error_text);
2004 return update_error;
2005 }
2006
process_erase_ap_ro_hash(struct transfer_descriptor * td)2007 static void process_erase_ap_ro_hash(struct transfer_descriptor *td)
2008 {
2009 /* Try erasing AP RO hash, could fail if board ID is programmed. */
2010 uint32_t rv;
2011 uint8_t response;
2012 size_t response_size;
2013 char error_details[64];
2014
2015 response_size = sizeof(response);
2016 rv = send_vendor_command(td, VENDOR_CC_SEED_AP_RO_CHECK, NULL, 0,
2017 &response, &response_size);
2018 if (!rv) {
2019 printf("AP RO hash erased\n");
2020 exit(0);
2021 }
2022
2023 if (response_size == sizeof(response)) {
2024 switch (response) {
2025 case ARCVE_FLASH_ERASE_FAILED:
2026 snprintf(error_details, sizeof(error_details),
2027 "erase failure");
2028 break;
2029 case ARCVE_BID_PROGRAMMED:
2030 snprintf(error_details, sizeof(error_details),
2031 "BID already programmed");
2032 break;
2033 default:
2034 snprintf(error_details, sizeof(error_details),
2035 "Unexpected error rc %d, response %d", rv,
2036 response);
2037 break;
2038 }
2039 } else {
2040 snprintf(error_details, sizeof(error_details),
2041 "misconfigured response, rc=%d, size %zd", rv,
2042 response_size);
2043 }
2044
2045 fprintf(stderr, "Error: %s\n", error_details);
2046
2047 exit(update_error);
2048 }
2049
generate_reset_request(struct transfer_descriptor * td)2050 static void generate_reset_request(struct transfer_descriptor *td)
2051 {
2052 size_t response_size;
2053 uint8_t response;
2054 uint16_t subcommand;
2055 uint8_t command_body[2]; /* Max command body size. */
2056 size_t command_body_size;
2057 const char *reset_type;
2058 int rv;
2059
2060 if (protocol_version < 6) {
2061 if (td->ep_type == usb_xfer) {
2062 /*
2063 * Send a second stop request, which should reboot
2064 * without replying.
2065 */
2066 send_done(&td->uep);
2067 }
2068 /* Nothing we can do over /dev/tpm0 running versions below 6. */
2069 return;
2070 }
2071
2072 /*
2073 * If this is an upstart request, don't post a request now. The target
2074 * should handle it on the next reboot.
2075 */
2076 if (td->upstart_mode)
2077 return;
2078
2079 /*
2080 * If the user explicitly wants it, request post reset instead of
2081 * immediate reset. In this case next time the target reboots, the GSC
2082 * will reboot as well, and will consider running the uploaded code.
2083 *
2084 * Otherwise, to reset the target the host is supposed to send the
2085 * command to enable the uploaded image disabled by default.
2086 */
2087 response_size = 1;
2088 if (td->post_reset) {
2089 subcommand = EXTENSION_POST_RESET;
2090 command_body_size = 0;
2091 reset_type = "posted";
2092 } else {
2093 subcommand = VENDOR_CC_TURN_UPDATE_ON;
2094 command_body_size = sizeof(command_body);
2095 command_body[0] = 0;
2096 command_body[1] = 100; /* Reset in 100 ms. */
2097 reset_type = "requested";
2098 }
2099
2100 rv = send_vendor_command(td, subcommand, command_body,
2101 command_body_size, &response, &response_size);
2102
2103 if (rv) {
2104 fprintf(stderr, "*%s: Error %#x\n", __func__, rv);
2105 exit(update_error);
2106 }
2107 printf("reboot %s\n", reset_type);
2108 }
2109
2110 /* Forward to correct SHA implementation based on image type */
sha_init(EVP_MD_CTX * ctx)2111 static void sha_init(EVP_MD_CTX *ctx)
2112 {
2113 if (gsc_dev == GSC_DEVICE_H1)
2114 EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
2115 else if (gsc_dev == GSC_DEVICE_DT || gsc_dev == GSC_DEVICE_NT)
2116 EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
2117 else {
2118 fprintf(stderr, "Error: unknown GSC device type\n");
2119 exit(update_error);
2120 }
2121 }
2122
2123 /* Forward to correct SHA implementation based on image type */
sha_update(EVP_MD_CTX * ctx,const void * data,size_t len)2124 static void sha_update(EVP_MD_CTX *ctx, const void *data, size_t len)
2125 {
2126 EVP_DigestUpdate(ctx, data, len);
2127 }
2128
2129 /* Forward to correct SHA implementation based on image type */
sha_final_into_block_digest(EVP_MD_CTX * ctx,void * block_digest,size_t size)2130 static void sha_final_into_block_digest(EVP_MD_CTX *ctx, void *block_digest,
2131 size_t size)
2132 {
2133 /* Big enough for either hash algo */
2134 uint8_t full_digest[SHA256_DIGEST_LENGTH];
2135 unsigned int length;
2136
2137 EVP_DigestFinal(ctx, full_digest, &length);
2138
2139 /* Copy out the smaller of the 2 byte counts. */
2140 memcpy(block_digest, full_digest, MIN(size, length));
2141 }
2142
2143 /*
2144 * Machine output is formatted as "key=value", one key-value pair per line, and
2145 * parsed by other programs (e.g., debugd). The value part should be specified
2146 * in the printf-like way. For example:
2147 *
2148 * print_machine_output("date", "%d/%d/%d", 2018, 1, 1),
2149 *
2150 * which outputs this line in console:
2151 *
2152 * date=2018/1/1
2153 *
2154 * The key part should not contain '=' or newline. The value part may contain
2155 * special characters like spaces, quotes, brackets, but not newlines. The
2156 * newline character means end of value.
2157 *
2158 * Any output format change in this function may require similar changes on the
2159 * programs that are using this gsctool.
2160 */
print_machine_output(const char * key,const char * format,...)2161 __attribute__((__format__(__printf__, 2, 3))) static void print_machine_output(
2162 const char *key, const char *format, ...)
2163 {
2164 va_list args;
2165
2166 if (strchr(key, '=') != NULL || strchr(key, '\n') != NULL) {
2167 fprintf(stderr,
2168 "Error: key %s contains '=' or a newline character.\n",
2169 key);
2170 return;
2171 }
2172
2173 if (strchr(format, '\n') != NULL) {
2174 fprintf(stderr,
2175 "Error: value format %s contains a newline character. "
2176 "\n",
2177 format);
2178 return;
2179 }
2180
2181 va_start(args, format);
2182
2183 printf("%s=", key);
2184 vprintf(format, args);
2185 printf("\n");
2186
2187 va_end(args);
2188 }
2189
2190 /*
2191 * Prints out the header, including FW versions and board IDs, of the given
2192 * image. Output in a machine-friendly format if show_machine_output is true.
2193 */
show_headers_versions(const struct image * image,bool show_machine_output)2194 static int show_headers_versions(const struct image *image,
2195 bool show_machine_output)
2196 {
2197 /*
2198 * There are 2 FW slots in an image, and each slot has 2 sections, RO
2199 * and RW. The 2 slots should have identical FW versions and board
2200 * IDs.
2201 */
2202 const size_t kNumSlots = 2;
2203 const size_t kNumSectionsPerSlot = 2;
2204 const struct section_t *sections = image->sections;
2205
2206 /*
2207 * String representation of FW version (<epoch>:<major>:<minor>), one
2208 * string for each FW section.
2209 */
2210 char ro_fw_ver[kNumSlots][MAX_FW_VER_LENGTH];
2211 char rw_fw_ver[kNumSlots][MAX_FW_VER_LENGTH];
2212
2213 uint32_t dev_id0_[kNumSlots];
2214 uint32_t dev_id1_[kNumSlots];
2215 uint32_t print_devid = 0;
2216
2217 struct board_id {
2218 uint32_t id;
2219 uint32_t mask;
2220 uint32_t flags;
2221 } bid[kNumSlots];
2222
2223 char bid_string[kNumSlots][MAX_BOARD_ID_LENGTH];
2224
2225 size_t i;
2226
2227 for (i = 0; i < NUM_SECTIONS; i++) {
2228 const struct typed_image_header h =
2229 as_header(image, sections[i].offset);
2230 const size_t slot_idx = i / kNumSectionsPerSlot;
2231
2232 uint32_t cur_bid;
2233 size_t j;
2234
2235 if (i == RO_A || i == RO_B) {
2236 /* RO. */
2237 snprintf(ro_fw_ver[slot_idx], MAX_FW_VER_LENGTH,
2238 "%d.%d.%d", sections[i].shv.epoch,
2239 sections[i].shv.major, sections[i].shv.minor);
2240 /* No need to read board ID in an RO section. */
2241 continue;
2242 } else {
2243 /* RW. */
2244 snprintf(rw_fw_ver[slot_idx], MAX_FW_VER_LENGTH,
2245 "%d.%d.%d", sections[i].shv.epoch,
2246 sections[i].shv.major, sections[i].shv.minor);
2247 }
2248
2249 /*
2250 * For RW sections, retrieves the board ID fields' contents,
2251 * which are stored XORed with a padding value.
2252 */
2253 if (h.type == GSC_DEVICE_H1 || h.type == GSC_DEVICE_DT) {
2254 bid[slot_idx].id = h.h->board_id_type ^
2255 SIGNED_HEADER_PADDING;
2256 bid[slot_idx].mask = h.h->board_id_type_mask ^
2257 SIGNED_HEADER_PADDING;
2258 bid[slot_idx].flags = h.h->board_id_flags ^
2259 SIGNED_HEADER_PADDING;
2260
2261 dev_id0_[slot_idx] = h.h->dev_id0_;
2262 dev_id1_[slot_idx] = h.h->dev_id1_;
2263 } else if (h.type == GSC_DEVICE_NT) {
2264 /*
2265 * TODO(b/341348812): Get BID info from signed manifest
2266 * header.
2267 */
2268 fprintf(stderr, "BID info not support on NT yet.\n");
2269 bid[slot_idx].id = -1;
2270 bid[slot_idx].mask = -1;
2271 bid[slot_idx].flags = -1;
2272
2273 /* Check if devid constraints are being enforced */
2274 if (h.m->constraint_selector_bits & 0x6) {
2275 dev_id0_[slot_idx] =
2276 h.m->constraint_device_id[1];
2277 dev_id1_[slot_idx] =
2278 h.m->constraint_device_id[2];
2279 } else {
2280 dev_id0_[slot_idx] = 0;
2281 dev_id1_[slot_idx] = 0;
2282 }
2283 } else {
2284 fprintf(stderr, "\nERROR: Unknown image type.\n");
2285 exit(update_error);
2286 }
2287 /* Print the devid if any slot has a non-zero devid. */
2288 print_devid |= dev_id0_[slot_idx] | dev_id1_[slot_idx];
2289 /*
2290 * If board ID is a 4-uppercase-letter string (as it ought to
2291 * be), print it as 4 letters, otherwise print it as an 8-digit
2292 * hex.
2293 */
2294 cur_bid = bid[slot_idx].id;
2295 for (j = 0; j < sizeof(cur_bid); ++j)
2296 if (!isupper(((const char *)&cur_bid)[j]))
2297 break;
2298
2299 if (j == sizeof(cur_bid)) {
2300 cur_bid = be32toh(cur_bid);
2301 snprintf(bid_string[slot_idx], MAX_BOARD_ID_LENGTH,
2302 "%.4s", (const char *)&cur_bid);
2303 } else {
2304 snprintf(bid_string[slot_idx], MAX_BOARD_ID_LENGTH,
2305 "%08x", cur_bid);
2306 }
2307 }
2308
2309 if (show_machine_output) {
2310 print_machine_output("IMAGE_RO_FW_VER", "%s", ro_fw_ver[0]);
2311 print_machine_output("IMAGE_RW_FW_VER", "%s", rw_fw_ver[0]);
2312 print_machine_output("IMAGE_BID_STRING", "%s", bid_string[0]);
2313 print_machine_output("IMAGE_BID_MASK", "%08x", bid[0].mask);
2314 print_machine_output("IMAGE_BID_FLAGS", "%08x", bid[0].flags);
2315 } else {
2316 printf("RO_A:%s RW_A:%s[%s:%08x:%08x] ", ro_fw_ver[0],
2317 rw_fw_ver[0], bid_string[0], bid[0].mask, bid[0].flags);
2318 printf("RO_B:%s RW_B:%s[%s:%08x:%08x]\n", ro_fw_ver[1],
2319 rw_fw_ver[1], bid_string[1], bid[1].mask, bid[1].flags);
2320
2321 if (print_devid) {
2322 printf("DEVID: 0x%08x 0x%08x", dev_id0_[0],
2323 dev_id1_[0]);
2324 /*
2325 * Only print the second devid if it's different.
2326 * Separate the devids with tabs, so it's easier to
2327 * read.
2328 */
2329 if (dev_id0_[0] != dev_id0_[1] ||
2330 dev_id1_[0] != dev_id1_[1])
2331 printf("\t\t\t\tDEVID_B: 0x%08x 0x%08x",
2332 dev_id0_[1], dev_id1_[1]);
2333 printf("\n");
2334 }
2335 }
2336
2337 return 0;
2338 }
2339
2340 /*
2341 * The default flag value will allow to run images built for any hardware
2342 * generation of a particular board ID.
2343 */
2344 #define DEFAULT_BOARD_ID_FLAG 0xff00
parse_bid(const char * opt,struct board_id * bid,enum board_id_action * bid_action)2345 static int parse_bid(const char *opt, struct board_id *bid,
2346 enum board_id_action *bid_action)
2347 {
2348 char *e;
2349 const char *param2;
2350 size_t param1_length;
2351
2352 if (!opt) {
2353 *bid_action = bid_get;
2354 return 1;
2355 }
2356
2357 /* Set it here to make bailing out easier later. */
2358 bid->flags = DEFAULT_BOARD_ID_FLAG;
2359
2360 *bid_action = bid_set; /* Ignored by caller on errors. */
2361
2362 /*
2363 * Pointer to the optional second component of the command line
2364 * parameter, when present - separated by a colon.
2365 */
2366 param2 = strchr(opt, ':');
2367 if (param2) {
2368 param1_length = param2 - opt;
2369 param2++;
2370 if (!*param2)
2371 return 0; /* Empty second parameter. */
2372 } else {
2373 param1_length = strlen(opt);
2374 }
2375
2376 if (!param1_length)
2377 return 0; /* Colon is the first character of the string? */
2378
2379 if (param1_length <= 4) {
2380 unsigned i;
2381
2382 /* Input must be a symbolic board name. */
2383 bid->type = 0;
2384 for (i = 0; i < param1_length; i++)
2385 bid->type = (bid->type << 8) | opt[i];
2386 } else {
2387 bid->type = (uint32_t)strtoul(opt, &e, 0);
2388 if ((param2 && (*e != ':')) || (!param2 && *e))
2389 return 0;
2390 }
2391
2392 if (param2) {
2393 bid->flags = (uint32_t)strtoul(param2, &e, 0);
2394 if (*e)
2395 return 0;
2396 }
2397
2398 return 1;
2399 }
2400
2401 /*
2402 * Reads a two-character hexadecimal byte from a string. If the string is
2403 * ill-formed, returns 0. Otherwise, |byte| contains the byte value and the
2404 * return value is non-zero.
2405 */
read_hex_byte(const char * s,uint8_t * byte)2406 static int read_hex_byte(const char *s, uint8_t *byte)
2407 {
2408 uint8_t b = 0;
2409 for (const char *end = s + 2; s < end; ++s) {
2410 if (*s >= '0' && *s <= '9')
2411 b = b * 16 + *s - '0';
2412 else if (*s >= 'A' && *s <= 'F')
2413 b = b * 16 + 10 + *s - 'A';
2414 else if (*s >= 'a' && *s <= 'f')
2415 b = b * 16 + 10 + *s - 'a';
2416 else
2417 return 0;
2418 }
2419 *byte = b;
2420 return 1;
2421 }
2422
parse_sn_bits(const char * opt,uint8_t * sn_bits)2423 static int parse_sn_bits(const char *opt, uint8_t *sn_bits)
2424 {
2425 size_t len = strlen(opt);
2426
2427 if (!strncmp(opt, "0x", 2)) {
2428 opt += 2;
2429 len -= 2;
2430 }
2431 if (len != SN_BITS_SIZE * 2)
2432 return 0;
2433
2434 for (int i = 0; i < SN_BITS_SIZE; ++i, opt += 2)
2435 if (!read_hex_byte(opt, sn_bits++))
2436 return 0;
2437
2438 return 1;
2439 }
2440
parse_sn_inc_rma(const char * opt,uint8_t * arg)2441 static int parse_sn_inc_rma(const char *opt, uint8_t *arg)
2442 {
2443 uint32_t inc;
2444 char *e;
2445
2446 inc = (uint32_t)strtoul(opt, &e, 0);
2447
2448 if (opt == e || *e != '\0' || inc > 7)
2449 return 0;
2450
2451 *arg = inc;
2452 return 1;
2453 }
2454
common_process_password(struct transfer_descriptor * td,enum ccd_vendor_subcommands subcmd)2455 static uint32_t common_process_password(struct transfer_descriptor *td,
2456 enum ccd_vendor_subcommands subcmd)
2457 {
2458 size_t response_size;
2459 uint8_t response;
2460 uint32_t rv;
2461 char *password = NULL;
2462 char *password_copy = NULL;
2463 ssize_t copy_len;
2464 ssize_t len;
2465 size_t zero = 0;
2466 struct termios oldattr, newattr;
2467
2468 /* Suppress command line echo while password is being entered. */
2469 tcgetattr(STDIN_FILENO, &oldattr);
2470 newattr = oldattr;
2471 newattr.c_lflag &= ~ECHO;
2472 newattr.c_lflag |= (ICANON | ECHONL);
2473 tcsetattr(STDIN_FILENO, TCSANOW, &newattr);
2474
2475 /* With command line echo suppressed request password entry twice. */
2476 printf("Enter password:");
2477 len = getline(&password, &zero, stdin);
2478 printf("Re-enter password:");
2479 zero = 0;
2480 copy_len = getline(&password_copy, &zero, stdin);
2481
2482 /* Restore command line echo. */
2483 tcsetattr(STDIN_FILENO, TCSANOW, &oldattr);
2484
2485 /* Empty password will still have the newline. */
2486 if ((len <= 1) || !password_copy || (copy_len != len)) {
2487 fprintf(stderr, "Error reading password\n");
2488 if (password)
2489 free(password);
2490 if (password_copy)
2491 free(password_copy);
2492 if ((copy_len >= 0) && (len >= 0) && (copy_len != len))
2493 fprintf(stderr, "Password length mismatch\n");
2494 exit(update_error);
2495 }
2496
2497 /* Compare the two inputs. */
2498 if (strcmp(password, password_copy)) {
2499 fprintf(stderr, "Entered passwords don't match\n");
2500 free(password);
2501 free(password_copy);
2502 exit(update_error);
2503 }
2504
2505 /*
2506 * Ok, we have a password, let's move it in the buffer to overwrite
2507 * the newline and free a byte to prepend the subcommand code.
2508 */
2509 memmove(password + 1, password, len - 1);
2510 password[0] = subcmd;
2511 response_size = sizeof(response);
2512 rv = send_vendor_command(td, VENDOR_CC_CCD, password, len, &response,
2513 &response_size);
2514 free(password);
2515 free(password_copy);
2516
2517 if ((rv != VENDOR_RC_SUCCESS) && (rv != VENDOR_RC_IN_PROGRESS))
2518 fprintf(stderr, "Error sending password: rv %d, response %d\n",
2519 rv, response_size ? response : 0);
2520
2521 return rv;
2522 }
2523
process_password(struct transfer_descriptor * td)2524 static void process_password(struct transfer_descriptor *td)
2525 {
2526 if (common_process_password(td, CCDV_PASSWORD) == VENDOR_RC_SUCCESS)
2527 return;
2528
2529 exit(update_error);
2530 }
2531
poll_for_pp(struct transfer_descriptor * td,uint16_t command,uint8_t poll_type)2532 void poll_for_pp(struct transfer_descriptor *td, uint16_t command,
2533 uint8_t poll_type)
2534 {
2535 uint8_t response;
2536 uint8_t prev_response;
2537 size_t response_size;
2538 int rv;
2539
2540 prev_response = ~0; /* Guaranteed invalid value. */
2541
2542 while (1) {
2543 response_size = sizeof(response);
2544 rv = send_vendor_command(td, command, &poll_type,
2545 sizeof(poll_type), &response,
2546 &response_size);
2547
2548 if (((rv != VENDOR_RC_SUCCESS) &&
2549 (rv != VENDOR_RC_IN_PROGRESS)) ||
2550 (response_size != 1)) {
2551 fprintf(stderr, "Error: rv %d, response %d\n", rv,
2552 response_size ? response : 0);
2553 exit(update_error);
2554 }
2555
2556 if (response == CCD_PP_DONE) {
2557 printf("PP Done!\n");
2558 return;
2559 }
2560
2561 if (response == CCD_PP_CLOSED) {
2562 fprintf(stderr,
2563 "Error: Physical presence check timeout!\n");
2564 exit(update_error);
2565 }
2566
2567 if (response == CCD_PP_AWAITING_PRESS) {
2568 printf("Press PP button now!\n");
2569 } else if (response == CCD_PP_BETWEEN_PRESSES) {
2570 if (prev_response != response)
2571 printf("Another press will be required!\n");
2572 } else {
2573 fprintf(stderr, "Error: unknown poll result %d\n",
2574 response);
2575 exit(update_error);
2576 }
2577 prev_response = response;
2578
2579 usleep(500 * 1000); /* Poll every half a second. */
2580 }
2581 }
2582
2583 /* Determine the longest capability name found in the passed in table. */
longest_cap_name_len(const struct ccd_capability_info * table,size_t count)2584 static size_t longest_cap_name_len(const struct ccd_capability_info *table,
2585 size_t count)
2586 {
2587 size_t i;
2588 size_t result = 0;
2589
2590 for (i = 0; i < count; i++) {
2591 size_t this_size;
2592
2593 this_size = strlen(table[i].name);
2594 if (this_size > result)
2595 result = this_size;
2596 }
2597 return result;
2598 }
2599
2600 /*
2601 * Print the passed in capability name padded to the longest length determined
2602 * earlier.
2603 */
print_aligned(const char * name,size_t field_size)2604 static void print_aligned(const char *name, size_t field_size)
2605 {
2606 size_t name_len;
2607
2608 name_len = strlen(name);
2609
2610 printf("%s", name);
2611 while (name_len < field_size) {
2612 printf(" ");
2613 name_len++;
2614 }
2615 }
2616
2617 /*
2618 * Translates "AnExampleTPMString" into "AN_EXAMPLE_TPM_STRING". Note that
2619 * output must be large enough to contain a 150%-sized string of input.
2620 */
to_upper_underscore(const char * input,char * output)2621 static void to_upper_underscore(const char *input, char *output)
2622 {
2623 bool first_char = true;
2624 bool needs_underscore = false;
2625
2626 while (*input != '\0') {
2627 *output = toupper(*input);
2628 /*
2629 * If we encounter an upper case char in the input, we may need
2630 * to add an underscore in the output before (re)writing the
2631 * output char
2632 */
2633 if (*output == *input) {
2634 /*
2635 * See if the next input letter is lower case, that
2636 * means this uppercase letter needs a '_' before it.
2637 */
2638 if (islower(*(input + 1)) && !first_char)
2639 needs_underscore = true;
2640 if (needs_underscore) {
2641 needs_underscore = false;
2642 *output++ = '_';
2643 *output = *input;
2644 }
2645 } else {
2646 /*
2647 * We encountered a lower case, so the next upper case
2648 * should have a '_' before it
2649 */
2650 needs_underscore = true;
2651 }
2652 first_char = false;
2653 input++;
2654 output++;
2655 }
2656 *output = '\0';
2657 }
2658
2659 /*
2660 * Ensure that the CCD info response is well formed otherwise exits. Upon return
2661 * the ccd_info variable will contain the structured ccd info response and the
2662 * return value is the version of ccd info to parse with (e.g. 0 for cr50 and
2663 * 1 for ti50).
2664 */
validate_into_ccd_info_response(void * response,size_t response_size,struct ccd_info_response * ccd_info)2665 static uint32_t validate_into_ccd_info_response(
2666 void *response, size_t response_size,
2667 struct ccd_info_response *ccd_info)
2668 {
2669 struct ccd_info_response_header ccd_info_header;
2670 size_t i;
2671 uint32_t ccd_info_version;
2672
2673 if (response_size < sizeof(ccd_info_header)) {
2674 fprintf(stderr, "CCD info response too short %zd\n",
2675 response_size);
2676 exit(update_error);
2677 }
2678
2679 /* Let's check if this is a newer version response. */
2680 memcpy(&ccd_info_header, response, sizeof(ccd_info_header));
2681 if ((ccd_info_header.ccd_magic == CCD_INFO_MAGIC) &&
2682 (ccd_info_header.ccd_size == response_size) &&
2683 /* Verify that payload size matches ccd_info size. */
2684 ((response_size - sizeof(ccd_info_header)) == sizeof(*ccd_info))) {
2685 ccd_info_version = ccd_info_header.ccd_version;
2686 memcpy(ccd_info,
2687 (uint8_t *)response +
2688 sizeof(struct ccd_info_response_header),
2689 sizeof(*ccd_info));
2690 /*
2691 * V1 CCD info structure uses little endian for transmission.
2692 * No need to update to host endianness since it is already LE.
2693 */
2694 } else if (response_size == CCD_INFO_V0_SIZE) {
2695 ccd_info_version = 0; /* Default, Cr50 case. */
2696 memcpy(ccd_info, response, sizeof(*ccd_info));
2697 /*
2698 * V0 CCD info structure uses big endian for transmission.
2699 * Update fields to host endianness.
2700 */
2701 ccd_info->ccd_flags = be32toh(ccd_info->ccd_flags);
2702 for (i = 0; i < ARRAY_SIZE(ccd_info->ccd_caps_current); i++) {
2703 ccd_info->ccd_caps_current[i] =
2704 be32toh(ccd_info->ccd_caps_current[i]);
2705 ccd_info->ccd_caps_defaults[i] =
2706 be32toh(ccd_info->ccd_caps_defaults[i]);
2707 }
2708 } else {
2709 fprintf(stderr, "Unexpected CCD info response size %zd\n",
2710 response_size);
2711 exit(update_error);
2712 }
2713
2714 return ccd_info_version;
2715 }
2716
print_ccd_info(void * response,size_t response_size,bool show_machine_output)2717 static void print_ccd_info(void *response, size_t response_size,
2718 bool show_machine_output)
2719 {
2720 struct ccd_info_response ccd_info;
2721 size_t i;
2722 const struct ccd_capability_info cr50_cap_info[] = CAP_INFO_DATA;
2723 const char *state_names[] = CCD_STATE_NAMES;
2724 const char *cap_state_names[] = CCD_CAP_STATE_NAMES;
2725 uint32_t caps_bitmap = 0;
2726 uint32_t ccd_info_version;
2727
2728 /*
2729 * CCD info structure is different for different GSCs. Two layouts are
2730 * defined at this time, version 0 (Cr50) and version 1 (Ti50). The
2731 * array below indexed by version number provides access to version
2732 * specific information about the layout.
2733 */
2734 const struct {
2735 size_t cap_count;
2736 const struct ccd_capability_info *info_table;
2737 } version_to_ccd[] = {
2738 { CR50_CCD_CAP_COUNT, cr50_cap_info },
2739 { TI50_CCD_CAP_COUNT, ti50_cap_info },
2740 };
2741
2742 /* Run time determined properties of the CCD info table. */
2743 size_t gsc_cap_count;
2744 const struct ccd_capability_info *gsc_capability_info;
2745 size_t name_column_width;
2746
2747 ccd_info_version = validate_into_ccd_info_response(
2748 response, response_size, &ccd_info);
2749
2750 if (ccd_info_version >= ARRAY_SIZE(version_to_ccd)) {
2751 fprintf(stderr, "Unsupported CCD info version number %d\n",
2752 ccd_info_version);
2753 exit(update_error);
2754 }
2755
2756 /* Now report CCD state on the console. */
2757 const char *const state = ccd_info.ccd_state > ARRAY_SIZE(state_names) ?
2758 "Error" :
2759 state_names[ccd_info.ccd_state];
2760 const char *const password = (ccd_info.ccd_indicator_bitmap &
2761 CCD_INDICATOR_BIT_HAS_PASSWORD) ?
2762 "Set" :
2763 "None";
2764 if (show_machine_output) {
2765 print_machine_output("STATE", "%s", state);
2766 print_machine_output("PASSWORD", "%s", password);
2767 print_machine_output("CCD_FLAGS", "%#06x", ccd_info.ccd_flags);
2768 print_machine_output(
2769 "CCD_FLAG_TESTLAB_MODE", "%c",
2770 (ccd_info.ccd_flags & CCD_FLAG_TEST_LAB) ? 'Y' : 'N');
2771 print_machine_output("CCD_FLAG_FACTORY_MODE", "%c",
2772 (ccd_info.ccd_flags &
2773 CCD_FLAG_FACTORY_MODE_ENABLED) ?
2774 'Y' :
2775 'N');
2776 } else {
2777 printf("State: %s\n", state);
2778 printf("Password: %s\n", password);
2779 printf("Flags: %#06x\n", ccd_info.ccd_flags);
2780 printf("Capabilities, current and default:\n");
2781 }
2782
2783 gsc_cap_count = version_to_ccd[ccd_info_version].cap_count;
2784 gsc_capability_info = version_to_ccd[ccd_info_version].info_table;
2785 name_column_width =
2786 longest_cap_name_len(gsc_capability_info, gsc_cap_count) + 1;
2787 for (i = 0; i < gsc_cap_count; i++) {
2788 int is_enabled;
2789 int index;
2790 int shift;
2791 int cap_current;
2792 int cap_default;
2793
2794 index = i / (32 / CCD_CAP_BITS);
2795 shift = (i % (32 / CCD_CAP_BITS)) * CCD_CAP_BITS;
2796
2797 cap_current = (ccd_info.ccd_caps_current[index] >> shift) &
2798 CCD_CAP_BITMASK;
2799 cap_default = (ccd_info.ccd_caps_defaults[index] >> shift) &
2800 CCD_CAP_BITMASK;
2801
2802 if (ccd_info.ccd_force_disabled) {
2803 is_enabled = 0;
2804 } else {
2805 switch (cap_current) {
2806 case CCD_CAP_STATE_ALWAYS:
2807 is_enabled = 1;
2808 break;
2809 case CCD_CAP_STATE_UNLESS_LOCKED:
2810 is_enabled = (ccd_info.ccd_state !=
2811 CCD_STATE_LOCKED);
2812 break;
2813 default:
2814 is_enabled = (ccd_info.ccd_state ==
2815 CCD_STATE_OPENED);
2816 break;
2817 }
2818 }
2819
2820 if (show_machine_output) {
2821 char upper[80];
2822
2823 to_upper_underscore(gsc_capability_info[i].name, upper);
2824 print_machine_output(upper, "%c",
2825 is_enabled ? 'Y' : 'N');
2826 } else {
2827 printf(" ");
2828 print_aligned(gsc_capability_info[i].name,
2829 name_column_width);
2830 printf("%c %s", is_enabled ? 'Y' : '-',
2831 cap_state_names[cap_current]);
2832
2833 if (cap_current != cap_default)
2834 printf(" (%s)", cap_state_names[cap_default]);
2835
2836 printf("\n");
2837 }
2838
2839 if (is_enabled)
2840 caps_bitmap |= (1 << i);
2841 }
2842 if (show_machine_output) {
2843 print_machine_output("CCD_CAPS_BITMAP", "%#x", caps_bitmap);
2844 print_machine_output("CAPABILITY_MODIFIED", "%c",
2845 (ccd_info.ccd_indicator_bitmap &
2846 CCD_INDICATOR_BIT_ALL_CAPS_DEFAULT) ?
2847 'N' :
2848 'Y');
2849 print_machine_output("INITIAL_FACTORY_MODE", "%c",
2850 (ccd_info.ccd_indicator_bitmap &
2851 CCD_INDICATOR_BIT_INITIAL_FACTORY_MODE) ?
2852 'Y' :
2853 'N');
2854
2855 } else {
2856 printf("CCD caps bitmap: %#x\n", caps_bitmap);
2857 printf("Capabilities are %s.\n",
2858 (ccd_info.ccd_indicator_bitmap &
2859 CCD_INDICATOR_BIT_ALL_CAPS_DEFAULT) ?
2860 "default" :
2861 "modified");
2862 if (ccd_info.ccd_indicator_bitmap &
2863 CCD_INDICATOR_BIT_INITIAL_FACTORY_MODE) {
2864 printf("Chip factory mode.");
2865 }
2866 }
2867 }
2868
process_ccd_state(struct transfer_descriptor * td,int ccd_unlock,int ccd_open,int ccd_lock,int ccd_info,bool show_machine_output)2869 static void process_ccd_state(struct transfer_descriptor *td, int ccd_unlock,
2870 int ccd_open, int ccd_lock, int ccd_info,
2871 bool show_machine_output)
2872 {
2873 uint8_t payload;
2874 /* Max possible response size is when ccd_info is requested. */
2875 uint8_t response[sizeof(struct ccd_info_response_packet)];
2876 size_t response_size;
2877 int rv;
2878
2879 if (ccd_unlock)
2880 payload = CCDV_UNLOCK;
2881 else if (ccd_open)
2882 payload = CCDV_OPEN;
2883 else if (ccd_lock)
2884 payload = CCDV_LOCK;
2885 else
2886 payload = CCDV_GET_INFO;
2887
2888 response_size = sizeof(response);
2889 rv = send_vendor_command(td, VENDOR_CC_CCD, &payload, sizeof(payload),
2890 &response, &response_size);
2891
2892 /*
2893 * If password is required - try sending the same subcommand
2894 * accompanied by user password.
2895 */
2896 if (rv == VENDOR_RC_PASSWORD_REQUIRED)
2897 rv = common_process_password(td, payload);
2898
2899 if (rv == VENDOR_RC_SUCCESS) {
2900 if (ccd_info)
2901 print_ccd_info(response, response_size,
2902 show_machine_output);
2903 return;
2904 }
2905
2906 if (rv != VENDOR_RC_IN_PROGRESS) {
2907 fprintf(stderr, "Error: rv %d, response %d\n", rv,
2908 response_size ? response[0] : 0);
2909 exit(update_error);
2910 }
2911
2912 /*
2913 * Physical presence process started, poll for the state the user
2914 * asked for. Only two subcommands would return 'IN_PROGRESS'.
2915 */
2916 if (ccd_unlock)
2917 poll_for_pp(td, VENDOR_CC_CCD, CCDV_PP_POLL_UNLOCK);
2918 else
2919 poll_for_pp(td, VENDOR_CC_CCD, CCDV_PP_POLL_OPEN);
2920 }
2921
2922 /*
2923 * Ensure that the AllowUnverifiedRO capability is set to always. If called for
2924 * Cr50 (which does not have this capability), the program will exit instead.
2925 */
is_unverified_ro_allowed(struct transfer_descriptor * td)2926 static bool is_unverified_ro_allowed(struct transfer_descriptor *td)
2927 {
2928 uint8_t cmd = CCDV_GET_INFO;
2929 /* Max possible response size is when ccd_info is requested. */
2930 uint8_t response[sizeof(struct ccd_info_response_packet)];
2931 size_t response_size = sizeof(response);
2932 struct ccd_info_response ccd_info;
2933 uint32_t ccd_info_version;
2934 int allow_unverified_ro_cap;
2935 int rv;
2936
2937 rv = send_vendor_command(td, VENDOR_CC_CCD, &cmd, sizeof(cmd),
2938 &response, &response_size);
2939 if (rv != VENDOR_RC_SUCCESS) {
2940 fprintf(stderr, "Error: rv %d, response %d\n", rv,
2941 response_size ? response[0] : 0);
2942 exit(update_error);
2943 }
2944 ccd_info_version = validate_into_ccd_info_response(
2945 response, response_size, &ccd_info);
2946 if (ccd_info_version != 1) {
2947 /*
2948 * We also don't know what order future ccd info versions will
2949 * place the AllowUnverifiedRO capability. We need to ensure
2950 * that the array lookup below is still correct for future
2951 * version if/when they become available
2952 */
2953 fprintf(stderr,
2954 "Error: CCD info version incorrect (%d).\n"
2955 "Cr50 does not support this operation.\n",
2956 ccd_info_version);
2957 exit(update_error);
2958 }
2959 /*
2960 * Pull out the AllowUnverifiedRo cap from the list.
2961 * See ti50_cap_info for full order of V1 capabilities
2962 */
2963 allow_unverified_ro_cap = (ccd_info.ccd_caps_current[1] >> 10) &
2964 CCD_CAP_BITMASK;
2965
2966 return allow_unverified_ro_cap == CCD_CAP_STATE_ALWAYS;
2967 }
2968
process_wp(struct transfer_descriptor * td,enum wp_options wp)2969 static enum exit_values process_wp(struct transfer_descriptor *td,
2970 enum wp_options wp)
2971 {
2972 size_t response_size;
2973 uint8_t response;
2974 int rv = 0;
2975 uint8_t command = wp;
2976
2977 response_size = sizeof(response);
2978
2979 /*
2980 * Ti50 supports enable, disable, and follow, but cr50 doesn't and will
2981 * return an error from the chip. gsctool supports the superset.
2982 */
2983 switch (wp) {
2984 case WP_DISABLE:
2985 case WP_FOLLOW:
2986 /* Ensure that AllowUnverifiedRo is true then fallthrough */
2987 if (!is_unverified_ro_allowed(td)) {
2988 fprintf(stderr,
2989 "Error: Must set AllowUnverifiedRo cap to "
2990 "always first.\n"
2991 "Otherwise changes to AP RO may cause system "
2992 "to no longer boot.\n"
2993 "Use `gsctool -I AllowUnverifiedRo:always`\n");
2994 return update_error;
2995 }
2996 case WP_ENABLE:
2997 printf("Setting WP\n");
2998 /* Enabling write protect doesn't require any special checks */
2999 rv = send_vendor_command(td, VENDOR_CC_WP, &command,
3000 sizeof(command), &response,
3001 &response_size);
3002 break;
3003 default:
3004 /* Just check the wp status without a parameter */
3005 printf("Getting WP\n");
3006 rv = send_vendor_command(td, VENDOR_CC_WP, NULL, 0, &response,
3007 &response_size);
3008 }
3009
3010 /*
3011 * If we tried to disable and we got in progress, then prompt the
3012 * user for power button pushes
3013 */
3014 if (wp == WP_DISABLE && rv == VENDOR_RC_IN_PROGRESS) {
3015 /* Progress physical button request then get the wp again */
3016 poll_for_pp(td, VENDOR_CC_CCD, CCDV_PP_POLL_WP_DISABLE);
3017 /* Reset expected response size and get WP status again */
3018 response_size = sizeof(response);
3019 rv = send_vendor_command(td, VENDOR_CC_WP, NULL, 0, &response,
3020 &response_size);
3021 }
3022 /*
3023 * Give user a more detailed error for not allowed. That means CCD
3024 * must be open before we can process the command
3025 */
3026 if (rv == VENDOR_RC_NOT_ALLOWED) {
3027 fprintf(stderr, "Error: OverrideWP must be enabled first.\n"
3028 "Use `gsctool -I OverrideWP:always`\n");
3029 return update_error;
3030 }
3031
3032 if (rv != VENDOR_RC_SUCCESS) {
3033 fprintf(stderr, "Error %d %sting write protect\n", rv,
3034 (wp == WP_ENABLE) ? "set" : "get");
3035 if (wp == WP_ENABLE) {
3036 fprintf(stderr,
3037 "Early Cr50 versions do not support setting WP"
3038 "\n");
3039 }
3040 return update_error;
3041 }
3042 if (response_size != sizeof(response)) {
3043 fprintf(stderr,
3044 "Unexpected response size %zd while getting "
3045 "write protect\n",
3046 response_size);
3047 return update_error;
3048 }
3049
3050 printf("WP: %08x\n", response);
3051 printf("Flash WP: %s%s%s\n",
3052 response & WPV_FWMP_FORCE_WP_EN ? "fwmp " : "",
3053 response & WPV_FORCE ? "forced " : "",
3054 response & WPV_ENABLE ? "enabled" : "disabled");
3055 printf(" at boot: %s\n",
3056 response & WPV_FWMP_FORCE_WP_EN ? "fwmp enabled" :
3057 !(response & WPV_ATBOOT_SET) ? "follow_batt_pres" :
3058 response & WPV_ATBOOT_ENABLE ? "forced enabled" :
3059 "forced disabled");
3060 return noop;
3061 }
3062
process_get_chassis_open(struct transfer_descriptor * td)3063 static enum exit_values process_get_chassis_open(struct transfer_descriptor *td)
3064 {
3065 struct chassis_open_repsonse {
3066 uint8_t version;
3067 uint8_t chassis_open;
3068 } response;
3069 size_t response_size;
3070 int rv;
3071
3072 response_size = sizeof(response);
3073
3074 rv = send_vendor_command(td, VENDOR_CC_GET_CHASSIS_OPEN, NULL, 0,
3075 &response, &response_size);
3076
3077 if (rv != VENDOR_RC_SUCCESS) {
3078 fprintf(stderr, "Error %d getting chassis open\n", rv);
3079 return update_error;
3080 }
3081 if (response_size != sizeof(response)) {
3082 fprintf(stderr,
3083 "Unexpected response size %zd while getting "
3084 "chassis open\n",
3085 response_size);
3086 return update_error;
3087 }
3088 if (response.version != 1) {
3089 fprintf(stderr,
3090 "Unexpected response version %d while getting "
3091 "chassis open\n",
3092 response.version);
3093 return update_error;
3094 }
3095
3096 printf("Chassis Open: %s\n",
3097 response.chassis_open & 1 ? "true" : "false");
3098 return noop;
3099 }
3100
process_get_dev_ids(struct transfer_descriptor * td,bool show_machine_output)3101 static enum exit_values process_get_dev_ids(struct transfer_descriptor *td,
3102 bool show_machine_output)
3103 {
3104 struct sys_info_repsonse {
3105 uint32_t ro_keyid;
3106 uint32_t rw_keyid;
3107 uint32_t dev_id0;
3108 uint32_t dev_id1;
3109 } response;
3110 size_t response_size;
3111 int rv;
3112
3113 response_size = sizeof(response);
3114
3115 rv = send_vendor_command(td, VENDOR_CC_SYSINFO, NULL, 0, &response,
3116 &response_size);
3117
3118 if (rv != VENDOR_RC_SUCCESS) {
3119 fprintf(stderr, "Error %d getting device ids\n", rv);
3120 return update_error;
3121 }
3122 if (response_size != sizeof(response)) {
3123 fprintf(stderr,
3124 "Unexpected response size %zd while getting "
3125 "device ids\n",
3126 response_size);
3127 return update_error;
3128 }
3129
3130 /* Convert from BE transimision format */
3131 response.dev_id0 = be32toh(response.dev_id0);
3132 response.dev_id1 = be32toh(response.dev_id1);
3133
3134 if (show_machine_output) {
3135 print_machine_output("DEV_ID0", "%08x", response.dev_id0);
3136 print_machine_output("DEV_ID1", "%08x", response.dev_id1);
3137 } else {
3138 printf("DEVID: 0x%08x 0x%08x\n", response.dev_id0,
3139 response.dev_id1);
3140 }
3141 return noop;
3142 }
3143
process_get_aprov_reset_counts(struct transfer_descriptor * td)3144 static enum exit_values process_get_aprov_reset_counts(
3145 struct transfer_descriptor *td)
3146 {
3147 /*
3148 * We shouldn't need a version for this command since the entire
3149 * command should be removed after feature launch. However, if we
3150 * did need a version, the upper 7 bits of allow_unverified_ro are
3151 * unused.
3152 */
3153 struct aprov_reset_counts {
3154 uint8_t allow_unverified_ro;
3155 uint8_t settings_change;
3156 uint8_t external_wp;
3157 uint8_t internal_wp;
3158 } response;
3159 size_t response_size;
3160 int rv;
3161 int32_t allow_unverified_sign = 1;
3162
3163 response_size = sizeof(response);
3164
3165 rv = send_vendor_command(td, VENDOR_CC_GET_AP_RO_RESET_COUNTS, NULL, 0,
3166 &response, &response_size);
3167
3168 if (rv != VENDOR_RC_SUCCESS) {
3169 fprintf(stderr, "Error %d getting reset counts\n", rv);
3170 return update_error;
3171 }
3172 if (response_size != sizeof(response)) {
3173 fprintf(stderr,
3174 "Unexpected response size %zd while getting "
3175 "reset counts\n",
3176 response_size);
3177 return update_error;
3178 }
3179
3180 /* Change all of the values to negative if unverified RO is allowed. */
3181 if (response.allow_unverified_ro != 0)
3182 allow_unverified_sign = -1;
3183
3184 const uint32_t combined = response.settings_change +
3185 (response.external_wp << 8) +
3186 (response.internal_wp << 16);
3187
3188 /*
3189 * The `cr50-metrics.conf` file depends on these string names. Do
3190 * not change without updated that file.
3191 */
3192 print_machine_output("COMBINED", "0x%08x",
3193 allow_unverified_sign * combined);
3194 print_machine_output("SETTINGS_CHANGE", "0x%08x",
3195 allow_unverified_sign * response.settings_change);
3196 print_machine_output("EXTERNAL_WP", "0x%08x",
3197 allow_unverified_sign * response.external_wp);
3198 print_machine_output("INTERNAL_WP", "0x%08x",
3199 allow_unverified_sign * response.internal_wp);
3200 return noop;
3201 }
3202
process_get_apro_hash(struct transfer_descriptor * td)3203 static int process_get_apro_hash(struct transfer_descriptor *td)
3204 {
3205 size_t response_size;
3206 uint8_t response[SHA256_DIGEST_SIZE];
3207 const char *const desc = "getting apro hash";
3208 int rv = 0;
3209 int i;
3210
3211 response_size = sizeof(response);
3212
3213 rv = send_vendor_command(td, VENDOR_CC_GET_AP_RO_HASH, NULL, 0,
3214 &response, &response_size);
3215
3216 if (response_size == 1) {
3217 printf("get hash rc: %d ", response[0]);
3218 switch (response[0]) {
3219 case ARCVE_NOT_PROGRAMMED:
3220 printf("AP RO hash unprogrammed\n");
3221 return 0;
3222 case ARCVE_FLASH_READ_FAILED:
3223 printf("flash read failed\n");
3224 return 0;
3225 case ARCVE_BOARD_ID_BLOCKED:
3226 printf("board id blocked\n");
3227 return 0;
3228 default:
3229 fprintf(stderr, "unexpected error\n");
3230 return update_error;
3231 }
3232 } else if (rv != VENDOR_RC_SUCCESS) {
3233 fprintf(stderr, "Error %d %s\n", rv, desc);
3234 return update_error;
3235 } else if (response_size != SHA256_DIGEST_SIZE) {
3236 fprintf(stderr, "Error in the size of response, %zu.\n",
3237 response_size);
3238 return update_error;
3239 }
3240 printf("digest: ");
3241 for (i = 0; i < SHA256_DIGEST_SIZE; i++)
3242 printf("%x", response[i]);
3243 printf("\n");
3244 return 0;
3245 }
3246
process_get_apro_boot_status(struct transfer_descriptor * td)3247 static int process_get_apro_boot_status(struct transfer_descriptor *td)
3248 {
3249 size_t response_size;
3250 uint8_t response;
3251 const char *const desc = "getting apro status";
3252 int rv = 0;
3253
3254 response_size = sizeof(response);
3255
3256 rv = send_vendor_command(td, VENDOR_CC_GET_AP_RO_STATUS, NULL, 0,
3257 &response, &response_size);
3258 if (rv != VENDOR_RC_SUCCESS) {
3259 fprintf(stderr, "Error %d %s\n", rv, desc);
3260 return update_error;
3261 }
3262 if (response_size != 1) {
3263 fprintf(stderr, "Unexpected response size %zd while %s\n",
3264 response_size, desc);
3265 return update_error;
3266 }
3267
3268 /* Print the response and meaning, as in 'enum ap_ro_status'. */
3269 printf("apro result (%d) : ", response);
3270 switch (response) {
3271 case AP_RO_NOT_RUN:
3272 printf("not run\n");
3273 break;
3274 case AP_RO_PASS:
3275 case AP_RO_V2_SUCCESS:
3276 printf("pass\n");
3277 break;
3278 case AP_RO_PASS_UNVERIFIED_GBB:
3279 printf("pass - unverified gbb!\n");
3280 break;
3281 case AP_RO_V2_NON_ZERO_GBB_FLAGS:
3282 printf("pass - except non-zero gbb flags!\n");
3283 break;
3284 case AP_RO_FAIL:
3285 case AP_RO_V2_FAILED_VERIFICATION:
3286 printf("FAIL\n");
3287 break;
3288 case AP_RO_UNSUPPORTED_TRIGGERED:
3289 printf("not supported\ntriggered: yes\n");
3290 break;
3291 case AP_RO_UNSUPPORTED_UNKNOWN:
3292 printf("not supported\ntriggered: unknown\n");
3293 break;
3294 case AP_RO_UNSUPPORTED_NOT_TRIGGERED:
3295 printf("not supported\ntriggered: no\n");
3296 break;
3297 case AP_RO_IN_PROGRESS:
3298 printf("in progress.");
3299 break;
3300 case AP_RO_V2_INCONSISTENT_GSCVD:
3301 printf("inconsistent gscvd\n");
3302 break;
3303 case AP_RO_V2_INCONSISTENT_KEYBLOCK:
3304 printf("inconsistent keyblock\n");
3305 break;
3306 case AP_RO_V2_INCONSISTENT_KEY:
3307 printf("inconsistent key\n");
3308 break;
3309 case AP_RO_V2_SPI_READ:
3310 printf("spi read failure\n");
3311 break;
3312 case AP_RO_V2_UNSUPPORTED_CRYPTO_ALGORITHM:
3313 printf("unsupported crypto algo\n");
3314 break;
3315 case AP_RO_V2_VERSION_MISMATCH:
3316 printf("header version mismatch\n");
3317 break;
3318 case AP_RO_V2_OUT_OF_MEMORY:
3319 printf("out of memory\n");
3320 break;
3321 case AP_RO_V2_INTERNAL:
3322 printf("internal\n");
3323 break;
3324 case AP_RO_V2_TOO_BIG:
3325 printf("too many areas\n");
3326 break;
3327 case AP_RO_V2_MISSING_GSCVD:
3328 printf("missing gscvd\n");
3329 break;
3330 case AP_RO_V2_BOARD_ID_MISMATCH:
3331 printf("board id mismatch\n");
3332 break;
3333 case AP_RO_V2_SETTING_NOT_PROVISIONED:
3334 printf("setting not provisioned\n");
3335 break;
3336 case AP_RO_V2_WRONG_ROOT_KEY:
3337 printf("key is recognized but disallowed (e.g. preMP key)\n");
3338 break;
3339 default:
3340 printf("unknown\n");
3341 fprintf(stderr, "unknown status\n");
3342 return update_error;
3343 }
3344
3345 return 0;
3346 }
3347
process_arv_config_spi_addr_mode(struct transfer_descriptor * td,int arv_config_spi_addr_mode)3348 static int process_arv_config_spi_addr_mode(struct transfer_descriptor *td,
3349 int arv_config_spi_addr_mode)
3350 {
3351 enum ap_ro_config_spi_mode_e {
3352 ap_ro_spi_config_3byte = 0,
3353 ap_ro_spi_config_4byte = 1,
3354 };
3355
3356 struct __attribute__((__packed__)) ap_ro_config_spi_mode_msg {
3357 uint8_t version;
3358 uint8_t command;
3359 uint8_t state;
3360 uint8_t mode;
3361 };
3362
3363 struct ap_ro_config_spi_mode_msg msg = {
3364 .version = ARV_CONFIG_SETTING_CURRENT_VERSION,
3365 .command = arv_config_setting_command_spi_addressing_mode,
3366 .state = arv_config_setting_state_present,
3367 .mode = ap_ro_spi_config_4byte
3368 };
3369 size_t response_size = sizeof(msg);
3370 int rv = 0;
3371
3372 switch (arv_config_spi_addr_mode) {
3373 case arv_config_spi_addr_mode_get:
3374 rv = send_vendor_command(td, VENDOR_CC_GET_AP_RO_VERIFY_SETTING,
3375 &msg, sizeof(msg), &msg,
3376 &response_size);
3377 if (rv != VENDOR_RC_SUCCESS) {
3378 fprintf(stderr,
3379 "Error %d getting ap ro spi addr mode\n", rv);
3380 return update_error;
3381 }
3382
3383 if (response_size != sizeof(msg)) {
3384 fprintf(stderr,
3385 "Error getting ap ro spi addr mode response\n");
3386 return update_error;
3387 }
3388
3389 if (msg.state != arv_config_setting_state_present) {
3390 switch (msg.state) {
3391 case arv_config_setting_state_not_present:
3392 fprintf(stderr, "not provisioned\n");
3393 break;
3394 case arv_config_setting_state_corrupted:
3395 fprintf(stderr, "corrupted\n");
3396 break;
3397 case arv_config_setting_state_invalid:
3398 fprintf(stderr, "invalid\n");
3399 break;
3400 default:
3401 fprintf(stderr,
3402 "unexpected message response state\n");
3403 return update_error;
3404 }
3405 return 0;
3406 }
3407
3408 switch (msg.mode) {
3409 case ap_ro_spi_config_3byte:
3410 printf("3byte\n");
3411 break;
3412 case ap_ro_spi_config_4byte:
3413 printf("4byte\n");
3414 break;
3415 default:
3416 fprintf(stderr, "unknown spi mode\n");
3417 return update_error;
3418 }
3419
3420 break;
3421 case arv_config_spi_addr_mode_set_3byte:
3422 msg.mode = ap_ro_spi_config_3byte;
3423 /* Fallthrough */
3424 case arv_config_spi_addr_mode_set_4byte:
3425 /* The default is 4byte addressing */
3426 rv = send_vendor_command(td, VENDOR_CC_SET_AP_RO_VERIFY_SETTING,
3427 &msg, sizeof(msg), &msg,
3428 &response_size);
3429 if (rv != VENDOR_RC_SUCCESS) {
3430 fprintf(stderr,
3431 "Error %d setting ap ro spi addr mode\n", rv);
3432 return update_error;
3433 }
3434 break;
3435 default:
3436 return update_error;
3437 }
3438
3439 return 0;
3440 }
3441
3442 /*
3443 * Reads an ascii hex byte in the following forms:
3444 * - 0x01
3445 * - 0x1
3446 * - 01
3447 * - 0
3448 *
3449 * 1 is returned on success, 0 on failure.
3450 */
read_hex_byte_string(char * s,uint8_t * byte)3451 static int read_hex_byte_string(char *s, uint8_t *byte)
3452 {
3453 uint8_t b = 0;
3454
3455 if (!strncmp(s, "0x", 2))
3456 s += 2;
3457
3458 if (strlen(s) == 0)
3459 return 0;
3460
3461 for (const char *end = s + 2; s < end; ++s) {
3462 if (*s >= '0' && *s <= '9')
3463 b = b * 16 + *s - '0';
3464 else if (*s >= 'A' && *s <= 'F')
3465 b = b * 16 + 10 + *s - 'A';
3466 else if (*s >= 'a' && *s <= 'f')
3467 b = b * 16 + 10 + *s - 'a';
3468 else if (*s == '\0')
3469 /* Single nibble, do nothing instead of `break`
3470 * to keep checkpatch happy
3471 */
3472 ;
3473 else
3474 /* Invalid nibble */
3475 return 0;
3476 }
3477 *byte = b;
3478 return 1;
3479 }
3480
parse_wpsrs(const char * opt,struct arv_config_wpds * wpds)3481 static int parse_wpsrs(const char *opt, struct arv_config_wpds *wpds)
3482 {
3483 size_t len = strlen(opt);
3484 char *ptr, *p, *delim = " ";
3485 uint8_t b;
3486 int rv = 0;
3487 struct arv_config_wpd *wpd;
3488
3489 ptr = malloc(len + 1);
3490 strcpy(ptr, opt);
3491 p = strtok(ptr, delim);
3492
3493 while (p != NULL) {
3494 if (read_hex_byte_string(p, &b)) {
3495 wpd = &wpds->data[rv / 2];
3496 if (rv % 2 == 0) {
3497 wpd->expected_value = b;
3498 } else {
3499 wpd->mask = b;
3500 wpd->state = arv_config_setting_state_present;
3501 }
3502 rv++;
3503 } else {
3504 break;
3505 }
3506 p = strtok(NULL, delim);
3507 }
3508 free(ptr);
3509
3510 return rv;
3511 }
3512
print_wpd(size_t i,struct arv_config_wpd * wpd)3513 static void print_wpd(size_t i, struct arv_config_wpd *wpd)
3514 {
3515 if (wpd->state == arv_config_setting_state_not_present) {
3516 printf("not provisioned");
3517 return;
3518 } else if (wpd->state == arv_config_setting_state_corrupted) {
3519 printf("corrupted");
3520 return;
3521 } else if (wpd->state == arv_config_setting_state_invalid) {
3522 printf("invalid");
3523 return;
3524 }
3525
3526 printf("%zu: %02x & %02x", i, wpd->expected_value, wpd->mask);
3527 }
3528
process_arv_config_wpds(struct transfer_descriptor * td,enum arv_config_wpsr_choice_e choice,struct arv_config_wpds * wpds)3529 static int process_arv_config_wpds(struct transfer_descriptor *td,
3530 enum arv_config_wpsr_choice_e choice,
3531 struct arv_config_wpds *wpds)
3532 {
3533 struct __attribute__((__packed__)) arv_config_wpds_message {
3534 uint8_t version;
3535 /* See `arv_config_setting_command_e` */
3536 uint8_t command;
3537 struct arv_config_wpds wpds;
3538 };
3539 int rv = 0;
3540
3541 struct arv_config_wpds_message msg = {
3542 .version = ARV_CONFIG_SETTING_CURRENT_VERSION,
3543 .command = arv_config_setting_command_write_protect_descriptors,
3544 };
3545 size_t response_size = sizeof(msg);
3546
3547 if (choice == arv_config_wpsr_choice_get) {
3548 rv = send_vendor_command(td, VENDOR_CC_GET_AP_RO_VERIFY_SETTING,
3549 &msg, sizeof(msg), &msg,
3550 &response_size);
3551 if (rv != VENDOR_RC_SUCCESS) {
3552 fprintf(stderr,
3553 "Error %d getting ap ro write protect descriptors\n",
3554 rv);
3555 return update_error;
3556 }
3557
3558 if (response_size != sizeof(msg)) {
3559 fprintf(stderr,
3560 "Error getting ap ro write protect descriptors response\n");
3561 return update_error;
3562 }
3563
3564 if (msg.wpds.data[0].state ==
3565 arv_config_setting_state_present) {
3566 printf("expected values: ");
3567 }
3568 print_wpd(1, &msg.wpds.data[0]);
3569 if (msg.wpds.data[1].state !=
3570 arv_config_setting_state_not_present) {
3571 printf(", ");
3572 print_wpd(2, &msg.wpds.data[1]);
3573 }
3574 if (msg.wpds.data[2].state !=
3575 arv_config_setting_state_not_present) {
3576 printf(", ");
3577 print_wpd(3, &msg.wpds.data[2]);
3578 }
3579
3580 printf("\n");
3581 } else if (choice == arv_config_wpsr_choice_set) {
3582 msg.wpds = *wpds;
3583
3584 rv = send_vendor_command(td, VENDOR_CC_SET_AP_RO_VERIFY_SETTING,
3585 &msg, sizeof(msg), &msg,
3586 &response_size);
3587 if (rv != VENDOR_RC_SUCCESS) {
3588 fprintf(stderr,
3589 "Error %d setting ap ro write protect descriptors\n",
3590 rv);
3591 return update_error;
3592 }
3593 }
3594
3595 return 0;
3596 }
3597
process_get_boot_mode(struct transfer_descriptor * td)3598 static int process_get_boot_mode(struct transfer_descriptor *td)
3599 {
3600 size_t response_size;
3601 uint8_t response;
3602 const char *const desc = "Getting boot mode";
3603 int rv = 0;
3604
3605 response_size = sizeof(response);
3606
3607 rv = send_vendor_command(td, VENDOR_CC_GET_BOOT_MODE, NULL, 0,
3608 &response, &response_size);
3609 if (rv != VENDOR_RC_SUCCESS) {
3610 fprintf(stderr, "Error %d in %s\n", rv, desc);
3611 return update_error;
3612 }
3613 if (response_size != 1) {
3614 fprintf(stderr, "Unexpected response size %zd while %s\n",
3615 response_size, desc);
3616 return update_error;
3617 }
3618
3619 /* Print the response and meaning, as in 'enum boot_mode'. */
3620 printf("Boot mode = 0x%02x: ", response);
3621 switch (response) {
3622 case 0x00:
3623 printf("NORMAL\n");
3624 break;
3625 case 0x01:
3626 printf("NO_BOOT\n");
3627 break;
3628 default:
3629 fprintf(stderr, "unknown boot mode\n");
3630 return update_error;
3631 }
3632
3633 return 0;
3634 }
3635
process_bid(struct transfer_descriptor * td,enum board_id_action bid_action,struct board_id * bid,bool show_machine_output)3636 void process_bid(struct transfer_descriptor *td,
3637 enum board_id_action bid_action, struct board_id *bid,
3638 bool show_machine_output)
3639 {
3640 size_t response_size;
3641
3642 if (bid_action == bid_get) {
3643 response_size = sizeof(*bid);
3644 send_vendor_command(td, VENDOR_CC_GET_BOARD_ID, bid,
3645 sizeof(*bid), bid, &response_size);
3646
3647 if (response_size != sizeof(*bid)) {
3648 fprintf(stderr,
3649 "Error reading board ID: response size %zd, "
3650 "first byte %#02x\n",
3651 response_size,
3652 response_size ? *(uint8_t *)&bid : -1);
3653 exit(update_error);
3654 }
3655
3656 if (show_machine_output) {
3657 print_machine_output("BID_TYPE", "%08x",
3658 be32toh(bid->type));
3659 print_machine_output("BID_TYPE_INV", "%08x",
3660 be32toh(bid->type_inv));
3661 print_machine_output("BID_FLAGS", "%08x",
3662 be32toh(bid->flags));
3663
3664 for (int i = 0; i < 4; i++) {
3665 if (!isupper(((const char *)bid)[i])) {
3666 print_machine_output("BID_RLZ", "%s",
3667 "????");
3668 return;
3669 }
3670 }
3671
3672 print_machine_output("BID_RLZ", "%c%c%c%c",
3673 ((const char *)bid)[0],
3674 ((const char *)bid)[1],
3675 ((const char *)bid)[2],
3676 ((const char *)bid)[3]);
3677 } else {
3678 printf("Board ID space: %08x:%08x:%08x\n",
3679 be32toh(bid->type), be32toh(bid->type_inv),
3680 be32toh(bid->flags));
3681 }
3682
3683 return;
3684 }
3685
3686 if (bid_action == bid_set) {
3687 /* Sending just two fields: type and flags. */
3688 uint32_t command_body[2];
3689 uint8_t response;
3690
3691 command_body[0] = htobe32(bid->type);
3692 command_body[1] = htobe32(bid->flags);
3693
3694 response_size = sizeof(command_body);
3695 send_vendor_command(td, VENDOR_CC_SET_BOARD_ID, command_body,
3696 sizeof(command_body), command_body,
3697 &response_size);
3698
3699 /*
3700 * Speculative assignment: the response is expected to be one
3701 * byte in size and be placed in the first byte of the buffer.
3702 */
3703 response = *((uint8_t *)command_body);
3704
3705 if (response_size == 1) {
3706 if (!response)
3707 return; /* Success! */
3708
3709 fprintf(stderr, "Error %d while setting board id\n",
3710 response);
3711 } else {
3712 fprintf(stderr,
3713 "Unexpected response size %zd"
3714 " while setting board id\n",
3715 response_size);
3716 }
3717 exit(update_error);
3718 }
3719 }
3720
process_sn_bits(struct transfer_descriptor * td,uint8_t * sn_bits)3721 static void process_sn_bits(struct transfer_descriptor *td, uint8_t *sn_bits)
3722 {
3723 int rv;
3724 uint8_t response_code;
3725 size_t response_size = sizeof(response_code);
3726
3727 rv = send_vendor_command(td, VENDOR_CC_SN_SET_HASH, sn_bits,
3728 SN_BITS_SIZE, &response_code, &response_size);
3729
3730 if (rv) {
3731 fprintf(stderr, "Error %d while sending vendor command\n", rv);
3732 exit(update_error);
3733 }
3734
3735 if (response_size != 1) {
3736 fprintf(stderr,
3737 "Unexpected response size while setting sn bits\n");
3738 exit(update_error);
3739 }
3740
3741 if (response_code != 0) {
3742 fprintf(stderr, "Error %d while setting sn bits\n",
3743 response_code);
3744 exit(update_error);
3745 }
3746 }
3747
process_sn_inc_rma(struct transfer_descriptor * td,uint8_t arg)3748 static void process_sn_inc_rma(struct transfer_descriptor *td, uint8_t arg)
3749 {
3750 int rv;
3751 uint8_t response_code;
3752 size_t response_size = sizeof(response_code);
3753
3754 rv = send_vendor_command(td, VENDOR_CC_SN_INC_RMA, &arg, sizeof(arg),
3755 &response_code, &response_size);
3756 if (rv) {
3757 fprintf(stderr, "Error %d while sending vendor command\n", rv);
3758 exit(update_error);
3759 }
3760
3761 if (response_size != 1) {
3762 fprintf(stderr, "Unexpected response size while "
3763 "incrementing sn rma count\n");
3764 exit(update_error);
3765 }
3766
3767 if (response_code != 0) {
3768 fprintf(stderr, "Error %d while incrementing rma count\n",
3769 response_code);
3770 exit(update_error);
3771 }
3772 }
3773
3774 /* Get/Set the primary seed of the info1 manufacture state. */
process_endorsement_seed(struct transfer_descriptor * td,const char * endorsement_seed_str)3775 static int process_endorsement_seed(struct transfer_descriptor *td,
3776 const char *endorsement_seed_str)
3777 {
3778 uint8_t endorsement_seed[32];
3779 uint8_t response_seed[32];
3780 size_t seed_size = sizeof(endorsement_seed);
3781 size_t response_size = sizeof(response_seed);
3782 size_t i;
3783 int rv;
3784
3785 if (!endorsement_seed_str) {
3786 rv = send_vendor_command(td, VENDOR_CC_ENDORSEMENT_SEED, NULL,
3787 0, response_seed, &response_size);
3788 if (rv) {
3789 fprintf(stderr, "Error sending vendor command %d\n",
3790 rv);
3791 return update_error;
3792 }
3793 printf("Endorsement key seed: ");
3794 for (i = 0; i < response_size; i++)
3795 printf("%02x", response_seed[i]);
3796 printf("\n");
3797 return 0;
3798 }
3799 if (seed_size * 2 != strlen(endorsement_seed_str)) {
3800 printf("Invalid seed %s\n", endorsement_seed_str);
3801 return update_error;
3802 }
3803
3804 for (i = 0; i < seed_size; i++) {
3805 int nibble;
3806 char c;
3807
3808 c = endorsement_seed_str[2 * i];
3809 nibble = from_hexascii(c);
3810 if (nibble < 0) {
3811 fprintf(stderr, "Error: Non hex character in seed %c\n",
3812 c);
3813 return update_error;
3814 }
3815 endorsement_seed[i] = nibble << 4;
3816
3817 c = endorsement_seed_str[2 * i + 1];
3818 nibble = from_hexascii(c);
3819 if (nibble < 0) {
3820 fprintf(stderr, "Error: Non hex character in seed %c\n",
3821 c);
3822 return update_error;
3823 }
3824 endorsement_seed[i] |= nibble;
3825 }
3826
3827 printf("Setting seed: %s\n", endorsement_seed_str);
3828 rv = send_vendor_command(td, VENDOR_CC_ENDORSEMENT_SEED,
3829 endorsement_seed, seed_size, response_seed,
3830 &response_size);
3831 if (rv == VENDOR_RC_NOT_ALLOWED) {
3832 fprintf(stderr, "Seed already set\n");
3833 return update_error;
3834 }
3835 if (rv) {
3836 fprintf(stderr, "Error sending vendor command %d\n", rv);
3837 return update_error;
3838 }
3839 printf("Updated endorsement key seed.\n");
3840 return 0;
3841 }
3842
3843 /*
3844 * Retrieve the RMA authentication challenge from the Cr50, print out the
3845 * challenge on the console, then prompt the user for the authentication code,
3846 * and send the code back to Cr50. The Cr50 would report if the code matched
3847 * its expectations or not. Output in a machine-friendly format if
3848 * show_machine_output is true.
3849 */
process_rma(struct transfer_descriptor * td,const char * authcode,bool show_machine_output)3850 static void process_rma(struct transfer_descriptor *td, const char *authcode,
3851 bool show_machine_output)
3852 {
3853 char rma_response[81];
3854 size_t response_size = sizeof(rma_response);
3855 size_t i;
3856 size_t auth_size = 0;
3857
3858 if (!authcode) {
3859 send_vendor_command(td, VENDOR_CC_RMA_CHALLENGE_RESPONSE, NULL,
3860 0, rma_response, &response_size);
3861
3862 if (response_size == 1) {
3863 fprintf(stderr, "error %d\n", rma_response[0]);
3864 if (td->ep_type == usb_xfer)
3865 shut_down(&td->uep);
3866 exit(update_error);
3867 }
3868
3869 if (show_machine_output) {
3870 rma_response[response_size] = '\0';
3871 print_machine_output("CHALLENGE", "%s", rma_response);
3872 } else {
3873 printf("Challenge:");
3874 for (i = 0; i < response_size; i++) {
3875 if (!(i % 5)) {
3876 if (!(i % 40))
3877 printf("\n");
3878 printf(" ");
3879 }
3880 printf("%c", rma_response[i]);
3881 }
3882 printf("\n");
3883 }
3884 return;
3885 }
3886
3887 if (!*authcode) {
3888 printf("Empty response.\n");
3889 exit(update_error);
3890 return;
3891 }
3892
3893 if (!strcmp(authcode, "disable")) {
3894 printf("Invalid arg. Try using 'gsctool -F disable'\n");
3895 exit(update_error);
3896 return;
3897 }
3898
3899 printf("Processing response...\n");
3900 auth_size = strlen(authcode);
3901 response_size = sizeof(rma_response);
3902
3903 send_vendor_command(td, VENDOR_CC_RMA_CHALLENGE_RESPONSE, authcode,
3904 auth_size, rma_response, &response_size);
3905
3906 if (response_size == 1) {
3907 fprintf(stderr, "\nrma unlock failed, code %d ", *rma_response);
3908 switch (*rma_response) {
3909 case VENDOR_RC_BOGUS_ARGS:
3910 fprintf(stderr, "(wrong authcode size)\n");
3911 break;
3912 case VENDOR_RC_INTERNAL_ERROR:
3913 fprintf(stderr, "(authcode mismatch)\n");
3914 break;
3915 default:
3916 fprintf(stderr, "(unknown error)\n");
3917 break;
3918 }
3919 if (td->ep_type == usb_xfer)
3920 shut_down(&td->uep);
3921 exit(update_error);
3922 }
3923 printf("RMA unlock succeeded.\n");
3924 }
3925
3926 /*
3927 * Enable or disable factory mode. Factory mode will only be enabled if HW
3928 * write protect is removed.
3929 */
process_factory_mode(struct transfer_descriptor * td,const char * arg)3930 static void process_factory_mode(struct transfer_descriptor *td,
3931 const char *arg)
3932 {
3933 uint8_t rma_response;
3934 size_t response_size = sizeof(rma_response);
3935 char *cmd_str;
3936 int rv;
3937 uint16_t subcommand;
3938
3939 if (!strcasecmp(arg, "disable")) {
3940 subcommand = VENDOR_CC_DISABLE_FACTORY;
3941 cmd_str = "dis";
3942 } else if (!strcasecmp(arg, "enable")) {
3943 subcommand = VENDOR_CC_RESET_FACTORY;
3944 cmd_str = "en";
3945
3946 } else {
3947 fprintf(stderr, "Invalid factory mode arg %s", arg);
3948 exit(update_error);
3949 }
3950
3951 printf("%sabling factory mode\n", cmd_str);
3952 rv = send_vendor_command(td, subcommand, NULL, 0, &rma_response,
3953 &response_size);
3954 if (rv) {
3955 fprintf(stderr,
3956 "Failed %sabling factory mode\nvc error "
3957 "%d\n",
3958 cmd_str, rv);
3959 if (response_size == 1)
3960 fprintf(stderr, "ec error %d\n", rma_response);
3961 exit(update_error);
3962 }
3963 printf("Factory %sable succeeded.\n", cmd_str);
3964 }
3965
report_version(void)3966 static void report_version(void)
3967 {
3968 /* Get version from the generated file, ignore the underscore prefix. */
3969 const char *v = strchr(VERSION, '_');
3970
3971 printf("Version: %s, built on %s by %s\n", v ? v + 1 : "?", DATE,
3972 BUILDER);
3973 exit(0);
3974 }
3975
3976 /*
3977 * Either change or query TPM mode value.
3978 */
process_tpm_mode(struct transfer_descriptor * td,const char * arg)3979 static int process_tpm_mode(struct transfer_descriptor *td, const char *arg)
3980 {
3981 int rv;
3982 size_t command_size;
3983 size_t response_size;
3984 uint8_t response;
3985 uint8_t command_body;
3986
3987 response_size = sizeof(response);
3988 if (!arg) {
3989 command_size = 0;
3990 } else if (!strcasecmp(arg, "disable")) {
3991 command_size = sizeof(command_body);
3992 command_body = (uint8_t)TPM_MODE_DISABLED;
3993 } else if (!strcasecmp(arg, "enable")) {
3994 command_size = sizeof(command_body);
3995 command_body = (uint8_t)TPM_MODE_ENABLED;
3996 } else {
3997 fprintf(stderr, "Invalid tpm mode arg: %s.\n", arg);
3998 return update_error;
3999 }
4000
4001 rv = send_vendor_command(td, VENDOR_CC_TPM_MODE, &command_body,
4002 command_size, &response, &response_size);
4003 if (rv) {
4004 fprintf(stderr, "Error %d in setting TPM mode.\n", rv);
4005 return update_error;
4006 }
4007 if (response_size != sizeof(response)) {
4008 fprintf(stderr,
4009 "Error in the size of response,"
4010 " %zu.\n",
4011 response_size);
4012 return update_error;
4013 }
4014 if (response >= TPM_MODE_MAX) {
4015 fprintf(stderr,
4016 "Error in the value of response,"
4017 " %d.\n",
4018 response);
4019 return update_error;
4020 }
4021
4022 printf("TPM Mode: %s (%d)\n",
4023 (response == TPM_MODE_DISABLED) ? "disabled" : "enabled",
4024 response);
4025
4026 return rv;
4027 }
4028
4029 #define MAX_PAYLOAD_SIZE 256
4030 struct parsed_flog_entry {
4031 bool end_of_list;
4032 char payload[MAX_PAYLOAD_SIZE];
4033 size_t payload_size;
4034 uint64_t raw_timestamp;
4035 time_t timestamp;
4036 uint32_t event_type;
4037 bool timestamp_reliable;
4038 };
4039
pop_flog_dt(struct transfer_descriptor * td,struct parsed_flog_entry * parsed_entry)4040 static int pop_flog_dt(struct transfer_descriptor *td,
4041 struct parsed_flog_entry *parsed_entry)
4042 {
4043 union dt_entry_u entry;
4044 size_t resp_size = sizeof(entry);
4045 int rv = send_vendor_command(td, VENDOR_CC_POP_LOG_ENTRY_MS,
4046 &parsed_entry->raw_timestamp,
4047 sizeof(parsed_entry->raw_timestamp),
4048 &entry, &resp_size);
4049 if (rv)
4050 return rv;
4051 if (resp_size == 0) {
4052 parsed_entry->end_of_list = true;
4053 return 0;
4054 }
4055 parsed_entry->event_type = entry.evt.event_type;
4056 parsed_entry->payload_size =
4057 MIN(entry.evt.size - sizeof(entry.evt.event_type),
4058 MAX_PAYLOAD_SIZE);
4059 memcpy(parsed_entry->payload, entry.evt.payload,
4060 parsed_entry->payload_size);
4061 parsed_entry->raw_timestamp = entry.evt.time;
4062 parsed_entry->timestamp =
4063 (parsed_entry->raw_timestamp & ~(1ULL << 63)) / 1000;
4064 parsed_entry->timestamp_reliable =
4065 (parsed_entry->raw_timestamp >> 63) == 0;
4066 return rv;
4067 }
4068
pop_flog(struct transfer_descriptor * td,struct parsed_flog_entry * parsed_entry)4069 static int pop_flog(struct transfer_descriptor *td,
4070 struct parsed_flog_entry *parsed_entry)
4071 {
4072 union entry_u entry;
4073 size_t resp_size = sizeof(entry);
4074 uint32_t ts = (uint32_t)parsed_entry->raw_timestamp;
4075 int rv = send_vendor_command(td, VENDOR_CC_POP_LOG_ENTRY, &ts,
4076 sizeof(ts), &entry, &resp_size);
4077 if (rv)
4078 return rv;
4079 if (resp_size == 0) {
4080 parsed_entry->end_of_list = true;
4081 return 0;
4082 }
4083 parsed_entry->event_type = entry.r.type;
4084 parsed_entry->payload_size =
4085 MIN(FLASH_LOG_PAYLOAD_SIZE(entry.r.size), MAX_PAYLOAD_SIZE);
4086 memcpy(parsed_entry->payload, entry.r.payload,
4087 parsed_entry->payload_size);
4088 parsed_entry->raw_timestamp = entry.r.timestamp;
4089 parsed_entry->timestamp = entry.r.timestamp;
4090 parsed_entry->timestamp_reliable = true;
4091 return rv;
4092 }
4093
4094 /*
4095 * Retrieve from H1 flash log entries which are newer than the passed in
4096 * timestamp.
4097 *
4098 * On error retry a few times just in case flash log is locked by a concurrent
4099 * access.
4100 */
process_get_flog(struct transfer_descriptor * td,uint64_t prev_stamp,bool show_machine_output)4101 static int process_get_flog(struct transfer_descriptor *td, uint64_t prev_stamp,
4102 bool show_machine_output)
4103 {
4104 int rv;
4105 const int max_retries = 3;
4106 int retries = max_retries;
4107 bool time_zone_reported = false;
4108
4109 while (retries--) {
4110 struct parsed_flog_entry entry = { 0 };
4111 entry.raw_timestamp = prev_stamp;
4112 size_t i;
4113 struct tm loc_time;
4114 char date_str[25];
4115 if (is_ti50_device()) {
4116 rv = pop_flog_dt(td, &entry);
4117 } else {
4118 rv = pop_flog(td, &entry);
4119 }
4120
4121 if (rv) {
4122 /*
4123 * Flash log could be momentarily locked by a
4124 * concurrent access, let it settle and try again, 10
4125 * ms should be enough.
4126 */
4127 usleep(10 * 1000);
4128 continue;
4129 }
4130
4131 if (entry.end_of_list)
4132 return 0;
4133
4134 prev_stamp = entry.raw_timestamp;
4135 if (show_machine_output) {
4136 printf("%10" PRIu64 ":%02x", prev_stamp,
4137 entry.event_type);
4138 } else {
4139 localtime_r(&entry.timestamp, &loc_time);
4140
4141 if (!time_zone_reported) {
4142 strftime(date_str, sizeof(date_str), "%Z",
4143 &loc_time);
4144 printf("Log time zone is %s\n", date_str);
4145 time_zone_reported = true;
4146 }
4147
4148 /* Date format is MMM DD YY HH:mm:ss */
4149 strftime(date_str, sizeof(date_str), "%b %d %y %T",
4150 &loc_time);
4151 printf("%s : %02x", date_str, entry.event_type);
4152 }
4153 for (i = 0; i < entry.payload_size; i++)
4154 printf(" %02x", entry.payload[i]);
4155 if (entry.timestamp_reliable == false)
4156 printf(" -- TIMESTAMP UNRELIABLE!");
4157 printf("\n");
4158 retries = max_retries;
4159 }
4160
4161 fprintf(stderr, "%s: error %d\n", __func__, rv);
4162
4163 return rv;
4164 }
4165
process_tstamp(struct transfer_descriptor * td,const char * tstamp_ascii)4166 static int process_tstamp(struct transfer_descriptor *td,
4167 const char *tstamp_ascii)
4168 {
4169 char *e;
4170 size_t expected_response_size;
4171 size_t message_size;
4172 size_t response_size;
4173 uint32_t rv;
4174 uint32_t tstamp = 0;
4175 uint8_t max_response[sizeof(uint32_t)];
4176
4177 if (tstamp_ascii) {
4178 tstamp = strtoul(tstamp_ascii, &e, 10);
4179 if (*e) {
4180 fprintf(stderr, "invalid base timestamp value \"%s\"\n",
4181 tstamp_ascii);
4182 return -1;
4183 }
4184 tstamp = htobe32(tstamp);
4185 expected_response_size = 0;
4186 message_size = sizeof(tstamp);
4187 } else {
4188 expected_response_size = 4;
4189 message_size = 0;
4190 }
4191
4192 response_size = sizeof(max_response);
4193 rv = send_vendor_command(td, VENDOR_CC_FLOG_TIMESTAMP, &tstamp,
4194 message_size, max_response, &response_size);
4195
4196 if (rv) {
4197 fprintf(stderr, "error: return value %d\n", rv);
4198 return rv;
4199 }
4200 if (response_size != expected_response_size) {
4201 fprintf(stderr, "error: got %zd bytes, expected %zd\n",
4202 response_size, expected_response_size);
4203 return -1; /* Should never happen. */
4204 }
4205
4206 if (response_size) {
4207 memcpy(&tstamp, max_response, sizeof(tstamp));
4208 printf("Current H1 time is %d\n", be32toh(tstamp));
4209 }
4210 return 0;
4211 }
4212
process_reboot_gsc(struct transfer_descriptor * td,size_t timeout_ms)4213 static int process_reboot_gsc(struct transfer_descriptor *td, size_t timeout_ms)
4214 {
4215 /* Reboot timeout in milliseconds.
4216 * Maximum value is 1000ms on Ti50.
4217 */
4218 uint16_t msg = htobe16((uint16_t)timeout_ms);
4219 int rv = 0;
4220
4221 rv = send_vendor_command(td, VENDOR_CC_IMMEDIATE_RESET, &msg,
4222 sizeof(msg), NULL, 0);
4223 if (rv != VENDOR_RC_SUCCESS) {
4224 fprintf(stderr, "Error %d sending immediate reset command\n",
4225 rv);
4226 return update_error;
4227 }
4228
4229 return 0;
4230 }
4231
process_start_apro_verify(struct transfer_descriptor * td)4232 static int process_start_apro_verify(struct transfer_descriptor *td)
4233 {
4234 int rv = 0;
4235
4236 /*
4237 * For Ti50, we need to restart GSC to perform AP RO verification again.
4238 */
4239 if (is_ti50_device())
4240 return process_reboot_gsc(td, 1000);
4241
4242 /* If H1 chip, then send vendor command to start AP RO verification */
4243 rv = send_vendor_command(td, VENDOR_CC_AP_RO_VALIDATE, NULL, 0, NULL,
4244 NULL);
4245 if (rv != VENDOR_RC_SUCCESS) {
4246 fprintf(stderr, "Error %d starting RO verify\n", rv);
4247 return update_error;
4248 }
4249
4250 return 0;
4251 }
4252
4253 /*
4254 * Search the passed in zero terminated array of options_map structures for
4255 * option 'option'.
4256 *
4257 * If found - set the corresponding integer to 1 and return 1. If not found -
4258 * return 0.
4259 */
check_boolean(const struct options_map * omap,char option)4260 static int check_boolean(const struct options_map *omap, char option)
4261 {
4262 do {
4263 if (omap->opt != option)
4264 continue;
4265
4266 *omap->flag = 1;
4267 return 1;
4268 } while ((++omap)->opt);
4269
4270 return 0;
4271 }
4272
4273 /*
4274 * Set the long_opts table and short_opts string.
4275 *
4276 * This function allows to avoid maintaining two command line option
4277 * descriptions, for short and long forms.
4278 *
4279 * The long_opts table is built based on the cmd_line_options table contents,
4280 * and the short form is built based on the long_opts table contents.
4281 *
4282 * The 'required_argument' short options are followed by ':'.
4283 *
4284 * The passed in long_opts array and short_opts string are guaranteed to
4285 * accommodate all necessary objects/characters.
4286 */
set_opt_descriptors(struct option * long_opts,char * short_opts)4287 static void set_opt_descriptors(struct option *long_opts, char *short_opts)
4288 {
4289 size_t i;
4290 int j;
4291
4292 for (i = j = 0; i < ARRAY_SIZE(cmd_line_options); i++) {
4293 long_opts[i] = cmd_line_options[i].opt;
4294 short_opts[j++] = long_opts[i].val;
4295 if (long_opts[i].has_arg == required_argument)
4296 short_opts[j++] = ':';
4297 }
4298 }
4299
4300 /*
4301 * Find the long_opts table index where .val field is set to the passed in
4302 * short option value.
4303 */
get_longindex(int short_opt,const struct option * long_opts)4304 static int get_longindex(int short_opt, const struct option *long_opts)
4305 {
4306 int i;
4307
4308 for (i = 0; long_opts[i].name; i++)
4309 if (long_opts[i].val == short_opt)
4310 return i;
4311
4312 /*
4313 * We could never come here as the short options list is compiled
4314 * based on long options table.
4315 */
4316 fprintf(stderr, "Command line error, parameter argument missing\n");
4317 exit(1);
4318
4319 return -1; /* Not reached. */
4320 }
4321
4322 /*
4323 * Combine searching for command line parameters and optional arguments.
4324 *
4325 * The canonical short options description string does not allow to specify
4326 * that a command line argument expects an optional parameter. but gsctool
4327 * users expect to be able to use the following styles for optional
4328 * parameters:
4329 *
4330 * a) -x <param value>
4331 * b) --x_long <param_value>
4332 * c) --x_long=<param_value>
4333 *
4334 * Styles a) and b) are not supported standard getopt_long(), this function
4335 * adds ability to handle cases a) and b).
4336 */
getopt_all(int argc,char * argv[])4337 static int getopt_all(int argc, char *argv[])
4338 {
4339 int longindex = -1;
4340 static char short_opts[2 * ARRAY_SIZE(cmd_line_options)] = {};
4341 static struct option long_opts[ARRAY_SIZE(cmd_line_options) + 1] = {};
4342 int i;
4343
4344 if (!short_opts[0])
4345 set_opt_descriptors(long_opts, short_opts);
4346
4347 i = getopt_long(argc, argv, short_opts, long_opts, &longindex);
4348 if (i != -1) {
4349 if (longindex < 0) {
4350 /*
4351 * longindex is not set, this must have been the short
4352 * option case, Find the long_opts table index based
4353 * on the short option value.
4354 */
4355 longindex = get_longindex(i, long_opts);
4356 }
4357
4358 if (long_opts[longindex].has_arg == optional_argument) {
4359 /*
4360 * This command line option may include an argument,
4361 * let's check if it is there as the next token in the
4362 * command line.
4363 */
4364 if (!optarg && argv[optind] && argv[optind][0] != '-')
4365 /* Yes, it is. */
4366 optarg = argv[optind++];
4367 }
4368 }
4369
4370 return i;
4371 }
4372
get_crashlog(struct transfer_descriptor * td)4373 static int get_crashlog(struct transfer_descriptor *td)
4374 {
4375 uint32_t rv;
4376 uint8_t response[2048] = { 0 };
4377 size_t response_size = sizeof(response);
4378
4379 rv = send_vendor_command(td, VENDOR_CC_GET_CRASHLOG, NULL, 0, response,
4380 &response_size);
4381 if (rv != VENDOR_RC_SUCCESS) {
4382 printf("Get crash log failed. (%X)\n", rv);
4383 return 1;
4384 }
4385
4386 for (size_t i = 0; i < response_size; i++) {
4387 if (i % 64 == 0 && i > 0)
4388 printf("\n");
4389 printf("%02x", response[i]);
4390 }
4391 printf("\n");
4392 return 0;
4393 }
4394
get_console_logs(struct transfer_descriptor * td)4395 static int get_console_logs(struct transfer_descriptor *td)
4396 {
4397 uint32_t rv;
4398 uint8_t response[2048] = { 0 };
4399 size_t response_size = sizeof(response);
4400
4401 rv = send_vendor_command(td, VENDOR_CC_GET_CONSOLE_LOGS, NULL, 0,
4402 response, &response_size);
4403 if (rv != VENDOR_RC_SUCCESS) {
4404 printf("Get console logs failed. (%X)\n", rv);
4405 return 1;
4406 }
4407
4408 printf("%s", response);
4409 printf("\n");
4410 return 0;
4411 }
4412
process_get_factory_config(struct transfer_descriptor * td)4413 static int process_get_factory_config(struct transfer_descriptor *td)
4414 {
4415 uint32_t rv;
4416 uint64_t response = 0;
4417 size_t response_size = sizeof(response);
4418
4419 rv = send_vendor_command(td, VENDOR_CC_GET_FACTORY_CONFIG, NULL, 0,
4420 (uint8_t *)&response, &response_size);
4421 if (rv != VENDOR_RC_SUCCESS) {
4422 printf("Get factory config failed. (%X)\n", rv);
4423 return 1;
4424 }
4425
4426 if (response_size < sizeof(uint64_t)) {
4427 printf("Unexpected response size. (%zu)", response_size);
4428 return 2;
4429 }
4430
4431 uint64_t out = be64toh(response);
4432 bool is_x_branded = (out >> 4) & 1;
4433 uint8_t compliance_version = out & 0xF;
4434
4435 printf("raw value: %016" PRIX64 "\n", out);
4436 printf("chassis_x_branded: %s\n", is_x_branded ? "true" : "false");
4437 printf("hw_x_compliance_version: %02X\n", compliance_version);
4438 return 0;
4439 }
4440
process_set_factory_config(struct transfer_descriptor * td,uint64_t val)4441 static int process_set_factory_config(struct transfer_descriptor *td,
4442 uint64_t val)
4443 {
4444 uint64_t val_be = htobe64(val);
4445 uint32_t rv;
4446
4447 rv = send_vendor_command(td, VENDOR_CC_SET_FACTORY_CONFIG, &val_be,
4448 sizeof(val_be), NULL, NULL);
4449 if (rv != VENDOR_RC_SUCCESS) {
4450 printf("Factory config failed. (%X)\n", rv);
4451 return 1;
4452 }
4453
4454 return 0;
4455 }
4456
process_get_time(struct transfer_descriptor * td)4457 static int process_get_time(struct transfer_descriptor *td)
4458 {
4459 uint32_t rv;
4460 uint64_t response = 0;
4461 size_t response_size = sizeof(response);
4462
4463 rv = send_vendor_command(td, VENDOR_CC_GET_TIME, NULL, 0,
4464 (uint8_t *)&response, &response_size);
4465 if (rv != VENDOR_RC_SUCCESS) {
4466 printf("Get time failed. (%X)\n", rv);
4467 return 1;
4468 }
4469
4470 if (response_size < sizeof(uint64_t)) {
4471 printf("Unexpected response size. (%zu)", response_size);
4472 return 2;
4473 }
4474
4475 uint64_t out = be64toh(response);
4476
4477 printf("%" PRIu64 "\n", out);
4478 return 0;
4479 }
4480
print_ti50_misc_status(uint32_t misc_status,uint32_t version)4481 static void print_ti50_misc_status(uint32_t misc_status, uint32_t version)
4482 {
4483 misc_status = be32toh(misc_status);
4484 printf("misc_status (%d): %08x\n", version, misc_status);
4485 printf(" rdd_keepalive: %d\n",
4486 misc_status & METRICSV_RDD_KEEP_ALIVE_MASK);
4487 printf(" rdd_keepalive_at_boot: %d\n",
4488 (misc_status & METRICSV_RDD_KEEP_ALIVE_AT_BOOT_MASK) >>
4489 METRICSV_RDD_KEEP_ALIVE_AT_BOOT_SHIFT);
4490 printf(" ccd_mode: %d\n",
4491 (misc_status & METRICSV_CCD_MODE_MASK) >>
4492 METRICSV_CCD_MODE_SHIFT);
4493 if (version < 3)
4494 return;
4495 /* Display metrics added in version 3 */
4496 printf(" wp_asserted: %d\n",
4497 (misc_status & METRICSV_WP_ASSERTED_MASK) >>
4498 METRICSV_WP_ASSERTED_SHIFT);
4499 printf(" allow_unverified_ro: %d\n",
4500 (misc_status & METRICSV_ALLOW_UNVERIFIED_RO_MASK) >>
4501 METRICSV_ALLOW_UNVERIFIED_RO_SHIFT);
4502 printf(" is_prod: %d\n",
4503 (misc_status & METRICSV_IS_PROD_MASK) >> METRICSV_IS_PROD_SHIFT);
4504 }
4505
print_ti50_stats(struct ti50_stats_v0 * stats_v0,size_t size)4506 static int print_ti50_stats(struct ti50_stats_v0 *stats_v0, size_t size)
4507 {
4508 stats_v0->fs_init_time = be32toh(stats_v0->fs_init_time);
4509 stats_v0->fs_usage = be32toh(stats_v0->fs_usage);
4510 stats_v0->aprov_time = be32toh(stats_v0->aprov_time);
4511 stats_v0->expanded_aprov_status =
4512 be32toh(stats_v0->expanded_aprov_status);
4513
4514 printf("fs_init_time: %d\n", stats_v0->fs_init_time);
4515 printf("fs_usage: %d\n", stats_v0->fs_usage);
4516 printf("aprov_time: %d\n", stats_v0->aprov_time);
4517 printf("expanded_aprov_status: %X\n", stats_v0->expanded_aprov_status);
4518
4519 if (size == sizeof(struct ti50_stats_v1)) {
4520 struct ti50_stats_v1 *stats_v1 =
4521 (struct ti50_stats_v1 *)stats_v0;
4522 print_ti50_misc_status(stats_v1->misc_status, 1);
4523 return 0;
4524 }
4525 if (size >= sizeof(struct ti50_stats)) {
4526 struct ti50_stats *stats = (struct ti50_stats *)stats_v0;
4527
4528 stats->version = be32toh(stats->version);
4529 /* Version was added with v2 and therefore must be >= 2. */
4530 if (stats->version < 2) {
4531 printf("Invalid stats version %d.", stats->version);
4532 return 1;
4533 }
4534
4535 stats->filesystem_busy_count =
4536 be32toh(stats->filesystem_busy_count);
4537 stats->crypto_busy_count = be32toh(stats->crypto_busy_count);
4538 stats->dispatcher_busy_count =
4539 be32toh(stats->dispatcher_busy_count);
4540 stats->timeslices_expired = be32toh(stats->timeslices_expired);
4541 stats->crypto_init_time = be32toh(stats->crypto_init_time);
4542
4543 printf("filesystem_busy_count: %d\n",
4544 stats->filesystem_busy_count);
4545 printf("crypto_busy_count: %d\n", stats->crypto_busy_count);
4546 printf("dispatcher_busy_count: %d\n",
4547 stats->dispatcher_busy_count);
4548 printf("timeslices_expired: %d\n",
4549 stats->timeslices_expired);
4550 printf("crypto_init_time: %d\n", stats->crypto_init_time);
4551 print_ti50_misc_status(stats->v1.misc_status, stats->version);
4552 }
4553 return 0;
4554 }
4555
process_ti50_get_metrics(struct transfer_descriptor * td,bool show_machine_output)4556 static int process_ti50_get_metrics(struct transfer_descriptor *td,
4557 bool show_machine_output)
4558 {
4559 uint32_t rv;
4560 /* Allocate extra space in case future versions add more data. */
4561 struct ti50_stats response[4];
4562 size_t response_size = sizeof(response);
4563
4564 rv = send_vendor_command(td, VENDOR_CC_GET_TI50_STATS, NULL, 0,
4565 (uint8_t *)&response, &response_size);
4566 if (rv != VENDOR_RC_SUCCESS) {
4567 printf("Get stats failed. (%X)\n", rv);
4568 return 1;
4569 }
4570
4571 if (response_size < sizeof(struct ti50_stats_v0)) {
4572 printf("Unexpected response size. (%zu)\n", response_size);
4573 return 2;
4574 }
4575
4576 if (show_machine_output) {
4577 uint8_t *raw_response = (uint8_t *)response;
4578
4579 for (size_t i = 0; i < response_size; i++)
4580 printf("%02X", raw_response[i]);
4581 } else {
4582 return print_ti50_stats((struct ti50_stats_v0 *)response,
4583 response_size);
4584 }
4585 return 0;
4586 }
4587
process_cr50_get_metrics(struct transfer_descriptor * td,bool show_machine_output)4588 static int process_cr50_get_metrics(struct transfer_descriptor *td,
4589 bool show_machine_output)
4590 {
4591 /* Allocate extra space in case future versions add more data. */
4592 struct cr50_stats_response response[4] = {};
4593 size_t response_size = sizeof(response);
4594 struct cr50_stats_response stats;
4595 uint32_t rv;
4596
4597 rv = send_vendor_command(td, VENDOR_CC_GET_CR50_METRICS, NULL, 0,
4598 (uint8_t *)&response, &response_size);
4599 if (rv != VENDOR_RC_SUCCESS) {
4600 printf("Get stats failed. (%X)\n", rv);
4601 return 1;
4602 }
4603
4604 if (response_size != sizeof(stats)) {
4605 printf("Unexpected response size. (%zu)\n", response_size);
4606 return 2;
4607 }
4608
4609 /* Let's check if this is a newer version response. */
4610 memcpy(&stats, response, sizeof(stats));
4611
4612 stats.version = be32toh(stats.version);
4613 stats.reset_src = be32toh(stats.reset_src);
4614 stats.brdprop = be32toh(stats.brdprop);
4615 stats.reset_time_s = be64toh(stats.reset_time_s);
4616 stats.cold_reset_time_s = be32toh(stats.cold_reset_time_s);
4617 stats.misc_status = be32toh(stats.misc_status);
4618
4619 if (stats.version > CR50_METRICSV_STATS_VERSION) {
4620 fprintf(stderr, "unsupported ver - %d. supports up to %d\n",
4621 stats.version, CR50_METRICSV_STATS_VERSION);
4622 }
4623 printf("version: %10u\n", stats.version);
4624 printf("reset_src: 0x%010x\n", stats.reset_src);
4625 printf("brdprop: 0x%010x\n", stats.brdprop);
4626 printf("cold_reset_time_s: %10u\n", stats.cold_reset_time_s);
4627 printf("reset_time_s: %10u\n", stats.reset_time_s);
4628 printf("misc_status: 0x%010x\n", stats.misc_status);
4629
4630 printf(" rdd detected: %7d\n",
4631 (stats.misc_status >> CR50_METRICSV_RDD_IS_DETECTED_SHIFT) & 1);
4632 printf(" rddkeeplive en: %7d\n",
4633 (stats.misc_status >> CR50_METRICSV_RDD_KEEPALIVE_EN_SHIFT) & 1);
4634 printf(" rddkeeplive en atboot: %3d\n",
4635 (stats.misc_status >>
4636 CR50_METRICSV_RDD_KEEPALIVE_EN_ATBOOT_SHIFT) &
4637 1);
4638 printf(" ccd_mode en: %7d\n",
4639 (stats.misc_status >> CR50_METRICSV_CCD_MODE_EN_SHIFT) & 1);
4640 printf(" ambigous straps: %7d\n",
4641 (stats.misc_status >> CR50_METRICSV_AMBIGUOUS_STRAP_SHIFT) & 1);
4642
4643 return 0;
4644 }
4645
4646 /*
4647 * The below variables and array must be held in sync with the appropriate
4648 * counterparts in defined in ti50:common/{hil,capsules}/src/boot_tracer.rs.
4649 */
4650 #define MAX_BOOT_TRACE_SIZE 54
4651 #define TIMESPAN_EVENT 0
4652 #define TIME_SHIFT 11
4653 #define MAX_TIME_MS (1 << TIME_SHIFT)
4654 static const char *const boot_tracer_stages[] = {
4655 "Timespan", /* This one will not be displayed separately. */
4656 "ProjectStart", "EcRstAsserted", "EcRstDeasserted",
4657 "TpmRstAsserted", "TpmRstDeasserted", "FirstApComms",
4658 "PcrExtension", "TpmAppReady"
4659 };
4660
process_get_boot_trace(struct transfer_descriptor * td,bool erase,bool show_machine_output)4661 static int process_get_boot_trace(struct transfer_descriptor *td, bool erase,
4662 bool show_machine_output)
4663 {
4664 /* zero means no erase, 1 means erase. */
4665 uint32_t payload = htobe32(erase);
4666 uint16_t boot_trace[MAX_BOOT_TRACE_SIZE / sizeof(uint16_t)];
4667 size_t response_size = sizeof(boot_trace);
4668 uint32_t rv;
4669 uint64_t timespan = 0;
4670 size_t i;
4671
4672 rv = send_vendor_command(td, VENDOR_CC_GET_BOOT_TRACE, &payload,
4673 sizeof(payload), &boot_trace, &response_size);
4674
4675 if (rv != VENDOR_RC_SUCCESS) {
4676 printf("Get boot trace failed. (%X)\n", rv);
4677 return 1;
4678 }
4679
4680 if (response_size == 0)
4681 return 0; /* Trace is empty. */
4682
4683 if (!show_machine_output)
4684 printf(" got %zd bytes back:\n", response_size);
4685 if (response_size > 0) {
4686 for (i = 0; i < response_size / sizeof(uint16_t); i++) {
4687 uint16_t entry = boot_trace[i];
4688 uint16_t event_id = entry >> TIME_SHIFT;
4689 uint16_t delta_time = entry & ((1 << TIME_SHIFT) - 1);
4690
4691 if (show_machine_output) {
4692 printf(" %04x", entry);
4693 continue;
4694 }
4695
4696 if (event_id >= ARRAY_SIZE(boot_tracer_stages)) {
4697 printf("Unknown event %d\n", event_id);
4698 continue;
4699 }
4700
4701 if (event_id == TIMESPAN_EVENT) {
4702 timespan += (uint64_t)delta_time * MAX_TIME_MS;
4703 continue;
4704 }
4705 printf(" %20s: %4" PRId64 " ms\n",
4706 boot_tracer_stages[event_id],
4707 timespan + delta_time);
4708 timespan = 0;
4709 }
4710 printf("\n");
4711 }
4712 return 0;
4713 }
4714
4715 struct get_chip_id_response {
4716 uint32_t tpm_vid_pid;
4717 uint32_t chip_id;
4718 };
4719
get_chip_id_info(struct transfer_descriptor * td)4720 static struct get_chip_id_response get_chip_id_info(
4721 struct transfer_descriptor *td)
4722 {
4723 uint32_t rv;
4724 struct get_chip_id_response response;
4725 size_t response_size = sizeof(response);
4726
4727 rv = send_vendor_command(td, VENDOR_CC_GET_CHIP_ID, NULL, 0,
4728 (uint8_t *)&response, &response_size);
4729 if (rv != VENDOR_RC_SUCCESS) {
4730 debug("Failed getting chip id: 0x%X. Okay for older chips\n",
4731 rv);
4732 } else if (response_size < sizeof(response)) {
4733 debug("Unexpected response size. (%zu)\n", response_size);
4734 } else {
4735 /* Success, convert endianness then return */
4736 response.tpm_vid_pid = be32toh(response.tpm_vid_pid);
4737 response.chip_id = be32toh(response.chip_id);
4738 return response;
4739 }
4740 /* Zero memory before returning since there was an error */
4741 memset(&response, 0, sizeof(response));
4742 return response;
4743 }
4744
4745 /*
4746 * Returns the GSC device type determine by how is responds to TPMV and
4747 * version requests.
4748 */
determine_gsc_type(struct transfer_descriptor * td)4749 static enum gsc_device determine_gsc_type(struct transfer_descriptor *td)
4750 {
4751 int epoch;
4752 int major;
4753 struct get_chip_id_response chip_id;
4754
4755 /*
4756 * Get the firmware version first. See if this is a specific GSC version
4757 * where the Ti50 FW does not response with an error code if the host
4758 * tries an unknown TPMV command over USB. This prevents a USB timeout
4759 * and shutting down of USB subsystem within gsctool (b/368631328).
4760 */
4761 get_version(td, false);
4762 epoch = targ.shv[1].epoch;
4763 major = targ.shv[1].major;
4764 if ((epoch == 0 || epoch == 1) && (major >= 21 && major <= 26))
4765 return GSC_DEVICE_DT;
4766 /*
4767 * Try the newer TPMV command. If the command isn't supported,
4768 * then the GSC should respond with an error. If that happens we will
4769 * fall back to the GSC version as the indicator.
4770 */
4771 chip_id = get_chip_id_info(td);
4772 switch (chip_id.tpm_vid_pid) {
4773 case 0x50666666:
4774 return GSC_DEVICE_NT;
4775 case 0x504a6666:
4776 return GSC_DEVICE_DT;
4777 case 0x00281ae0:
4778 return GSC_DEVICE_H1;
4779 }
4780
4781 if (chip_id.tpm_vid_pid)
4782 fprintf(stderr, "Unregonized VID_PID 0x%X\n",
4783 chip_id.tpm_vid_pid);
4784
4785 /*
4786 * If TPMV command doesn't exist or VID_PID is unrecognized then,
4787 * use the firmware version to determine type.
4788 */
4789 major = targ.shv[1].major;
4790 if (major >= 30 && major < 40)
4791 return GSC_DEVICE_NT;
4792 else if (major >= 20 && major < 30)
4793 return GSC_DEVICE_DT;
4794 else
4795 return GSC_DEVICE_H1;
4796 }
4797
main(int argc,char * argv[])4798 int main(int argc, char *argv[])
4799 {
4800 struct transfer_descriptor td;
4801 int rv = 0;
4802 int errorcnt;
4803 struct image *images = NULL;
4804 int num_images = 0;
4805 uint16_t vid = 0;
4806 uint16_t pid = 0;
4807 int i;
4808 int transferred_sections = 0;
4809 int binary_vers = 0;
4810 int show_fw_ver = 0;
4811 int rma = 0;
4812 const char *rma_auth_code = "";
4813 int get_endorsement_seed = 0;
4814 const char *endorsement_seed_str = "";
4815 int corrupt_inactive_rw = 0;
4816 struct board_id bid;
4817 enum board_id_action bid_action;
4818 int password = 0;
4819 int ccd_open = 0;
4820 int ccd_unlock = 0;
4821 int ccd_lock = 0;
4822 int ccd_info = 0;
4823 int get_flog = 0;
4824 uint32_t prev_log_entry = 0;
4825 enum wp_options wp = WP_NONE;
4826 int get_boot_mode = 0;
4827 int try_all_transfer = 0;
4828 int tpm_mode = 0;
4829 int get_apro_hash = 0;
4830 int get_apro_boot_status = 0;
4831 int start_apro_verify = 0;
4832 bool show_machine_output = false;
4833 int tstamp = 0;
4834 const char *tstamp_arg = NULL;
4835 enum arv_config_spi_addr_mode_e arv_config_spi_addr_mode =
4836 arv_config_spi_addr_mode_none;
4837 enum arv_config_wpsr_choice_e arv_config_wpsr_choice =
4838 arv_config_wpsr_choice_none;
4839 struct arv_config_wpds arv_config_wpds = { 0 };
4840
4841 const char *exclusive_opt_error =
4842 "Options -a, -s and -t are mutually exclusive\n";
4843 const char *openbox_desc_file = NULL;
4844 int factory_mode = 0;
4845 char *factory_mode_arg = "";
4846 char *tpm_mode_arg = NULL;
4847 char *serial = NULL;
4848 int sn_bits = 0;
4849 uint8_t sn_bits_arg[SN_BITS_SIZE];
4850 int sn_inc_rma = 0;
4851 uint8_t sn_inc_rma_arg = 0;
4852 int erase_ap_ro_hash = 0;
4853 int set_capability = 0;
4854 const char *capability_parameter = "";
4855 bool reboot_gsc = false;
4856 size_t reboot_gsc_timeout = 0;
4857 int get_clog = 0;
4858 int get_console = 0;
4859 int factory_config = 0;
4860 int set_factory_config = 0;
4861 uint64_t factory_config_arg = 0;
4862 int get_time = 0;
4863 bool get_boot_trace = false;
4864 bool erase_boot_trace = false;
4865 bool get_metrics = false;
4866 bool get_chassis_open = false;
4867 bool get_dev_ids = false;
4868 bool get_aprov_reset_counts = false;
4869
4870 /*
4871 * All options which result in setting a Boolean flag to True, along
4872 * with addresses of the flags. Terminated by a zeroed entry.
4873 */
4874 const struct options_map omap[] = {
4875 { 'b', &binary_vers },
4876 { 'c', &corrupt_inactive_rw },
4877 { 'f', &show_fw_ver },
4878 { 'g', &get_boot_mode },
4879 { 'H', &erase_ap_ro_hash },
4880 { 'k', &ccd_lock },
4881 { 'o', &ccd_open },
4882 { 'P', &password },
4883 { 'p', &td.post_reset },
4884 { 'U', &ccd_unlock },
4885 { 'u', &td.upstart_mode },
4886 { 'V', &verbose_mode },
4887 {},
4888 };
4889
4890 /*
4891 * Explicitly sets buffering type to line buffered so that output
4892 * lines can be written to pipe instantly. This is needed when the
4893 * cr50-verify-ro.sh execution in verify_ro is moved from crosh to
4894 * debugd.
4895 */
4896 setlinebuf(stdout);
4897
4898 progname = strrchr(argv[0], '/');
4899 if (progname)
4900 progname++;
4901 else
4902 progname = argv[0];
4903
4904 /* Usb transfer - default mode. */
4905 memset(&td, 0, sizeof(td));
4906 td.ep_type = usb_xfer;
4907
4908 bid_action = bid_none;
4909 errorcnt = 0;
4910 opterr = 0; /* quiet, you */
4911
4912 while ((i = getopt_all(argc, argv)) != -1) {
4913 if (check_boolean(omap, i))
4914 continue;
4915 switch (i) {
4916 case 'A':
4917 get_apro_hash = 1;
4918 break;
4919 case 'a':
4920 if (td.ep_type) {
4921 errorcnt++;
4922 fprintf(stderr, "%s", exclusive_opt_error);
4923 break;
4924 }
4925 try_all_transfer = 1;
4926 /* Try dev_xfer first. */
4927 td.ep_type = dev_xfer;
4928 break;
4929 case 'B':
4930 if (optarg && !strcmp(optarg, "start"))
4931 start_apro_verify = 1;
4932 else
4933 get_apro_boot_status = 1;
4934 break;
4935 case 'C':
4936 if (optarg && !strncmp(optarg, "3byte", strlen(optarg)))
4937 arv_config_spi_addr_mode =
4938 arv_config_spi_addr_mode_set_3byte;
4939 else if (optarg &&
4940 !strncmp(optarg, "4byte", strlen(optarg)))
4941 arv_config_spi_addr_mode =
4942 arv_config_spi_addr_mode_set_4byte;
4943 else
4944 arv_config_spi_addr_mode =
4945 arv_config_spi_addr_mode_get;
4946 break;
4947 case 'D':
4948 /* Option is deprecated and igorned */
4949 break;
4950 case 'd':
4951 if (!parse_vidpid(optarg, &vid, &pid)) {
4952 fprintf(stderr,
4953 "Invalid device argument: \"%s\"\n",
4954 optarg);
4955 errorcnt++;
4956 }
4957 break;
4958 case 'e':
4959 get_endorsement_seed = 1;
4960 endorsement_seed_str = optarg;
4961 break;
4962 case 'E':
4963 if (!optarg) {
4964 arv_config_wpsr_choice =
4965 arv_config_wpsr_choice_get;
4966 } else if (optarg && strlen(optarg) > 0) {
4967 arv_config_wpds.data[0].state =
4968 arv_config_setting_state_not_present;
4969 arv_config_wpds.data[1].state =
4970 arv_config_setting_state_not_present;
4971 arv_config_wpds.data[2].state =
4972 arv_config_setting_state_not_present;
4973
4974 rv = parse_wpsrs(optarg, &arv_config_wpds);
4975 if (rv == 2 || rv == 4 || rv == 6) {
4976 arv_config_wpsr_choice =
4977 arv_config_wpsr_choice_set;
4978 } else {
4979 fprintf(stderr,
4980 "Invalid write protect descriptors "
4981 "hex string: \"%s\"\n",
4982 optarg);
4983 exit(update_error);
4984 }
4985 } else {
4986 fprintf(stderr,
4987 "Invalid the write protect descriptors "
4988 "hex string length\n");
4989 exit(update_error);
4990 }
4991
4992 break;
4993 case 'F':
4994 factory_mode = 1;
4995 factory_mode_arg = optarg;
4996 break;
4997 case 'G':
4998 get_time = 1;
4999 break;
5000 case 'h':
5001 usage(errorcnt);
5002 break;
5003 case 'I':
5004 if (optarg) {
5005 set_capability = 1;
5006 capability_parameter = optarg;
5007 } else {
5008 ccd_info = 1;
5009 }
5010 break;
5011 case 'i':
5012 if (!parse_bid(optarg, &bid, &bid_action)) {
5013 fprintf(stderr,
5014 "Invalid board id argument: \"%s\"\n",
5015 optarg);
5016 errorcnt++;
5017 }
5018 break;
5019 case 'J':
5020 get_boot_trace = true;
5021 if (!optarg)
5022 break;
5023 if (strncasecmp(optarg, "erase", strlen(optarg))) {
5024 fprintf(stderr,
5025 "Invalid boot trace argument: "
5026 "\"%s\"\n",
5027 optarg);
5028 errorcnt++;
5029 }
5030 erase_boot_trace = true;
5031 break;
5032 case 'K':
5033 if (!strncasecmp(optarg, "chassis_open",
5034 strlen(optarg))) {
5035 get_chassis_open = true;
5036 } else if (!strncasecmp(optarg, "dev_ids",
5037 strlen(optarg))) {
5038 get_dev_ids = true;
5039 } else if (!strncasecmp(optarg,
5040 "aprov_gsc_reset_counts",
5041 strlen(optarg))) {
5042 /*
5043 * Note: This is a temporary command that allows
5044 * us to collect UMA metrics for how many times
5045 * the GSC would have been reset due to the AP
5046 * RO verification feature.
5047 *
5048 * Once the feature is rolled out, remove this
5049 * command line option. That is also why this
5050 * sub-command is not advertised in the help
5051 * menu.
5052 */
5053 get_aprov_reset_counts = true;
5054 } else {
5055 fprintf(stderr,
5056 "Invalid get_value argument: "
5057 "\"%s\"\n",
5058 optarg);
5059 errorcnt++;
5060 }
5061 break;
5062 case 'L':
5063 get_flog = 1;
5064 if (optarg)
5065 prev_log_entry = strtoul(optarg, NULL, 0);
5066 break;
5067 case 'l':
5068 get_console = 1;
5069 break;
5070 case 'M':
5071 show_machine_output = true;
5072 break;
5073 case 'm':
5074 tpm_mode = 1;
5075 tpm_mode_arg = optarg;
5076 break;
5077 case 'n':
5078 serial = optarg;
5079 break;
5080 case 'O':
5081 openbox_desc_file = optarg;
5082 break;
5083 case 'q':
5084 td.force_ro = 1;
5085 break;
5086 case 'r':
5087 rma = 1;
5088 rma_auth_code = optarg;
5089 break;
5090 case 'R':
5091 sn_inc_rma = 1;
5092 if (!parse_sn_inc_rma(optarg, &sn_inc_rma_arg)) {
5093 fprintf(stderr,
5094 "Invalid sn_rma_inc argument: \"%s\"\n",
5095 optarg);
5096 errorcnt++;
5097 }
5098
5099 break;
5100 case 's':
5101 if (td.ep_type || try_all_transfer) {
5102 errorcnt++;
5103 fprintf(stderr, "%s", exclusive_opt_error);
5104 break;
5105 }
5106 td.ep_type = dev_xfer;
5107 break;
5108 case 'S':
5109 sn_bits = 1;
5110 if (!parse_sn_bits(optarg, sn_bits_arg)) {
5111 fprintf(stderr,
5112 "Invalid sn_bits argument: \"%s\"\n",
5113 optarg);
5114 errorcnt++;
5115 }
5116
5117 break;
5118 case 't':
5119 if (td.ep_type || try_all_transfer) {
5120 errorcnt++;
5121 fprintf(stderr, "%s", exclusive_opt_error);
5122 break;
5123 }
5124 td.ep_type = ts_xfer;
5125 break;
5126 case 'T':
5127 tstamp = 1;
5128 tstamp_arg = optarg;
5129 break;
5130 case 'v':
5131 report_version(); /* This will call exit(). */
5132 break;
5133 case 'W':
5134 get_metrics = true;
5135 break;
5136 case 'w':
5137 if (!optarg) {
5138 wp = WP_CHECK;
5139 break;
5140 }
5141 if (!strcasecmp(optarg, "enable")) {
5142 wp = WP_ENABLE;
5143 break;
5144 }
5145 if (!strcasecmp(optarg, "disable")) {
5146 wp = WP_DISABLE;
5147 break;
5148 }
5149 if (!strcasecmp(optarg, "follow")) {
5150 wp = WP_FOLLOW;
5151 break;
5152 }
5153 fprintf(stderr, "Illegal wp option \"%s\"\n", optarg);
5154 errorcnt++;
5155 break;
5156 case 'x':
5157 get_clog = 1;
5158 break;
5159 case 'y':
5160 factory_config = 1;
5161 if (optarg) {
5162 set_factory_config = 1;
5163 factory_config_arg = strtoull(optarg, NULL, 16);
5164 }
5165 break;
5166 case 'z':
5167 reboot_gsc = true;
5168 /* Set a 1ms default reboot time to avoid libusb errors
5169 * when the GSC resets too quickly.
5170 */
5171 reboot_gsc_timeout = 1;
5172 if (optarg)
5173 reboot_gsc_timeout = strtoul(optarg, NULL, 0);
5174 break;
5175 case 0: /* auto-handled option */
5176 break;
5177 case '?':
5178 if (optopt)
5179 fprintf(stderr, "Unrecognized option: -%c\n",
5180 optopt);
5181 else
5182 fprintf(stderr, "Unrecognized option: %s\n",
5183 argv[optind - 1]);
5184 errorcnt++;
5185 break;
5186 case ':':
5187 fprintf(stderr, "Missing argument to %s\n",
5188 argv[optind - 1]);
5189 errorcnt++;
5190 break;
5191 default:
5192 fprintf(stderr, "Internal error at %s:%d\n", __FILE__,
5193 __LINE__);
5194 exit(update_error);
5195 }
5196 }
5197
5198 if (errorcnt)
5199 usage(errorcnt);
5200
5201 if ((bid_action == bid_none) &&
5202 (arv_config_spi_addr_mode == arv_config_spi_addr_mode_none) &&
5203 (arv_config_wpsr_choice == arv_config_wpsr_choice_none) &&
5204 !ccd_info && !ccd_lock && !ccd_open && !ccd_unlock &&
5205 !corrupt_inactive_rw && !get_apro_hash && !get_apro_boot_status &&
5206 !get_boot_mode && !get_boot_trace && !get_clog && !get_console &&
5207 !get_flog && !get_endorsement_seed && !get_metrics && !get_time &&
5208 !factory_config && !factory_mode && !erase_ap_ro_hash &&
5209 !password && !reboot_gsc && !rma && !set_capability &&
5210 !show_fw_ver && !sn_bits && !sn_inc_rma && !start_apro_verify &&
5211 !openbox_desc_file && !tstamp && !tpm_mode && (wp == WP_NONE) &&
5212 !get_chassis_open && !get_dev_ids && !get_aprov_reset_counts) {
5213 num_images = argc - optind;
5214 if (num_images <= 0) {
5215 fprintf(stderr,
5216 "\nERROR: Missing required <binary image>\n\n");
5217 usage(1);
5218 }
5219
5220 images = malloc(sizeof(struct image) * num_images);
5221
5222 for (i = 0; i < num_images; i++) {
5223 images[i].data = get_file_or_die(argv[optind + i],
5224 &images[i].data_len);
5225 images[i].file_path = argv[optind + i];
5226 printf("read %zd(%#zx) bytes from %s\n",
5227 images[i].data_len, images[i].data_len,
5228 images[i].file_path);
5229
5230 /* Validate images and locate headers within image */
5231 if (!locate_headers(&images[i]))
5232 exit(update_error);
5233
5234 if (!fetch_header_versions(&images[i]))
5235 exit(update_error);
5236
5237 if (binary_vers) {
5238 int error = show_headers_versions(
5239 &images[i], show_machine_output);
5240 if (error)
5241 exit(error);
5242 }
5243 }
5244 /* If displaying versions, exit now since we're done. */
5245 if (binary_vers)
5246 exit(0);
5247 } else {
5248 if (optind < argc)
5249 printf("Ignoring binary image %s\n", argv[optind]);
5250 }
5251
5252 if (((bid_action != bid_none) + !!rma + !!password + !!ccd_open +
5253 !!ccd_unlock + !!ccd_lock + !!ccd_info + !!get_flog +
5254 !!get_boot_mode + !!openbox_desc_file + !!factory_mode +
5255 (wp != WP_NONE) + !!get_endorsement_seed + !!erase_ap_ro_hash +
5256 !!set_capability + !!get_clog + !!get_console) > 1) {
5257 fprintf(stderr,
5258 "Error: options "
5259 "-e, -F, -g, -H, -I, -i, -k, -L, -l, -O, -o, -P, -r,"
5260 "-U, -x and -w are mutually exclusive\n");
5261 exit(update_error);
5262 }
5263
5264 if (td.ep_type == usb_xfer) {
5265 /* Extra variables only used to prevent 80+ character lines */
5266 const uint16_t subclass = USB_SUBCLASS_GOOGLE_CR50;
5267 const uint16_t protocol =
5268 USB_PROTOCOL_GOOGLE_CR50_NON_HC_FW_UPDATE;
5269 uint16_t pids[] = { H1_PID, D2_PID, NT_PID };
5270 int pid_count = ARRAY_SIZE(pids);
5271
5272 /*
5273 * If no usb device information was given, use default vid and
5274 * pids to search for GSC devices.
5275 */
5276 if (!vid)
5277 vid = USB_VID_GOOGLE;
5278 if (pid) {
5279 pids[0] = pid;
5280 pid_count = 1;
5281 }
5282 if (usb_findit(serial, vid, pids, pid_count, subclass, protocol,
5283 &td.uep)) {
5284 fprintf(stderr,
5285 "ERROR: Cannot find single GSC device\n");
5286 exit(update_error);
5287 }
5288 } else if (td.ep_type == dev_xfer) {
5289 td.tpm_fd = open("/dev/tpm0", O_RDWR);
5290 if (td.tpm_fd < 0) {
5291 if (!try_all_transfer) {
5292 perror("Could not open TPM");
5293 exit(update_error);
5294 }
5295 td.ep_type = ts_xfer;
5296 }
5297 }
5298
5299 /* Perform run selection of GSC device now that we have a connection */
5300 gsc_dev = determine_gsc_type(&td);
5301
5302 if (openbox_desc_file)
5303 return verify_ro(&td, openbox_desc_file, show_machine_output);
5304
5305 if (ccd_unlock || ccd_open || ccd_lock || ccd_info)
5306 process_ccd_state(&td, ccd_unlock, ccd_open, ccd_lock, ccd_info,
5307 show_machine_output);
5308
5309 if (set_capability)
5310 exit(process_set_capabililty(&td, capability_parameter));
5311
5312 if (password)
5313 process_password(&td);
5314
5315 if (bid_action != bid_none)
5316 process_bid(&td, bid_action, &bid, show_machine_output);
5317
5318 if (get_endorsement_seed)
5319 exit(process_endorsement_seed(&td, endorsement_seed_str));
5320
5321 if (rma)
5322 process_rma(&td, rma_auth_code, show_machine_output);
5323
5324 if (factory_mode)
5325 process_factory_mode(&td, factory_mode_arg);
5326 if (wp != WP_NONE)
5327 exit(process_wp(&td, wp));
5328
5329 if (get_chassis_open)
5330 exit(process_get_chassis_open(&td));
5331
5332 if (get_dev_ids)
5333 exit(process_get_dev_ids(&td, show_machine_output));
5334
5335 if (get_aprov_reset_counts)
5336 exit(process_get_aprov_reset_counts(&td));
5337
5338 if (corrupt_inactive_rw)
5339 invalidate_inactive_rw(&td);
5340
5341 if (tpm_mode) {
5342 int rv = process_tpm_mode(&td, tpm_mode_arg);
5343
5344 exit(rv);
5345 }
5346
5347 if (tstamp)
5348 return process_tstamp(&td, tstamp_arg);
5349
5350 if (sn_bits)
5351 process_sn_bits(&td, sn_bits_arg);
5352
5353 if (sn_inc_rma)
5354 process_sn_inc_rma(&td, sn_inc_rma_arg);
5355
5356 if (get_apro_hash)
5357 exit(process_get_apro_hash(&td));
5358
5359 if (get_apro_boot_status)
5360 exit(process_get_apro_boot_status(&td));
5361
5362 if (start_apro_verify)
5363 exit(process_start_apro_verify(&td));
5364
5365 if (get_boot_mode)
5366 exit(process_get_boot_mode(&td));
5367
5368 if (get_flog)
5369 process_get_flog(&td, prev_log_entry, show_machine_output);
5370
5371 if (erase_ap_ro_hash)
5372 process_erase_ap_ro_hash(&td);
5373
5374 if (arv_config_spi_addr_mode)
5375 exit(process_arv_config_spi_addr_mode(
5376 &td, arv_config_spi_addr_mode));
5377
5378 if (arv_config_wpsr_choice)
5379 exit(process_arv_config_wpds(&td, arv_config_wpsr_choice,
5380 &arv_config_wpds));
5381
5382 if (reboot_gsc)
5383 exit(process_reboot_gsc(&td, reboot_gsc_timeout));
5384
5385 if (get_clog)
5386 exit(get_crashlog(&td));
5387
5388 if (get_console)
5389 exit(get_console_logs(&td));
5390
5391 if (factory_config) {
5392 if (set_factory_config)
5393 exit(process_set_factory_config(&td,
5394 factory_config_arg));
5395 else
5396 exit(process_get_factory_config(&td));
5397 }
5398
5399 if (get_time) {
5400 exit(process_get_time(&td));
5401 }
5402
5403 if (get_boot_trace)
5404 exit(process_get_boot_trace(&td, erase_boot_trace,
5405 show_machine_output));
5406
5407 if (get_metrics) {
5408 if (is_ti50_device())
5409 exit(process_ti50_get_metrics(&td,
5410 show_machine_output));
5411 else
5412 exit(process_cr50_get_metrics(&td,
5413 show_machine_output));
5414 }
5415
5416 if (images || show_fw_ver) {
5417 struct image *match = NULL;
5418
5419 /* Find the matching image for the runtime-determined device */
5420 for (i = 0; i < num_images; i++) {
5421 if (images[i].type == gsc_dev) {
5422 if (match) {
5423 fprintf(stderr,
5424 "ERROR: Must only specify a "
5425 "single image for each chip "
5426 "type.\n");
5427 exit(update_error);
5428 }
5429 match = &images[i];
5430 }
5431 }
5432
5433 if (images && !match) {
5434 fprintf(stderr,
5435 "ERROR: No images matches chip type.\n");
5436 exit(update_error);
5437 }
5438
5439 setup_connection(&td);
5440
5441 if (match) {
5442 if (num_images > 1) {
5443 printf("Using file for update: %s\n",
5444 match->file_path);
5445 }
5446 transferred_sections = transfer_image(&td, match);
5447 }
5448
5449 /* Free images */
5450 match = NULL;
5451 for (i = 0; i < num_images; i++)
5452 free(images[i].data);
5453 free(images);
5454 images = NULL;
5455
5456 /*
5457 * Move USB updater sate machine to idle state so that
5458 * vendor commands can be processed later, if any.
5459 */
5460 if (td.ep_type == usb_xfer)
5461 send_done(&td.uep);
5462
5463 if (transferred_sections)
5464 generate_reset_request(&td);
5465
5466 if (show_fw_ver) {
5467 if (show_machine_output) {
5468 print_machine_output("RO_FW_VER", "%d.%d.%d",
5469 targ.shv[0].epoch,
5470 targ.shv[0].major,
5471 targ.shv[0].minor);
5472 print_machine_output("RW_FW_VER", "%d.%d.%d",
5473 targ.shv[1].epoch,
5474 targ.shv[1].major,
5475 targ.shv[1].minor);
5476 } else {
5477 printf("Current versions:\n");
5478 printf("RO %d.%d.%d\n", targ.shv[0].epoch,
5479 targ.shv[0].major, targ.shv[0].minor);
5480 printf("RW %d.%d.%d\n", targ.shv[1].epoch,
5481 targ.shv[1].major, targ.shv[1].minor);
5482 }
5483 }
5484 }
5485
5486 if (td.ep_type == usb_xfer) {
5487 libusb_close(td.uep.devh);
5488 libusb_exit(NULL);
5489 }
5490
5491 if (!transferred_sections)
5492 return noop;
5493
5494 printf("image updated\n");
5495 return all_updated;
5496 }
5497