Bug Summary

File:3rdparty/vboot/futility/cmd_show.c
Warning:line 798, column 3
Address of stack memory associated with local variable 'pubk2' is still referred to by the global variable 'show_option' upon returning to the caller. This will be a dangling reference

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name cmd_show.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/vboot -resource-dir /opt/xgcc/lib/clang/17 -D CHROMEOS_ENVIRONMENT -D EC_EFS=0 -D EXTERNAL_TPM_CLEAR_REQUEST=0 -D _GNU_SOURCE -D _FILE_OFFSET_BITS=64 -D HAVE_EXECINFO_H -D HAVE_NSS -I /usr/include/nss -I /usr/include/nspr -I firmware/include -I firmware/lib/include -I firmware/lib/cgptlib/include -I firmware/lib/tpm_lite/include -I firmware/2lib/include -I host/include -I host/lib/include -I host/lib21/include -I host/lib21/include -internal-isystem /opt/xgcc/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -source-date-epoch 1714465709 -Os -Wno-deprecated-declarations -Wno-trigraphs -Wwrite-strings -Wno-format-security -Wno-address-of-packed-member -Wno-unknown-warning -Wno-error=deprecated-declarations -std=gnu11 -fconst-strings -fdebug-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/vboot -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-opt-analyze-headers -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /cb-build/coreboot_scanbuild.0/sharedutils-scanbuildtmp/2024-05-02-073004-2299942-1 -x c futility/cmd_show.c
1/* Copyright 2014 The ChromiumOS Authors
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6#include <openssl/rsa.h>
7
8#include <errno(*__errno_location ()).h>
9#include <fcntl.h>
10#include <getopt.h>
11#include <inttypes.h>
12#include <stddef.h>
13#include <stdint.h>
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17#include <sys/stat.h>
18#include <sys/types.h>
19#include <unistd.h>
20
21#include "2api.h"
22#include "2common.h"
23#include "2sha.h"
24#include "2sysincludes.h"
25#include "cbfstool.h"
26#include "file_type_bios.h"
27#include "file_type.h"
28#include "fmap.h"
29#include "futility.h"
30#include "futility_options.h"
31#include "host_common.h"
32#include "host_key21.h"
33#include "host_misc.h"
34#include "util_misc.h"
35#include "vb1_helper.h"
36
37/* Options */
38struct show_option_s show_option = {
39 .type = FILE_TYPE_UNKNOWN,
40};
41
42/* Shared work buffer */
43static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE(80 * 1024)]
44 __attribute__((aligned(VB2_WORKBUF_ALIGN8)));
45static struct vb2_workbuf wb;
46
47void show_pubkey(const struct vb2_packed_key *pubkey, const char *sp)
48{
49 // Clear out formatting if we are in parseable mode.
50 if (show_option.parseable)
51 sp = "\0";
52 FT_PRINT("%sVboot API: 1.0\n", "%sapi::1.0\n", sp)do { do { if (!show_option.parseable) printf("%sVboot API: 1.0\n"
, sp); } while (0); do { if (!show_option.parseable) break; if
(ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("%sapi::1.0\n", sp); } while (0); } while (0)
;
53 FT_PRINT("%sAlgorithm: %d %s\n",do { do { if (!show_option.parseable) printf("%sAlgorithm: %d %s\n"
, sp, pubkey->algorithm, vb2_get_crypto_algorithm_name(pubkey
->algorithm)); } while (0); do { if (!show_option.parseable
) break; if (ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("%salgorithm::%d::%s\n", sp, pubkey->algorithm, vb2_get_crypto_algorithm_name
(pubkey->algorithm)); } while (0); } while (0)
54 "%salgorithm::%d::%s\n",do { do { if (!show_option.parseable) printf("%sAlgorithm: %d %s\n"
, sp, pubkey->algorithm, vb2_get_crypto_algorithm_name(pubkey
->algorithm)); } while (0); do { if (!show_option.parseable
) break; if (ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("%salgorithm::%d::%s\n", sp, pubkey->algorithm, vb2_get_crypto_algorithm_name
(pubkey->algorithm)); } while (0); } while (0)
55 sp, pubkey->algorithm,do { do { if (!show_option.parseable) printf("%sAlgorithm: %d %s\n"
, sp, pubkey->algorithm, vb2_get_crypto_algorithm_name(pubkey
->algorithm)); } while (0); do { if (!show_option.parseable
) break; if (ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("%salgorithm::%d::%s\n", sp, pubkey->algorithm, vb2_get_crypto_algorithm_name
(pubkey->algorithm)); } while (0); } while (0)
56 vb2_get_crypto_algorithm_name(pubkey->algorithm))do { do { if (!show_option.parseable) printf("%sAlgorithm: %d %s\n"
, sp, pubkey->algorithm, vb2_get_crypto_algorithm_name(pubkey
->algorithm)); } while (0); do { if (!show_option.parseable
) break; if (ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("%salgorithm::%d::%s\n", sp, pubkey->algorithm, vb2_get_crypto_algorithm_name
(pubkey->algorithm)); } while (0); } while (0)
;
57 FT_PRINT("%sKey Version: %d\n", "%sversion::%d\n",do { do { if (!show_option.parseable) printf("%sKey Version: %d\n"
, sp, pubkey->key_version); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("%sversion::%d\n", sp
, pubkey->key_version); } while (0); } while (0)
58 sp, pubkey->key_version)do { do { if (!show_option.parseable) printf("%sKey Version: %d\n"
, sp, pubkey->key_version); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("%sversion::%d\n", sp
, pubkey->key_version); } while (0); } while (0)
;
59 FT_PRINT("%sKey sha1sum: %s\n", "%ssha1_sum::%s\n",do { do { if (!show_option.parseable) printf("%sKey sha1sum: %s\n"
, sp, packed_key_sha1_string(pubkey)); } while (0); do { if (
!show_option.parseable) break; if (ft_print_header != ((void*
)0)) printf("%s::", ft_print_header); if (ft_print_header2 !=
((void*)0)) printf("%s::", ft_print_header2); printf("%ssha1_sum::%s\n"
, sp, packed_key_sha1_string(pubkey)); } while (0); } while (
0)
60 sp, packed_key_sha1_string(pubkey))do { do { if (!show_option.parseable) printf("%sKey sha1sum: %s\n"
, sp, packed_key_sha1_string(pubkey)); } while (0); do { if (
!show_option.parseable) break; if (ft_print_header != ((void*
)0)) printf("%s::", ft_print_header); if (ft_print_header2 !=
((void*)0)) printf("%s::", ft_print_header2); printf("%ssha1_sum::%s\n"
, sp, packed_key_sha1_string(pubkey)); } while (0); } while (
0)
;
61}
62
63static void show_keyblock(struct vb2_keyblock *keyblock, const char *print_name,
64 int sign_key, int good_sig)
65{
66 if (print_name)
67 FT_READABLE_PRINT("Keyblock: %s\n", print_name)do { if (!show_option.parseable) printf("Keyblock: %s\n"
, print_name); } while (0)
;
68 else
69 FT_READABLE_PRINT("Keyblock:\n")do { if (!show_option.parseable) printf("Keyblock:\n"); } while
(0)
;
70
71 FT_PRINT(" Signature: %s\n", "signature::%s\n",do { do { if (!show_option.parseable) printf(" Signature: %s\n"
, sign_key ? (good_sig ? "valid" : "invalid") : "ignored"); }
while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("signature::%s\n"
, sign_key ? (good_sig ? "valid" : "invalid") : "ignored"); }
while (0); } while (0)
72 sign_key ? (good_sig ? "valid" : "invalid") : "ignored")do { do { if (!show_option.parseable) printf(" Signature: %s\n"
, sign_key ? (good_sig ? "valid" : "invalid") : "ignored"); }
while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("signature::%s\n"
, sign_key ? (good_sig ? "valid" : "invalid") : "ignored"); }
while (0); } while (0)
;
73 FT_PRINT(" Size: %#x\n",do { do { if (!show_option.parseable) printf(" Size: %#x\n"
, keyblock->keyblock_size); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("size::%d\n", keyblock
->keyblock_size); } while (0); } while (0)
74 "size::%d\n", keyblock->keyblock_size)do { do { if (!show_option.parseable) printf(" Size: %#x\n"
, keyblock->keyblock_size); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("size::%d\n", keyblock
->keyblock_size); } while (0); } while (0)
;
75 FT_PRINT(" Flags: %d ",do { do { if (!show_option.parseable) printf(" Flags: %d "
, keyblock->keyblock_flags); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("flags::%d:", keyblock
->keyblock_flags); } while (0); } while (0)
76 "flags::%d:", keyblock->keyblock_flags)do { do { if (!show_option.parseable) printf(" Flags: %d "
, keyblock->keyblock_flags); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("flags::%d:", keyblock
->keyblock_flags); } while (0); } while (0)
;
77 if (keyblock->keyblock_flags & VB2_KEYBLOCK_FLAG_DEVELOPER_00x1)
78 FT_PRINT_RAW(" !DEV", ":!DEV")printf(show_option.parseable ? ":!DEV" : " !DEV");
79 if (keyblock->keyblock_flags & VB2_KEYBLOCK_FLAG_DEVELOPER_10x2)
80 FT_PRINT_RAW(" DEV", ":DEV")printf(show_option.parseable ? ":DEV" : " DEV");
81 if (keyblock->keyblock_flags & VB2_KEYBLOCK_FLAG_RECOVERY_00x4)
82 FT_PRINT_RAW(" !REC", ":!REC")printf(show_option.parseable ? ":!REC" : " !REC");
83 if (keyblock->keyblock_flags & VB2_KEYBLOCK_FLAG_RECOVERY_10x8)
84 FT_PRINT_RAW(" REC", ":REC")printf(show_option.parseable ? ":REC" : " REC");
85 if (keyblock->keyblock_flags & VB2_KEYBLOCK_FLAG_MINIOS_00x10)
86 FT_PRINT_RAW(" !MINIOS", ":!MINIOS")printf(show_option.parseable ? ":!MINIOS" : " !MINIOS");
87 if (keyblock->keyblock_flags & VB2_KEYBLOCK_FLAG_MINIOS_10x20)
88 FT_PRINT_RAW(" MINIOS", ":MINIOS")printf(show_option.parseable ? ":MINIOS" : " MINIOS");
89 printf("\n");
90
91 struct vb2_packed_key *data_key = &keyblock->data_key;
92 FT_PRINT(" Data key algorithm: %d %s\n",do { do { if (!show_option.parseable) printf(" Data key algorithm: %d %s\n"
, data_key->algorithm, vb2_get_crypto_algorithm_name(data_key
->algorithm)); } while (0); do { if (!show_option.parseable
) break; if (ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("data_key::algorithm::%d::%s\n", data_key->algorithm
, vb2_get_crypto_algorithm_name(data_key->algorithm)); } while
(0); } while (0)
93 "data_key::algorithm::%d::%s\n", data_key->algorithm,do { do { if (!show_option.parseable) printf(" Data key algorithm: %d %s\n"
, data_key->algorithm, vb2_get_crypto_algorithm_name(data_key
->algorithm)); } while (0); do { if (!show_option.parseable
) break; if (ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("data_key::algorithm::%d::%s\n", data_key->algorithm
, vb2_get_crypto_algorithm_name(data_key->algorithm)); } while
(0); } while (0)
94 vb2_get_crypto_algorithm_name(data_key->algorithm))do { do { if (!show_option.parseable) printf(" Data key algorithm: %d %s\n"
, data_key->algorithm, vb2_get_crypto_algorithm_name(data_key
->algorithm)); } while (0); do { if (!show_option.parseable
) break; if (ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("data_key::algorithm::%d::%s\n", data_key->algorithm
, vb2_get_crypto_algorithm_name(data_key->algorithm)); } while
(0); } while (0)
;
95 FT_PRINT(" Data key version: %d\n", "data_key::version::%d\n",do { do { if (!show_option.parseable) printf(" Data key version: %d\n"
, data_key->key_version); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("data_key::version::%d\n"
, data_key->key_version); } while (0); } while (0)
96 data_key->key_version)do { do { if (!show_option.parseable) printf(" Data key version: %d\n"
, data_key->key_version); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("data_key::version::%d\n"
, data_key->key_version); } while (0); } while (0)
;
97 FT_PRINT(" Data key sha1sum: %s\n", "data_key::sha1_sum::%s\n",do { do { if (!show_option.parseable) printf(" Data key sha1sum: %s\n"
, packed_key_sha1_string(data_key)); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("data_key::sha1_sum::%s\n"
, packed_key_sha1_string(data_key)); } while (0); } while (0)
98 packed_key_sha1_string(data_key))do { do { if (!show_option.parseable) printf(" Data key sha1sum: %s\n"
, packed_key_sha1_string(data_key)); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("data_key::sha1_sum::%s\n"
, packed_key_sha1_string(data_key)); } while (0); } while (0)
;
99}
100
101int ft_show_pubkey(const char *fname)
102{
103 int fd = -1;
104 struct vb2_packed_key *pubkey;
105 uint32_t len;
106 int rv = 0;
107
108 if (futil_open_and_map_file(fname, &fd, FILE_RO, (uint8_t **)&pubkey,
109 &len))
110 return 1;
111
112 if (vb2_packed_key_looks_ok(pubkey, len)) {
113 ERROR("Invalid public key: %s\n", fname)fprintf(stderr, "ERROR: %s: " "Invalid public key: %s\n", __func__
, fname )
;
114 rv = 1;
115 goto done;
116 }
117 FT_READABLE_PRINT("Public Key file: %s\n", fname)do { if (!show_option.parseable) printf("Public Key file: %s\n"
, fname); } while (0)
;
118
119 ft_print_header = "pubkey";
120 show_pubkey(pubkey, " ");
121
122done:
123 futil_unmap_and_close_file(fd, FILE_RO, (uint8_t *)pubkey, len);
124 return rv;
125}
126
127int ft_show_privkey(const char *fname)
128{
129 int fd = -1;
130 int rv = 0;
131 struct vb2_packed_private_key *pkey = NULL((void*)0);
132 uint32_t len;
133 struct vb2_private_key key;
134 const unsigned char *start;
135
136 if (futil_open_and_map_file(fname, &fd, FILE_RO, (uint8_t **)&pkey,
137 &len))
138 return 1;
139
140 start = pkey->key_data;
141 if (len <= sizeof(*pkey)) {
142 ERROR("Invalid private key: %s\n", fname)fprintf(stderr, "ERROR: %s: " "Invalid private key: %s\n", __func__
, fname )
;
143 rv = 1;
144 goto done;
145 }
146 len -= sizeof(*pkey);
147 key.rsa_private_key = d2i_RSAPrivateKey(NULL((void*)0), &start, len);
148
149
150 ft_print_header = "prikey";
151 FT_READABLE_PRINT("Private Key file: %s\n", fname)do { if (!show_option.parseable) printf("Private Key file: %s\n"
, fname); } while (0)
;
152 FT_PRINT(" Vboot API: 1.0\n", "api::1.0\n")do { do { if (!show_option.parseable) printf(" Vboot API: 1.0\n"
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("api::1.0\n"
); } while (0); } while (0)
;
153 FT_PRINT(" Algorithm: %u %s\n",do { do { if (!show_option.parseable) printf(" Algorithm: %u %s\n"
, pkey->algorithm, vb2_get_crypto_algorithm_name(pkey->
algorithm)); } while (0); do { if (!show_option.parseable) break
; if (ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("algorithm::%d::%s\n", pkey->algorithm, vb2_get_crypto_algorithm_name
(pkey->algorithm)); } while (0); } while (0)
154 "algorithm::%d::%s\n", pkey->algorithm,do { do { if (!show_option.parseable) printf(" Algorithm: %u %s\n"
, pkey->algorithm, vb2_get_crypto_algorithm_name(pkey->
algorithm)); } while (0); do { if (!show_option.parseable) break
; if (ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("algorithm::%d::%s\n", pkey->algorithm, vb2_get_crypto_algorithm_name
(pkey->algorithm)); } while (0); } while (0)
155 vb2_get_crypto_algorithm_name(pkey->algorithm))do { do { if (!show_option.parseable) printf(" Algorithm: %u %s\n"
, pkey->algorithm, vb2_get_crypto_algorithm_name(pkey->
algorithm)); } while (0); do { if (!show_option.parseable) break
; if (ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("algorithm::%d::%s\n", pkey->algorithm, vb2_get_crypto_algorithm_name
(pkey->algorithm)); } while (0); } while (0)
;
156 FT_PRINT(" Key sha1sum: %s\n", "sha1_sum::%s\n",do { do { if (!show_option.parseable) printf(" Key sha1sum: %s\n"
, private_key_sha1_string(&key)); } while (0); do { if (!
show_option.parseable) break; if (ft_print_header != ((void*)
0)) printf("%s::", ft_print_header); if (ft_print_header2 != (
(void*)0)) printf("%s::", ft_print_header2); printf("sha1_sum::%s\n"
, private_key_sha1_string(&key)); } while (0); } while (0
)
157 private_key_sha1_string(&key))do { do { if (!show_option.parseable) printf(" Key sha1sum: %s\n"
, private_key_sha1_string(&key)); } while (0); do { if (!
show_option.parseable) break; if (ft_print_header != ((void*)
0)) printf("%s::", ft_print_header); if (ft_print_header2 != (
(void*)0)) printf("%s::", ft_print_header2); printf("sha1_sum::%s\n"
, private_key_sha1_string(&key)); } while (0); } while (0
)
;
158
159done:
160 futil_unmap_and_close_file(fd, FILE_RO, (uint8_t *)pkey, len);
161 return rv;
162}
163
164int ft_show_keyblock(const char *fname)
165{
166 struct vb2_keyblock *block;
167 struct vb2_public_key *sign_key = show_option.k;
168 int good_sig = 0;
169 int retval = 0;
170 int fd = -1;
171 uint32_t len;
172
173 if (futil_open_and_map_file(fname, &fd, FILE_RO, (uint8_t **)&block, &len))
174 return 1;
175
176 ft_print_header = "keyblock";
177
178 /* Check the hash only first */
179 if (vb2_verify_keyblock_hash(block, len, &wb)) {
180 ERROR("%s is invalid\n", fname)fprintf(stderr, "ERROR: %s: " "%s is invalid\n", __func__, fname
)
;
181 FT_PARSEABLE_PRINT("invalid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("invalid\n"
); } while (0)
;
182 retval = 1;
183 goto done;
184 } else {
185 FT_PARSEABLE_PRINT("valid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("valid\n"
); } while (0)
;
186 }
187
188 /* Check the signature if we have one */
189 if (sign_key &&
190 VB2_SUCCESS == vb2_verify_keyblock(block, len, sign_key, &wb))
191 good_sig = 1;
192 else if (show_option.strict)
193 retval = 1;
194
195 show_keyblock(block, fname, !!sign_key, good_sig);
196
197done:
198 futil_unmap_and_close_file(fd, FILE_RO, (uint8_t *)block, len);
199 return retval;
200}
201
202static int fw_show_metadata_hash(const char *fname, enum bios_component body_c,
203 struct vb2_fw_preamble *pre)
204{
205 struct vb2_hash real_hash;
206 struct vb2_hash *body_hash =
207 (struct vb2_hash *)vb2_signature_data(&pre->body_signature);
208 const uint32_t bhsize = vb2_digest_size(body_hash->algo);
209
210 if (!bhsize || pre->body_signature.sig_size <
211 offsetof(struct vb2_hash, raw)__builtin_offsetof(struct vb2_hash, raw) + bhsize) {
212 ERROR("Body signature data is too small to fit metadata hash.\n")fprintf(stderr, "ERROR: %s: " "Body signature data is too small to fit metadata hash.\n"
, __func__ )
;
213 return 1;
214 }
215
216 FT_READABLE_PRINT(" Body metadata hash: %s ",do { if (!show_option.parseable) printf(" Body metadata hash: %s "
, vb2_get_hash_algorithm_name(body_hash->algo)); } while (
0)
217 vb2_get_hash_algorithm_name(body_hash->algo))do { if (!show_option.parseable) printf(" Body metadata hash: %s "
, vb2_get_hash_algorithm_name(body_hash->algo)); } while (
0)
;
218 FT_PARSEABLE_PRINT("body::metadata_hash::algorithm::%d::%s\n",do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::metadata_hash::algorithm::%d::%s\n"
, body_hash->algo, vb2_get_hash_algorithm_name(body_hash->
algo)); } while (0)
219 body_hash->algo,do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::metadata_hash::algorithm::%d::%s\n"
, body_hash->algo, vb2_get_hash_algorithm_name(body_hash->
algo)); } while (0)
220 vb2_get_hash_algorithm_name(body_hash->algo))do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::metadata_hash::algorithm::%d::%s\n"
, body_hash->algo, vb2_get_hash_algorithm_name(body_hash->
algo)); } while (0)
;
221 if (vb2_digest_size(body_hash->algo)) {
222 FT_PARSEABLE_PRINT("body::metadata_hash::hex::")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::metadata_hash::hex::"
); } while (0)
;
223 print_bytes((uint8_t *)body_hash->raw,
224 vb2_digest_size(body_hash->algo));
225 putchar('\n');
226 }
227
228 if (cbfstool_get_metadata_hash(fname, fmap_name[body_c], &real_hash) !=
229 VB2_SUCCESS ||
230 real_hash.algo == VB2_HASH_INVALID) {
231 ERROR("Failed to get metadata hash. Firmware body is"fprintf(stderr, "ERROR: %s: " "Failed to get metadata hash. Firmware body is"
" corrupted or is not a valid CBFS.\n", __func__ )
232 " corrupted or is not a valid CBFS.\n")fprintf(stderr, "ERROR: %s: " "Failed to get metadata hash. Firmware body is"
" corrupted or is not a valid CBFS.\n", __func__ )
;
233 FT_PARSEABLE_PRINT("body::metadata_hash::invalid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::metadata_hash::invalid\n"
); } while (0)
;
234 FT_PARSEABLE_PRINT("body::signature::invalid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::signature::invalid\n"
); } while (0)
;
235 return 1;
236 }
237
238 if (body_hash->algo != real_hash.algo ||
239 !vb2_digest_size(body_hash->algo) ||
240 memcmp(body_hash->raw, real_hash.raw,
241 vb2_digest_size(body_hash->algo))) {
242 FT_READABLE_PRINT(" MISMATCH! Real hash: %s:",do { if (!show_option.parseable) printf(" MISMATCH! Real hash: %s:"
, vb2_get_hash_algorithm_name(real_hash.algo)); } while (0)
243 vb2_get_hash_algorithm_name(real_hash.algo))do { if (!show_option.parseable) printf(" MISMATCH! Real hash: %s:"
, vb2_get_hash_algorithm_name(real_hash.algo)); } while (0)
;
244 FT_PARSEABLE_PRINT("body::metadata_hash::invalid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::metadata_hash::invalid\n"
); } while (0)
;
245 FT_PARSEABLE_PRINT(do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::metadata_hash::expected::algorithm::%d::%s\n"
, real_hash.algo, vb2_get_hash_algorithm_name(real_hash.algo)
); } while (0)
246 "body::metadata_hash::expected::algorithm::%d::%s\n",do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::metadata_hash::expected::algorithm::%d::%s\n"
, real_hash.algo, vb2_get_hash_algorithm_name(real_hash.algo)
); } while (0)
247 real_hash.algo,do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::metadata_hash::expected::algorithm::%d::%s\n"
, real_hash.algo, vb2_get_hash_algorithm_name(real_hash.algo)
); } while (0)
248 vb2_get_hash_algorithm_name(real_hash.algo))do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::metadata_hash::expected::algorithm::%d::%s\n"
, real_hash.algo, vb2_get_hash_algorithm_name(real_hash.algo)
); } while (0)
;
249
250 FT_PARSEABLE_PRINT("body::metadata_hash::expected::hex::")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::metadata_hash::expected::hex::"
); } while (0)
;
251
252 print_bytes(&real_hash.raw, vb2_digest_size(real_hash.algo));
253 putchar('\n');
254 ERROR("Signature hash does not match with"fprintf(stderr, "ERROR: %s: " "Signature hash does not match with"
" real metadata hash.\n", __func__ )
255 " real metadata hash.\n")fprintf(stderr, "ERROR: %s: " "Signature hash does not match with"
" real metadata hash.\n", __func__ )
;
256
257 /* To balance out signature::valid otherwise printed by caller. */
258 FT_PARSEABLE_PRINT("body::signature::invalid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::signature::invalid\n"
); } while (0)
;
259 return 1;
260 } else {
261 FT_PRINT(" Body metadata hash valid!\n",do { do { if (!show_option.parseable) printf(" Body metadata hash valid!\n"
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::metadata_hash::valid\n"
); } while (0); } while (0)
262 "body::metadata_hash::valid\n")do { do { if (!show_option.parseable) printf(" Body metadata hash valid!\n"
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::metadata_hash::valid\n"
); } while (0); } while (0)
;
263 }
264 return 0;
265}
266
267int show_fw_preamble_buf(const char *fname, uint8_t *buf, uint32_t len,
268 struct bios_state_s *state)
269{
270 const char *print_name = state ? fmap_name[state->c] : fname;
271 struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf;
272 struct vb2_public_key *sign_key = show_option.k;
273 uint8_t *fv_data = show_option.fv;
274 uint64_t fv_size = show_option.fv_size;
275 struct bios_area_s *fw_body_area = 0;
276 enum bios_component body_c = BIOS_FMAP_FW_MAIN_A;
277 int good_sig = 0;
278 int retval = 0;
279
280 ft_print_header2 = "keyblock";
281 /* Check the hash... */
282 if (VB2_SUCCESS != vb2_verify_keyblock_hash(keyblock, len, &wb)) {
283 ERROR("%s keyblock component is invalid\n", print_name)fprintf(stderr, "ERROR: %s: " "%s keyblock component is invalid\n"
, __func__, print_name )
;
284 FT_PARSEABLE_PRINT("invalid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("invalid\n"
); } while (0)
;
285 return 1;
286 } else {
287 FT_PARSEABLE_PRINT("valid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("valid\n"
); } while (0)
;
288 }
289
290 /*
291 * If we're being invoked while poking through a BIOS, we should
292 * be given the keys and data to verify as part of the state. If we
293 * have no state, then we're just looking at a standalone fw_preamble,
294 * so we'll have to get any keys or data from options.
295 */
296 struct vb2_public_key root_key;
297 if (state) {
298 if (!sign_key &&
299 state->rootkey.is_valid &&
300 VB2_SUCCESS == vb2_unpack_key_buffer(&root_key,
301 state->rootkey.buf,
302 state->rootkey.len)) {
303 /* BIOS should have a rootkey in the GBB */
304 sign_key = &root_key;
305 }
306
307 /* Identify the firmware body for this VBLOCK */
308 body_c = state->c == BIOS_FMAP_VBLOCK_A ? BIOS_FMAP_FW_MAIN_A
309 : BIOS_FMAP_FW_MAIN_B;
310 fw_body_area = &state->area[body_c];
311 }
312
313 /* If we have a key, check the signature too */
314 if (sign_key && VB2_SUCCESS ==
315 vb2_verify_keyblock(keyblock, len, sign_key, &wb))
316 good_sig = 1;
317 else if (show_option.strict)
318 retval = 1;
319
320 show_keyblock(keyblock, print_name, !!sign_key, good_sig);
321
322 struct vb2_public_key data_key;
323 if (VB2_SUCCESS != vb2_unpack_key(&data_key, &keyblock->data_key)) {
324 ERROR("Parsing data key in %s\n", print_name)fprintf(stderr, "ERROR: %s: " "Parsing data key in %s\n", __func__
, print_name )
;
325 FT_PARSEABLE_PRINT("data_key::invalid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("data_key::invalid\n"
); } while (0)
;
326 return 1;
327 }
328
329 ft_print_header2 = "preamble";
330 uint32_t more = keyblock->keyblock_size;
331 struct vb2_fw_preamble *pre2 = (struct vb2_fw_preamble *)(buf + more);
332 if (VB2_SUCCESS != vb2_verify_fw_preamble(pre2, len - more,
333 &data_key, &wb)) {
334 ERROR("%s is invalid\n", print_name)fprintf(stderr, "ERROR: %s: " "%s is invalid\n", __func__, print_name
)
;
335 FT_PARSEABLE_PRINT("invalid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("invalid\n"
); } while (0)
;
336 FT_PARSEABLE_PRINT("signature::invalid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("signature::invalid\n"
); } while (0)
;
337 return 1;
338 } else {
339 FT_PARSEABLE_PRINT("valid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("valid\n"
); } while (0)
;
340 FT_PARSEABLE_PRINT("signature::valid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("signature::valid\n"
); } while (0)
;
341 }
342
343 uint32_t flags = pre2->flags;
344 if (pre2->header_version_minor < 1)
345 flags = 0; /* Old 2.0 structure didn't have flags */
346
347 FT_READABLE_PRINT("Firmware Preamble:\n")do { if (!show_option.parseable) printf("Firmware Preamble:\n"
); } while (0)
;
348 FT_PRINT(" Size: %d\n", "size::%d\n",do { do { if (!show_option.parseable) printf(" Size: %d\n"
, pre2->preamble_size); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("size::%d\n", pre2->
preamble_size); } while (0); } while (0)
349 pre2->preamble_size)do { do { if (!show_option.parseable) printf(" Size: %d\n"
, pre2->preamble_size); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("size::%d\n", pre2->
preamble_size); } while (0); } while (0)
;
350 FT_PRINT(" Header version: %d.%d\n",do { do { if (!show_option.parseable) printf(" Header version: %d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("header_version::%d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); } while (0)
351 "header_version::%d.%d\n",do { do { if (!show_option.parseable) printf(" Header version: %d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("header_version::%d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); } while (0)
352 pre2->header_version_major,do { do { if (!show_option.parseable) printf(" Header version: %d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("header_version::%d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); } while (0)
353 pre2->header_version_minor)do { do { if (!show_option.parseable) printf(" Header version: %d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("header_version::%d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); } while (0)
;
354 FT_PRINT(" Firmware version: %d\n", "firmware_version::%d\n",do { do { if (!show_option.parseable) printf(" Firmware version: %d\n"
, pre2->firmware_version); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("firmware_version::%d\n"
, pre2->firmware_version); } while (0); } while (0)
355 pre2->firmware_version)do { do { if (!show_option.parseable) printf(" Firmware version: %d\n"
, pre2->firmware_version); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("firmware_version::%d\n"
, pre2->firmware_version); } while (0); } while (0)
;
356
357 struct vb2_packed_key *kernel_subkey = &pre2->kernel_subkey;
358 FT_PRINT(" Kernel key algorithm: %d %s\n",do { do { if (!show_option.parseable) printf(" Kernel key algorithm: %d %s\n"
, kernel_subkey->algorithm, vb2_get_crypto_algorithm_name(
kernel_subkey->algorithm)); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("kernel_subkey::algorithm::%d::%s\n"
, kernel_subkey->algorithm, vb2_get_crypto_algorithm_name(
kernel_subkey->algorithm)); } while (0); } while (0)
359 "kernel_subkey::algorithm::%d::%s\n",do { do { if (!show_option.parseable) printf(" Kernel key algorithm: %d %s\n"
, kernel_subkey->algorithm, vb2_get_crypto_algorithm_name(
kernel_subkey->algorithm)); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("kernel_subkey::algorithm::%d::%s\n"
, kernel_subkey->algorithm, vb2_get_crypto_algorithm_name(
kernel_subkey->algorithm)); } while (0); } while (0)
360 kernel_subkey->algorithm,do { do { if (!show_option.parseable) printf(" Kernel key algorithm: %d %s\n"
, kernel_subkey->algorithm, vb2_get_crypto_algorithm_name(
kernel_subkey->algorithm)); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("kernel_subkey::algorithm::%d::%s\n"
, kernel_subkey->algorithm, vb2_get_crypto_algorithm_name(
kernel_subkey->algorithm)); } while (0); } while (0)
361 vb2_get_crypto_algorithm_name(kernel_subkey->algorithm))do { do { if (!show_option.parseable) printf(" Kernel key algorithm: %d %s\n"
, kernel_subkey->algorithm, vb2_get_crypto_algorithm_name(
kernel_subkey->algorithm)); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("kernel_subkey::algorithm::%d::%s\n"
, kernel_subkey->algorithm, vb2_get_crypto_algorithm_name(
kernel_subkey->algorithm)); } while (0); } while (0)
;
362 if (kernel_subkey->algorithm >= VB2_ALG_COUNT)
363 retval = 1;
364 FT_PRINT(" Kernel key version: %d\n",do { do { if (!show_option.parseable) printf(" Kernel key version: %d\n"
, kernel_subkey->key_version); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("kernel_subkey::version::%d\n"
, kernel_subkey->key_version); } while (0); } while (0)
365 "kernel_subkey::version::%d\n",do { do { if (!show_option.parseable) printf(" Kernel key version: %d\n"
, kernel_subkey->key_version); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("kernel_subkey::version::%d\n"
, kernel_subkey->key_version); } while (0); } while (0)
366 kernel_subkey->key_version)do { do { if (!show_option.parseable) printf(" Kernel key version: %d\n"
, kernel_subkey->key_version); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("kernel_subkey::version::%d\n"
, kernel_subkey->key_version); } while (0); } while (0)
;
367 FT_PRINT(" Kernel key sha1sum: %s\n",do { do { if (!show_option.parseable) printf(" Kernel key sha1sum: %s\n"
, packed_key_sha1_string(kernel_subkey)); } while (0); do { if
(!show_option.parseable) break; if (ft_print_header != ((void
*)0)) printf("%s::", ft_print_header); if (ft_print_header2 !=
((void*)0)) printf("%s::", ft_print_header2); printf("kernel_subkey::sha1_sum::%s\n"
, packed_key_sha1_string(kernel_subkey)); } while (0); } while
(0)
368 "kernel_subkey::sha1_sum::%s\n",do { do { if (!show_option.parseable) printf(" Kernel key sha1sum: %s\n"
, packed_key_sha1_string(kernel_subkey)); } while (0); do { if
(!show_option.parseable) break; if (ft_print_header != ((void
*)0)) printf("%s::", ft_print_header); if (ft_print_header2 !=
((void*)0)) printf("%s::", ft_print_header2); printf("kernel_subkey::sha1_sum::%s\n"
, packed_key_sha1_string(kernel_subkey)); } while (0); } while
(0)
369 packed_key_sha1_string(kernel_subkey))do { do { if (!show_option.parseable) printf(" Kernel key sha1sum: %s\n"
, packed_key_sha1_string(kernel_subkey)); } while (0); do { if
(!show_option.parseable) break; if (ft_print_header != ((void
*)0)) printf("%s::", ft_print_header); if (ft_print_header2 !=
((void*)0)) printf("%s::", ft_print_header2); printf("kernel_subkey::sha1_sum::%s\n"
, packed_key_sha1_string(kernel_subkey)); } while (0); } while
(0)
;
370 FT_READABLE_PRINT(" Firmware body size: %d\n",do { if (!show_option.parseable) printf(" Firmware body size: %d\n"
, pre2->body_signature.data_size); } while (0)
371 pre2->body_signature.data_size)do { if (!show_option.parseable) printf(" Firmware body size: %d\n"
, pre2->body_signature.data_size); } while (0)
;
372 FT_PRINT(" Preamble flags: %d\n",do { do { if (!show_option.parseable) printf(" Preamble flags: %d\n"
, flags); } while (0); do { if (!show_option.parseable) break
; if (ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("flags::%d\n", flags); } while (0); } while (0)
373 "flags::%d\n", flags)do { do { if (!show_option.parseable) printf(" Preamble flags: %d\n"
, flags); } while (0); do { if (!show_option.parseable) break
; if (ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("flags::%d\n", flags); } while (0); } while (0)
;
374 ft_print_header2 = NULL((void*)0);
375
376 FT_PARSEABLE_PRINT("body::size::%d\n", pre2->body_signature.data_size)do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::size::%d\n"
, pre2->body_signature.data_size); } while (0)
;
377
378
379 if (flags & VB2_FIRMWARE_PREAMBLE_USE_RO_NORMAL0x00000001) {
380 FT_PRINT("Preamble requests USE_RO_NORMAL;"do { do { if (!show_option.parseable) printf("Preamble requests USE_RO_NORMAL;"
" skipping body verification.\n"); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("body::signature::ignored\n"
); } while (0); } while (0)
381 " skipping body verification.\n",do { do { if (!show_option.parseable) printf("Preamble requests USE_RO_NORMAL;"
" skipping body verification.\n"); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("body::signature::ignored\n"
); } while (0); } while (0)
382 "body::signature::ignored\n")do { do { if (!show_option.parseable) printf("Preamble requests USE_RO_NORMAL;"
" skipping body verification.\n"); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("body::signature::ignored\n"
); } while (0); } while (0)
;
383 goto done;
384 }
385
386 /* We'll need to get the firmware body from somewhere... */
387 if (fw_body_area && fw_body_area->is_valid) {
388 fv_data = fw_body_area->buf;
389 fv_size = fw_body_area->len;
390 }
391
392 if (!fv_data) {
393 FT_PRINT("No firmware body available to verify.\n",do { do { if (!show_option.parseable) printf("No firmware body available to verify.\n"
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::signature::ignored\n"
); } while (0); } while (0)
394 "body::signature::ignored\n")do { do { if (!show_option.parseable) printf("No firmware body available to verify.\n"
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::signature::ignored\n"
); } while (0); } while (0)
;
395 if (show_option.strict)
396 return 1;
397 return 0;
398 }
399
400 if (pre2->body_signature.data_size) {
401 if (vb2_verify_data(fv_data, fv_size, &pre2->body_signature,
402 &data_key, &wb) != VB2_SUCCESS) {
403 ERROR("Verifying firmware body.\n")fprintf(stderr, "ERROR: %s: " "Verifying firmware body.\n", __func__
)
;
404 FT_PARSEABLE_PRINT("body::signature::invalid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::signature::invalid\n"
); } while (0)
;
405 return show_option.strict ? 1 : 0;
406 }
407 } else if (state) { /* Only works if `fname` is a BIOS image */
408 if (fw_show_metadata_hash(fname, body_c, pre2))
409 return show_option.strict ? 1 : 0;
410 } else {
411 WARN("Metadata hash verification not supported.\n")fprintf(stderr, "WARNING: %s: " "Metadata hash verification not supported.\n"
, __func__ )
;
412 FT_PARSEABLE_PRINT("body::metadata_hash::ignored\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::metadata_hash::ignored\n"
); } while (0)
;
413 FT_PARSEABLE_PRINT("body::signature::ignored\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::signature::ignored\n"
); } while (0)
;
414 return show_option.strict ? 1 : 0;
415 }
416
417 FT_PRINT("Body verification succeeded.\n",do { do { if (!show_option.parseable) printf("Body verification succeeded.\n"
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::signature::valid\n"
); } while (0); } while (0)
418 "body::signature::valid\n")do { do { if (!show_option.parseable) printf("Body verification succeeded.\n"
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::signature::valid\n"
); } while (0); } while (0)
;
419
420done:
421 /* Can't trust the BIOS unless everything is signed. */
422 if (good_sig) {
423 if (state)
424 state->area[state->c].is_valid = 1;
425 FT_PARSEABLE_PRINT("verified\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("verified\n"
); } while (0)
;
426 }
427
428 return retval;
429}
430
431int ft_show_fw_preamble(const char *fname)
432{
433 int rv = 0;
434 int fd = -1;
435 uint8_t *buf;
436 uint32_t len;
437
438 if (futil_open_and_map_file(fname, &fd, FILE_RO, &buf, &len))
439 return 1;
440 ft_print_header = "fw_pre";
441 rv = show_fw_preamble_buf(fname, buf, len, NULL((void*)0));
442
443 futil_unmap_and_close_file(fd, FILE_RO, buf, len);
444 return rv;
445}
446
447int ft_show_kernel_preamble(const char *fname)
448{
449 struct vb2_keyblock *keyblock;
450 struct vb2_public_key *sign_key = show_option.k;
451 int retval = 0;
452 int fd = -1;
453 uint8_t *buf;
454 uint32_t len;
455
456 if (futil_open_and_map_file(fname, &fd, FILE_RO, &buf, &len))
457 return 1;
458
459 keyblock = (struct vb2_keyblock *)buf;
460 ft_print_header = "kernel";
461 ft_print_header2 = "keyblock";
462 /* Check the hash... */
463 if (VB2_SUCCESS != vb2_verify_keyblock_hash(keyblock, len, &wb)) {
464 ERROR("%s keyblock component is invalid\n", fname)fprintf(stderr, "ERROR: %s: " "%s keyblock component is invalid\n"
, __func__, fname )
;
465 FT_PARSEABLE_PRINT("invalid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("invalid\n"
); } while (0)
;
466 retval = 1;
467 goto done;
468 } else {
469 FT_PARSEABLE_PRINT("valid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("valid\n"
); } while (0)
;
470 }
471
472 /* If we have a key, check the signature too */
473 int good_sig = 0;
474 if (sign_key && VB2_SUCCESS ==
475 vb2_verify_keyblock(keyblock, len, sign_key, &wb))
476 good_sig = 1;
477 else if (show_option.strict)
478 retval = 1;
479
480 FT_READABLE_PRINT("Kernel partition: %s\n", fname)do { if (!show_option.parseable) printf("Kernel partition: %s\n"
, fname); } while (0)
;
481 show_keyblock(keyblock, NULL((void*)0), !!sign_key, good_sig);
482
483 struct vb2_public_key data_key;
484 if (VB2_SUCCESS != vb2_unpack_key(&data_key, &keyblock->data_key)) {
485 ERROR("Parsing data key in %s\n", fname)fprintf(stderr, "ERROR: %s: " "Parsing data key in %s\n", __func__
, fname )
;
486 retval = 1;
487 goto done;
488 }
489
490 ft_print_header2 = NULL((void*)0);
491 uint32_t more = keyblock->keyblock_size;
492 struct vb2_kernel_preamble *pre2 =
493 (struct vb2_kernel_preamble *)(buf + more);
494
495 if (VB2_SUCCESS != vb2_verify_kernel_preamble(pre2, len - more,
496 &data_key, &wb)) {
497 ERROR("%s is invalid\n", fname)fprintf(stderr, "ERROR: %s: " "%s is invalid\n", __func__, fname
)
;
498 FT_PARSEABLE_PRINT("preamble::invalid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("preamble::invalid\n"
); } while (0)
;
499 FT_PARSEABLE_PRINT("preamble::signature::invalid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("preamble::signature::invalid\n"
); } while (0)
;
500 retval = 1;
501 goto done;
502 }
503
504 more += pre2->preamble_size;
505 FT_PARSEABLE_PRINT("preamble::valid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("preamble::valid\n"
); } while (0)
;
506 FT_PARSEABLE_PRINT("preamble::signature::valid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("preamble::signature::valid\n"
); } while (0)
;
507 FT_READABLE_PRINT("Kernel Preamble:\n")do { if (!show_option.parseable) printf("Kernel Preamble:\n")
; } while (0)
;
508 FT_PRINT(" Size: %#x\n",do { do { if (!show_option.parseable) printf(" Size: %#x\n"
, pre2->preamble_size); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("preamble::size::%d\n"
, pre2->preamble_size); } while (0); } while (0)
509 "preamble::size::%d\n", pre2->preamble_size)do { do { if (!show_option.parseable) printf(" Size: %#x\n"
, pre2->preamble_size); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("preamble::size::%d\n"
, pre2->preamble_size); } while (0); } while (0)
;
510 FT_PRINT(" Header version: %d.%d\n",do { do { if (!show_option.parseable) printf(" Header version: %d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("preamble::header_version::%d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); } while (0)
511 "preamble::header_version::%d.%d\n",do { do { if (!show_option.parseable) printf(" Header version: %d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("preamble::header_version::%d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); } while (0)
512 pre2->header_version_major,do { do { if (!show_option.parseable) printf(" Header version: %d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("preamble::header_version::%d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); } while (0)
513 pre2->header_version_minor)do { do { if (!show_option.parseable) printf(" Header version: %d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("preamble::header_version::%d.%d\n"
, pre2->header_version_major, pre2->header_version_minor
); } while (0); } while (0)
;
514 FT_PRINT(" Kernel version: %u\n",do { do { if (!show_option.parseable) printf(" Kernel version: %u\n"
, pre2->kernel_version); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("preamble::kernel_version::%u\n"
, pre2->kernel_version); } while (0); } while (0)
515 "preamble::kernel_version::%u\n",do { do { if (!show_option.parseable) printf(" Kernel version: %u\n"
, pre2->kernel_version); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("preamble::kernel_version::%u\n"
, pre2->kernel_version); } while (0); } while (0)
516 pre2->kernel_version)do { do { if (!show_option.parseable) printf(" Kernel version: %u\n"
, pre2->kernel_version); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("preamble::kernel_version::%u\n"
, pre2->kernel_version); } while (0); } while (0)
;
517 FT_PRINT(" Flags: %#x\n",do { do { if (!show_option.parseable) printf(" Flags: %#x\n"
, vb2_kernel_get_flags(pre2)); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("preamble::flags::%d\n"
, vb2_kernel_get_flags(pre2)); } while (0); } while (0)
518 "preamble::flags::%d\n", vb2_kernel_get_flags(pre2))do { do { if (!show_option.parseable) printf(" Flags: %#x\n"
, vb2_kernel_get_flags(pre2)); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("preamble::flags::%d\n"
, vb2_kernel_get_flags(pre2)); } while (0); } while (0)
;
519
520 FT_PRINT(" Body load address: 0x%" PRIx64 "\n",do { do { if (!show_option.parseable) printf(" Body load address: 0x%"
"l" "x" "\n", pre2->body_load_address); } while (0); do {
if (!show_option.parseable) break; if (ft_print_header != ((
void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::address::%"
"l" "u" "\n", pre2->body_load_address); } while (0); } while
(0)
521 "body::address::%" PRIu64 "\n",do { do { if (!show_option.parseable) printf(" Body load address: 0x%"
"l" "x" "\n", pre2->body_load_address); } while (0); do {
if (!show_option.parseable) break; if (ft_print_header != ((
void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::address::%"
"l" "u" "\n", pre2->body_load_address); } while (0); } while
(0)
522 pre2->body_load_address)do { do { if (!show_option.parseable) printf(" Body load address: 0x%"
"l" "x" "\n", pre2->body_load_address); } while (0); do {
if (!show_option.parseable) break; if (ft_print_header != ((
void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::address::%"
"l" "u" "\n", pre2->body_load_address); } while (0); } while
(0)
;
523 FT_PRINT(" Body size: %#x\n",do { do { if (!show_option.parseable) printf(" Body size: %#x\n"
, pre2->body_signature.data_size); } while (0); do { if (!
show_option.parseable) break; if (ft_print_header != ((void*)
0)) printf("%s::", ft_print_header); if (ft_print_header2 != (
(void*)0)) printf("%s::", ft_print_header2); printf("body::size::%d\n"
, pre2->body_signature.data_size); } while (0); } while (0
)
524 "body::size::%d\n",do { do { if (!show_option.parseable) printf(" Body size: %#x\n"
, pre2->body_signature.data_size); } while (0); do { if (!
show_option.parseable) break; if (ft_print_header != ((void*)
0)) printf("%s::", ft_print_header); if (ft_print_header2 != (
(void*)0)) printf("%s::", ft_print_header2); printf("body::size::%d\n"
, pre2->body_signature.data_size); } while (0); } while (0
)
525 pre2->body_signature.data_size)do { do { if (!show_option.parseable) printf(" Body size: %#x\n"
, pre2->body_signature.data_size); } while (0); do { if (!
show_option.parseable) break; if (ft_print_header != ((void*)
0)) printf("%s::", ft_print_header); if (ft_print_header2 != (
(void*)0)) printf("%s::", ft_print_header2); printf("body::size::%d\n"
, pre2->body_signature.data_size); } while (0); } while (0
)
;
526 FT_PRINT(" Bootloader address: 0x%" PRIx64 "\n",do { do { if (!show_option.parseable) printf(" Bootloader address: 0x%"
"l" "x" "\n", pre2->bootloader_address); } while (0); do {
if (!show_option.parseable) break; if (ft_print_header != ((
void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("bootloader::address::%"
"l" "u" "\n", pre2->bootloader_address); } while (0); } while
(0)
527 "bootloader::address::%" PRIu64 "\n",do { do { if (!show_option.parseable) printf(" Bootloader address: 0x%"
"l" "x" "\n", pre2->bootloader_address); } while (0); do {
if (!show_option.parseable) break; if (ft_print_header != ((
void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("bootloader::address::%"
"l" "u" "\n", pre2->bootloader_address); } while (0); } while
(0)
528 pre2->bootloader_address)do { do { if (!show_option.parseable) printf(" Bootloader address: 0x%"
"l" "x" "\n", pre2->bootloader_address); } while (0); do {
if (!show_option.parseable) break; if (ft_print_header != ((
void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("bootloader::address::%"
"l" "u" "\n", pre2->bootloader_address); } while (0); } while
(0)
;
529 FT_PRINT(" Bootloader size: %#x\n",do { do { if (!show_option.parseable) printf(" Bootloader size: %#x\n"
, pre2->bootloader_size); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("bootloader::size::%d\n"
, pre2->bootloader_size); } while (0); } while (0)
530 "bootloader::size::%d\n",do { do { if (!show_option.parseable) printf(" Bootloader size: %#x\n"
, pre2->bootloader_size); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("bootloader::size::%d\n"
, pre2->bootloader_size); } while (0); } while (0)
531 pre2->bootloader_size)do { do { if (!show_option.parseable) printf(" Bootloader size: %#x\n"
, pre2->bootloader_size); } while (0); do { if (!show_option
.parseable) break; if (ft_print_header != ((void*)0)) printf(
"%s::", ft_print_header); if (ft_print_header2 != ((void*)0))
printf("%s::", ft_print_header2); printf("bootloader::size::%d\n"
, pre2->bootloader_size); } while (0); } while (0)
;
532
533 uint64_t vmlinuz_header_address = 0;
534 uint32_t vmlinuz_header_size = 0;
535 vb2_kernel_get_vmlinuz_header(pre2,
536 &vmlinuz_header_address,
537 &vmlinuz_header_size);
538 if (vmlinuz_header_size) {
539 FT_PRINT(" Vmlinuz_header address: 0x%" PRIx64 "\n",do { do { if (!show_option.parseable) printf(" Vmlinuz_header address: 0x%"
"l" "x" "\n", vmlinuz_header_address); } while (0); do { if (
!show_option.parseable) break; if (ft_print_header != ((void*
)0)) printf("%s::", ft_print_header); if (ft_print_header2 !=
((void*)0)) printf("%s::", ft_print_header2); printf("vmlinuz_header::address::%"
"l" "u" "\n", vmlinuz_header_address); } while (0); } while (
0)
540 "vmlinuz_header::address::%" PRIu64 "\n",do { do { if (!show_option.parseable) printf(" Vmlinuz_header address: 0x%"
"l" "x" "\n", vmlinuz_header_address); } while (0); do { if (
!show_option.parseable) break; if (ft_print_header != ((void*
)0)) printf("%s::", ft_print_header); if (ft_print_header2 !=
((void*)0)) printf("%s::", ft_print_header2); printf("vmlinuz_header::address::%"
"l" "u" "\n", vmlinuz_header_address); } while (0); } while (
0)
541 vmlinuz_header_address)do { do { if (!show_option.parseable) printf(" Vmlinuz_header address: 0x%"
"l" "x" "\n", vmlinuz_header_address); } while (0); do { if (
!show_option.parseable) break; if (ft_print_header != ((void*
)0)) printf("%s::", ft_print_header); if (ft_print_header2 !=
((void*)0)) printf("%s::", ft_print_header2); printf("vmlinuz_header::address::%"
"l" "u" "\n", vmlinuz_header_address); } while (0); } while (
0)
;
542 FT_PRINT(" Vmlinuz header size: %#x\n",do { do { if (!show_option.parseable) printf(" Vmlinuz header size: %#x\n"
, vmlinuz_header_size); } while (0); do { if (!show_option.parseable
) break; if (ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("vmlinuz_header::size::%d\n", vmlinuz_header_size);
} while (0); } while (0)
543 "vmlinuz_header::size::%d\n",do { do { if (!show_option.parseable) printf(" Vmlinuz header size: %#x\n"
, vmlinuz_header_size); } while (0); do { if (!show_option.parseable
) break; if (ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("vmlinuz_header::size::%d\n", vmlinuz_header_size);
} while (0); } while (0)
544 vmlinuz_header_size)do { do { if (!show_option.parseable) printf(" Vmlinuz header size: %#x\n"
, vmlinuz_header_size); } while (0); do { if (!show_option.parseable
) break; if (ft_print_header != ((void*)0)) printf("%s::", ft_print_header
); if (ft_print_header2 != ((void*)0)) printf("%s::", ft_print_header2
); printf("vmlinuz_header::size::%d\n", vmlinuz_header_size);
} while (0); } while (0)
;
545 }
546
547 /* Verify kernel body */
548 uint8_t *kernel_blob;
549 uint64_t kernel_size;
550 if (show_option.fv) {
551 /* It's in a separate file, which we've already read in */
552 kernel_blob = show_option.fv;
553 kernel_size = show_option.fv_size;
554 } else {
555 /* It should be at an offset within the input file. */
556 kernel_blob = buf + more;
557 kernel_size = len - more;
558 }
559
560 if (!kernel_size) {
561 FT_PRINT("No kernel blob available to verify.\n",do { do { if (!show_option.parseable) printf("No kernel blob available to verify.\n"
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::signature::ignored\n"
); } while (0); } while (0)
562 "body::signature::ignored\n")do { do { if (!show_option.parseable) printf("No kernel blob available to verify.\n"
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::signature::ignored\n"
); } while (0); } while (0)
;
563 if (show_option.strict)
564 retval = 1;
565 goto done;
566 }
567
568 if (VB2_SUCCESS !=
569 vb2_verify_data(kernel_blob, kernel_size, &pre2->body_signature,
570 &data_key, &wb)) {
571 ERROR("Verifying kernel body.\n")fprintf(stderr, "ERROR: %s: " "Verifying kernel body.\n", __func__
)
;
572 FT_PARSEABLE_PRINT("body::signature::invalid\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::signature::invalid\n"
); } while (0)
;
573 if (show_option.strict)
574 retval = 1;
575 goto done;
576 }
577
578 FT_PRINT("Body verification succeeded.\n",do { do { if (!show_option.parseable) printf("Body verification succeeded.\n"
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::signature::valid\n"
); } while (0); } while (0)
579 "body::signature::valid\n")do { do { if (!show_option.parseable) printf("Body verification succeeded.\n"
); } while (0); do { if (!show_option.parseable) break; if (ft_print_header
!= ((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("body::signature::valid\n"
); } while (0); } while (0)
;
580 if (good_sig)
581 FT_PARSEABLE_PRINT("verified\n")do { if (!show_option.parseable) break; if (ft_print_header !=
((void*)0)) printf("%s::", ft_print_header); if (ft_print_header2
!= ((void*)0)) printf("%s::", ft_print_header2); printf("verified\n"
); } while (0)
;
582
583 FT_READABLE_PRINT("Config:\n%s\n",do { if (!show_option.parseable) printf("Config:\n%s\n", kernel_blob
+ kernel_cmd_line_offset(pre2)); } while (0)
584 kernel_blob + kernel_cmd_line_offset(pre2))do { if (!show_option.parseable) printf("Config:\n%s\n", kernel_blob
+ kernel_cmd_line_offset(pre2)); } while (0)
;
585
586done:
587 futil_unmap_and_close_file(fd, FILE_RO, buf, len);
588 return retval;
589}
590
591enum no_short_opts {
592 OPT_TYPE = 1000,
593 OPT_PUBKEY,
594 OPT_HELP,
595};
596
597static const char usage[] = "\n"
598 "Usage: " MYNAME"futility" " %s [OPTIONS] FILE [...]\n"
599 "\n"
600 "Where FILE could be\n"
601 "\n"
602 " a boot descriptor block (BDB)\n"
603 " a keyblock (.keyblock)\n"
604 " a firmware preamble signature (VBLOCK_A/B)\n"
605 " a firmware image (image.bin)\n"
606 " a kernel partition (/dev/sda2, /dev/mmcblk0p2)\n"
607 " keys in various formats (.vbpubk, .vbprivk, .pem)\n"
608 " several other file types related to verified boot\n"
609 "\n"
610 "Options:\n"
611 " -t Just show the type of each file\n"
612 " --type TYPE Override the detected file type\n"
613 " Use \"--type help\" for a list\n"
614 " -P|--parseable Machine friendly output format\n"
615 "Type-specific options:\n"
616 " -k|--publickey FILE.vbpubk Public key in vb1 format\n"
617 " --pubkey FILE.vpubk2 Public key in vb2 format\n"
618 " -f|--fv FILE Verify this payload (FW_MAIN_A/B)\n"
619 " --strict "
620 "Fail unless all signatures are valid\n"
621 "\n";
622
623static void print_help(int argc, char *argv[])
624{
625 if (!strcmp(argv[0], "verify"))
626 printf("\nUsage: " MYNAME"futility" " %s [OPTIONS] FILE [...]\n\n"
627 "This is just an alias for\n\n"
628 " " MYNAME"futility" " show --strict\n\n",
629 argv[0]);
630
631 printf(usage, "show");
632}
633
634static const struct option long_opts[] = {
635 /* name hasarg *flag val */
636 {"publickey", 1, 0, 'k'},
637 {"fv", 1, 0, 'f'},
638 {"type", 1, NULL((void*)0), OPT_TYPE},
639 {"strict", 0, &show_option.strict, 1},
640 {"pubkey", 1, NULL((void*)0), OPT_PUBKEY},
641 {"parseable", 0, NULL((void*)0), 'P'},
642 {"help", 0, NULL((void*)0), OPT_HELP},
643 {NULL((void*)0), 0, NULL((void*)0), 0},
644};
645static const char *short_opts = ":f:k:Pt";
646
647
648static int show_type(char *filename)
649{
650 enum futil_file_err err;
651 enum futil_file_type type;
652 err = futil_file_type(filename, &type);
653 switch (err) {
654 case FILE_ERR_NONE:
655 printf("%s:\t%s\n", filename, futil_file_type_name(type));
656 /* Only our recognized types return success */
657 return 0;
658 case FILE_ERR_DIR:
659 printf("%s:\t%s\n", filename, "directory");
660 break;
661 case FILE_ERR_CHR:
662 printf("%s:\t%s\n", filename, "character special");
663 break;
664 case FILE_ERR_FIFO:
665 printf("%s:\t%s\n", filename, "FIFO");
666 break;
667 case FILE_ERR_SOCK:
668 printf("%s:\t%s\n", filename, "socket");
669 break;
670 default:
671 break;
672 }
673 /* Everything else is an error */
674 return 1;
675}
676
677static int load_publickey(const char *fname, uint8_t **buf_ptr,
678 struct vb2_public_key *pubkey)
679{
680 uint32_t len = 0;
681 if (vb2_read_file(fname, buf_ptr, &len) != VB2_SUCCESS) {
682 ERROR("Reading publickey %s\n", fname)fprintf(stderr, "ERROR: %s: " "Reading publickey %s\n", __func__
, fname )
;
683 return 1;
684 }
685
686 struct vb2_keyblock *keyblock;
687 uint8_t *buf = *buf_ptr;
688 enum futil_file_type type = futil_file_type_buf(buf, len);
689 switch (type) {
690 case FILE_TYPE_FW_PREAMBLE:
691 keyblock = (struct vb2_keyblock *)buf;
692 if (vb2_check_keyblock(keyblock, len, &keyblock->keyblock_hash)
693 != VB2_SUCCESS) {
694 ERROR("Checking publickey keyblock\n")fprintf(stderr, "ERROR: %s: " "Checking publickey keyblock\n"
, __func__ )
;
695 return 1;
696 }
697 struct vb2_fw_preamble *pre =
698 (struct vb2_fw_preamble *)(buf + keyblock->keyblock_size);
699 if (vb2_unpack_key(pubkey, &pre->kernel_subkey) != VB2_SUCCESS) {
700 ERROR("Unpacking publickey from preamble %s\n", fname)fprintf(stderr, "ERROR: %s: " "Unpacking publickey from preamble %s\n"
, __func__, fname )
;
701 return 1;
702 }
703 break;
704 case FILE_TYPE_PUBKEY:
705 if (vb2_unpack_key_buffer(pubkey, buf, len) != VB2_SUCCESS) {
706 ERROR("Unpacking publickey %s\n", fname)fprintf(stderr, "ERROR: %s: " "Unpacking publickey %s\n", __func__
, fname )
;
707 return 1;
708 }
709 break;
710 default:
711 ERROR("Unsupported file type '%s' for publickey %s\n",fprintf(stderr, "ERROR: %s: " "Unsupported file type '%s' for publickey %s\n"
, __func__, futil_file_type_name(type), fname )
712 futil_file_type_name(type), fname)fprintf(stderr, "ERROR: %s: " "Unsupported file type '%s' for publickey %s\n"
, __func__, futil_file_type_name(type), fname )
;
713 return 1;
714 }
715
716 return 0;
717}
718
719static int do_show(int argc, char *argv[])
720{
721 uint8_t *pubkbuf = NULL((void*)0);
722 struct vb2_public_key pubk2;
723 char *infile = 0;
724 int i;
725 int errorcnt = 0;
726 int type_override = 0;
727 enum futil_file_type type;
728
729 vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
730
731 opterr = 0; /* quiet, you */
732 while ((i = getopt_long(argc, argv, short_opts, long_opts, 0)) != -1) {
2
Assuming the condition is true
3
Loop condition is true. Entering loop body
6
Execution continues on line 732
7
Assuming the condition is true
8
Loop condition is true. Entering loop body
12
Execution continues on line 732
13
Assuming the condition is false
14
Loop condition is false. Execution continues on line 796
733 switch (i) {
4
Control jumps to 'case 107:' at line 743
9
Control jumps to 'case 107:' at line 743
734 case 'f':
735 show_option.fv = ReadFile(optarg,
736 &show_option.fv_size);
737 if (!show_option.fv) {
738 ERROR("Reading %s: %s\n",fprintf(stderr, "ERROR: %s: " "Reading %s: %s\n", __func__, optarg
, strerror((*__errno_location ())) )
739 optarg, strerror(errno))fprintf(stderr, "ERROR: %s: " "Reading %s: %s\n", __func__, optarg
, strerror((*__errno_location ())) )
;
740 errorcnt++;
741 }
742 break;
743 case 'k':
744 if (load_publickey(optarg, &pubkbuf, &pubk2)) {
5
Taking true branch
10
Assuming the condition is false
11
Taking false branch
745 ERROR("Loading publickey %s\n", optarg)fprintf(stderr, "ERROR: %s: " "Loading publickey %s\n", __func__
, optarg )
;
746 errorcnt++;
747 break;
748 }
749 show_option.k = &pubk2;
750 break;
751 case 't':
752 show_option.t_flag = 1;
753 break;
754 case 'P':
755 show_option.parseable = true1;
756 break;
757 case OPT_TYPE:
758 if (!futil_str_to_file_type(optarg,
759 &show_option.type)) {
760 if (!strcasecmp("help", optarg))
761 print_file_types_and_exit(errorcnt);
762 ERROR("Invalid --type \"%s\"\n", optarg)fprintf(stderr, "ERROR: %s: " "Invalid --type \"%s\"\n", __func__
, optarg )
;
763 errorcnt++;
764 }
765 type_override = 1;
766 break;
767 case OPT_PUBKEY:
768 if (vb21_packed_key_read(&show_option.pkey, optarg)) {
769 ERROR("Reading %s\n", optarg)fprintf(stderr, "ERROR: %s: " "Reading %s\n", __func__, optarg
)
;
770 errorcnt++;
771 }
772 break;
773 case OPT_HELP:
774 print_help(argc, argv);
775 return !!errorcnt;
776
777 case '?':
778 if (optopt)
779 ERROR("Unrecognized option: -%c\n",fprintf(stderr, "ERROR: %s: " "Unrecognized option: -%c\n", __func__
, optopt )
780 optopt)fprintf(stderr, "ERROR: %s: " "Unrecognized option: -%c\n", __func__
, optopt )
;
781 else
782 ERROR("Unrecognized option\n")fprintf(stderr, "ERROR: %s: " "Unrecognized option\n", __func__
)
;
783 errorcnt++;
784 break;
785 case ':':
786 ERROR("Missing argument to -%c\n", optopt)fprintf(stderr, "ERROR: %s: " "Missing argument to -%c\n", __func__
, optopt )
;
787 errorcnt++;
788 break;
789 case 0: /* handled option */
790 break;
791 default:
792 FATAL("Unrecognized getopt output: %d\n", i)do { fprintf(stderr, "FATAL: %s: " "Unrecognized getopt output: %d\n"
, __func__, i ); exit(1); } while (0)
;
793 }
794 }
795
796 if (errorcnt
14.1
'errorcnt' is 1
) {
15
Taking true branch
797 print_help(argc, argv);
798 return 1;
16
Address of stack memory associated with local variable 'pubk2' is still referred to by the global variable 'show_option' upon returning to the caller. This will be a dangling reference
799 }
800
801 if (argc - optind < 1) {
802 ERROR("Missing input filename\n")fprintf(stderr, "ERROR: %s: " "Missing input filename\n", __func__
)
;
803 print_help(argc, argv);
804 return 1;
805 }
806
807 if (show_option.t_flag) {
808 for (i = optind; i < argc; i++)
809 errorcnt += show_type(argv[i]);
810 goto done;
811 }
812
813 for (i = optind; i < argc; i++) {
814 infile = argv[i];
815
816 /* Allow the user to override the type */
817 if (type_override)
818 type = show_option.type;
819 else
820 futil_file_type(infile, &type);
821
822 errorcnt += futil_file_type_show(type, infile);
823 }
824
825done:
826 if (pubkbuf)
827 free(pubkbuf);
828 if (show_option.fv)
829 free(show_option.fv);
830
831 return !!errorcnt;
832}
833
834DECLARE_FUTIL_COMMAND(show, do_show, VBOOT_VERSION_ALL,const struct futil_cmd_t __cmd_show = { .name = "show", .handler
= do_show, .version = VBOOT_VERSION_ALL, .shorthelp = "Display the content of various binary components"
, }
835 "Display the content of various binary components")const struct futil_cmd_t __cmd_show = { .name = "show", .handler
= do_show, .version = VBOOT_VERSION_ALL, .shorthelp = "Display the content of various binary components"
, }
;
836
837static int do_verify(int argc, char *argv[])
838{
839 show_option.strict = 1;
840 return do_show(argc, argv);
1
Calling 'do_show'
841}
842
843DECLARE_FUTIL_COMMAND(verify, do_verify,const struct futil_cmd_t __cmd_verify = { .name = "verify", .
handler = do_verify, .version = VBOOT_VERSION_ALL, .shorthelp
= "Verify the signatures of various binary components. " "This does not verify GSCVD contents."
, }
844 VBOOT_VERSION_ALL,const struct futil_cmd_t __cmd_verify = { .name = "verify", .
handler = do_verify, .version = VBOOT_VERSION_ALL, .shorthelp
= "Verify the signatures of various binary components. " "This does not verify GSCVD contents."
, }
845 "Verify the signatures of various binary components. "const struct futil_cmd_t __cmd_verify = { .name = "verify", .
handler = do_verify, .version = VBOOT_VERSION_ALL, .shorthelp
= "Verify the signatures of various binary components. " "This does not verify GSCVD contents."
, }
846 "This does not verify GSCVD contents.")const struct futil_cmd_t __cmd_verify = { .name = "verify", .
handler = do_verify, .version = VBOOT_VERSION_ALL, .shorthelp
= "Verify the signatures of various binary components. " "This does not verify GSCVD contents."
, }
;