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 util_misc.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 -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 host/lib/util_misc.c
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | #include <openssl/bn.h> |
9 | #include <openssl/rsa.h> |
10 | |
11 | #include <stdio.h> |
12 | #include <stdlib.h> |
13 | #include <string.h> |
14 | #include <unistd.h> |
15 | |
16 | #include "2common.h" |
17 | #include "2sha.h" |
18 | #include "2sysincludes.h" |
19 | #include "host_common.h" |
20 | #include "host_key21.h" |
21 | #include "host_p11.h" |
22 | #include "openssl_compat.h" |
23 | #include "util_misc.h" |
24 | |
25 | const char *packed_key_sha1_string(const struct vb2_packed_key *key) |
26 | { |
27 | uint8_t *buf = ((uint8_t *)key) + key->key_offset; |
28 | uint32_t buflen = key->key_size; |
29 | struct vb2_hash hash; |
30 | static char dest[VB2_SHA1_DIGEST_SIZE * 2 + 1]; |
31 | |
32 | vb2_hash_calculate(false, buf, buflen, VB2_HASH_SHA1, &hash); |
33 | |
34 | char *dnext = dest; |
35 | int i; |
36 | for (i = 0; i < sizeof(hash.sha1); i++) |
37 | dnext += sprintf(dnext, "%02x", hash.sha1[i]); |
38 | |
39 | return dest; |
40 | } |
41 | |
42 | const char *private_key_sha1_string(const struct vb2_private_key *key) |
43 | { |
44 | uint8_t *buf; |
45 | uint32_t buflen; |
46 | struct vb2_hash hash; |
47 | static char dest[VB2_SHA1_DIGEST_SIZE * 2 + 1]; |
48 | |
49 | if (!key->rsa_private_key || |
50 | vb_keyb_from_rsa(key->rsa_private_key, &buf, &buflen)) { |
51 | return "<error>"; |
52 | } |
53 | |
54 | vb2_hash_calculate(false, buf, buflen, VB2_HASH_SHA1, &hash); |
55 | |
56 | char *dnext = dest; |
57 | int i; |
58 | for (i = 0; i < sizeof(hash.sha1); i++) |
59 | dnext += sprintf(dnext, "%02x", hash.sha1[i]); |
60 | |
61 | free(buf); |
62 | return dest; |
63 | } |
64 | |
65 | static int vb_keyb_from_modulus(const BIGNUM *rsa_private_key_n, uint32_t modulus_size, |
66 | uint8_t **keyb_data, uint32_t *keyb_size) |
67 | { |
68 | uint32_t i; |
69 | uint32_t nwords = modulus_size / 4; |
70 | BIGNUM *N = NULL; |
71 | BIGNUM *Big1 = NULL, *Big2 = NULL, *Big32 = NULL, *BigMinus1 = NULL; |
72 | BIGNUM *B = NULL; |
73 | BIGNUM *N0inv = NULL, *R = NULL, *RR = NULL; |
74 | BIGNUM *RRTemp = NULL, *NnumBits = NULL; |
75 | BIGNUM *n = NULL, *rr = NULL; |
76 | BN_CTX *bn_ctx = BN_CTX_new(); |
77 | uint32_t n0invout; |
78 | uint32_t bufsize; |
79 | uint32_t *outbuf; |
80 | int retval = 1; |
81 | |
82 | bufsize = (2 + nwords + nwords) * sizeof(uint32_t); |
83 | outbuf = malloc(bufsize); |
84 | if (!outbuf) |
| 6 | | Assuming 'outbuf' is non-null | |
|
| |
85 | goto done; |
86 | |
87 | *keyb_data = (uint8_t *)outbuf; |
88 | *keyb_size = bufsize; |
89 | |
90 | *outbuf++ = nwords; |
91 | |
92 | |
93 | #define NEW_BIGNUM(x) do { x = BN_new(); if (!x) goto done; } while (0) |
94 | NEW_BIGNUM(N); |
| |
| |
| 10 | | Control jumps to line 160 | |
|
95 | NEW_BIGNUM(Big1); |
96 | NEW_BIGNUM(Big2); |
97 | NEW_BIGNUM(Big32); |
98 | NEW_BIGNUM(BigMinus1); |
99 | NEW_BIGNUM(N0inv); |
100 | NEW_BIGNUM(R); |
101 | NEW_BIGNUM(RR); |
102 | NEW_BIGNUM(RRTemp); |
103 | NEW_BIGNUM(NnumBits); |
104 | NEW_BIGNUM(n); |
105 | NEW_BIGNUM(rr); |
106 | NEW_BIGNUM(B); |
107 | #undef NEW_BIGNUM |
108 | |
109 | BN_copy(N, rsa_private_key_n); |
110 | BN_set_word(Big1, 1L); |
111 | BN_set_word(Big2, 2L); |
112 | BN_set_word(Big32, 32L); |
113 | BN_sub(BigMinus1, Big1, Big2); |
114 | |
115 | BN_exp(B, Big2, Big32, bn_ctx); |
116 | |
117 | |
118 | BN_mod_inverse(N0inv, N, B, bn_ctx); |
119 | BN_sub(N0inv, B, N0inv); |
120 | n0invout = BN_get_word(N0inv); |
121 | |
122 | *outbuf++ = n0invout; |
123 | |
124 | |
125 | BN_set_word(NnumBits, BN_num_bits(N)); |
126 | BN_exp(R, Big2, NnumBits, bn_ctx); |
127 | |
128 | |
129 | BN_copy(RR, R); |
130 | BN_mul(RRTemp, RR, R, bn_ctx); |
131 | BN_mod(RR, RRTemp, N, bn_ctx); |
132 | |
133 | |
134 | |
135 | for (i = 0; i < nwords; ++i) { |
136 | uint32_t nout; |
137 | |
138 | BN_mod(n, N, B, bn_ctx); |
139 | nout = BN_get_word(n); |
140 | *outbuf++ = nout; |
141 | |
142 | BN_rshift(N, N, 32); |
143 | } |
144 | |
145 | |
146 | for (i = 0; i < nwords; ++i) { |
147 | uint32_t rrout; |
148 | |
149 | BN_mod(rr, RR, B, bn_ctx); |
150 | rrout = BN_get_word(rr); |
151 | *outbuf++ = rrout; |
152 | |
153 | BN_rshift(RR, RR, 32); |
154 | } |
155 | |
156 | outbuf = NULL; |
157 | retval = 0; |
158 | |
159 | done: |
160 | free(outbuf); |
| 11 | | Argument to free() is offset by 4 bytes from the start of memory allocated by malloc() |
|
161 | |
162 | BN_free(Big1); |
163 | BN_free(Big2); |
164 | BN_free(Big32); |
165 | BN_free(BigMinus1); |
166 | BN_free(N0inv); |
167 | BN_free(R); |
168 | BN_free(RRTemp); |
169 | BN_free(NnumBits); |
170 | BN_free(n); |
171 | BN_free(rr); |
172 | |
173 | return retval; |
174 | } |
175 | |
176 | static int vb_keyb_from_p11_key(struct pkcs11_key *p11_key, uint8_t **keyb_data, |
177 | uint32_t *keyb_size) |
178 | { |
179 | int ret = 1; |
180 | uint32_t modulus_size = 0; |
181 | BIGNUM *N = NULL; |
182 | uint8_t *modulus = pkcs11_get_modulus(p11_key, &modulus_size); |
183 | if (!modulus) { |
184 | fprintf(stderr, "Failed to get modulus from PKCS#11 key\n"); |
185 | goto done; |
186 | } |
187 | |
188 | N = BN_bin2bn(modulus, modulus_size, NULL); |
189 | if (!N) { |
190 | fprintf(stderr, "Failed to call BN_bin2bn()\n"); |
191 | goto done; |
192 | } |
193 | ret = vb_keyb_from_modulus(N, modulus_size, keyb_data, keyb_size); |
194 | done: |
195 | BN_free(N); |
196 | free(modulus); |
197 | return ret; |
198 | } |
199 | |
200 | int vb_keyb_from_rsa(struct rsa_st *rsa_private_key, uint8_t **keyb_data, uint32_t *keyb_size) |
201 | { |
202 | const BIGNUM *N; |
203 | RSA_get0_key(rsa_private_key, &N, NULL, NULL); |
204 | if (!N) { |
| 3 | | Assuming 'N' is non-null | |
|
| |
205 | fprintf(stderr, "Failed to get N from RSA private key\n"); |
206 | return 1; |
207 | } |
208 | return vb_keyb_from_modulus(N, RSA_size(rsa_private_key), keyb_data, keyb_size); |
| 5 | | Calling 'vb_keyb_from_modulus' | |
|
209 | } |
210 | |
211 | int vb_keyb_from_private_key(struct vb2_private_key *private_key, uint8_t **keyb_data, |
212 | uint32_t *keyb_size) |
213 | { |
214 | switch (private_key->key_location) { |
| 1 | Control jumps to 'case PRIVATE_KEY_LOCAL:' at line 217 | |
|
215 | case PRIVATE_KEY_P11: |
216 | return vb_keyb_from_p11_key(private_key->p11_key, keyb_data, keyb_size); |
217 | case PRIVATE_KEY_LOCAL: |
218 | return vb_keyb_from_rsa(private_key->rsa_private_key, keyb_data, keyb_size); |
| 2 | | Calling 'vb_keyb_from_rsa' | |
|
219 | } |
220 | return 1; |
221 | } |
222 | |
223 | enum vb2_signature_algorithm vb2_get_sig_alg(uint32_t exp, uint32_t bits) |
224 | { |
225 | switch (exp) { |
226 | case RSA_3: |
227 | switch (bits) { |
228 | case 2048: |
229 | return VB2_SIG_RSA2048_EXP3; |
230 | case 3072: |
231 | return VB2_SIG_RSA3072_EXP3; |
232 | } |
233 | break; |
234 | case RSA_F4: |
235 | switch (bits) { |
236 | case 1024: |
237 | return VB2_SIG_RSA1024; |
238 | case 2048: |
239 | return VB2_SIG_RSA2048; |
240 | case 4096: |
241 | return VB2_SIG_RSA4096; |
242 | case 8192: |
243 | return VB2_SIG_RSA8192; |
244 | } |
245 | } |
246 | |
247 | |
248 | return VB2_SIG_INVALID; |
249 | } |