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