xref: /aosp_15_r20/external/gsc-utils/extra/usb_updater/gsctool.c (revision 4f2df630800bdcf1d4f0decf95d8a1cb87344f5f)
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(&sections[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(&sections[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