Bug Summary

File:3rdparty/vboot/futility/cmd_show.c
Warning:line 831, column 2
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 false
8
Loop condition is false. Execution continues on line 796
733 switch (i) {
4
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 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
8.1
'errorcnt' is 0
) {
9
Taking false branch
797 print_help(argc, argv);
798 return 1;
799 }
800
801 if (argc - optind < 1) {
10
Assuming the condition is false
11
Taking false branch
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) {
12
Assuming field 't_flag' is 0
13
Taking false branch
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++) {
14
Assuming 'i' is >= 'argc'
15
Loop condition is false. Execution continues on line 826
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)
16
Assuming 'pubkbuf' is null
17
Taking false branch
827 free(pubkbuf);
828 if (show_option.fv)
18
Assuming field 'fv' is null
19
Taking false branch
829 free(show_option.fv);
830
831 return !!errorcnt;
20
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
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."
, }
;