.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* Parse a signed PE binary |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved. |
---|
4 | 5 | * Written by David Howells (dhowells@redhat.com) |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or |
---|
7 | | - * modify it under the terms of the GNU General Public Licence |
---|
8 | | - * as published by the Free Software Foundation; either version |
---|
9 | | - * 2 of the Licence, or (at your option) any later version. |
---|
10 | 6 | */ |
---|
11 | 7 | |
---|
12 | 8 | #define pr_fmt(fmt) "PEFILE: "fmt |
---|
.. | .. |
---|
78 | 74 | break; |
---|
79 | 75 | |
---|
80 | 76 | default: |
---|
81 | | - pr_debug("Unknown PEOPT magic = %04hx\n", pe32->magic); |
---|
| 77 | + pr_warn("Unknown PEOPT magic = %04hx\n", pe32->magic); |
---|
82 | 78 | return -ELIBBAD; |
---|
83 | 79 | } |
---|
84 | 80 | |
---|
.. | .. |
---|
99 | 95 | ctx->certs_size = ddir->certs.size; |
---|
100 | 96 | |
---|
101 | 97 | if (!ddir->certs.virtual_address || !ddir->certs.size) { |
---|
102 | | - pr_debug("Unsigned PE binary\n"); |
---|
103 | | - return -EKEYREJECTED; |
---|
| 98 | + pr_warn("Unsigned PE binary\n"); |
---|
| 99 | + return -ENODATA; |
---|
104 | 100 | } |
---|
105 | 101 | |
---|
106 | 102 | chkaddr(ctx->header_size, ddir->certs.virtual_address, |
---|
.. | .. |
---|
131 | 127 | unsigned len; |
---|
132 | 128 | |
---|
133 | 129 | if (ctx->sig_len < sizeof(wrapper)) { |
---|
134 | | - pr_debug("Signature wrapper too short\n"); |
---|
| 130 | + pr_warn("Signature wrapper too short\n"); |
---|
135 | 131 | return -ELIBBAD; |
---|
136 | 132 | } |
---|
137 | 133 | |
---|
.. | .. |
---|
139 | 135 | pr_debug("sig wrapper = { %x, %x, %x }\n", |
---|
140 | 136 | wrapper.length, wrapper.revision, wrapper.cert_type); |
---|
141 | 137 | |
---|
142 | | - /* Both pesign and sbsign round up the length of certificate table |
---|
143 | | - * (in optional header data directories) to 8 byte alignment. |
---|
| 138 | + /* sbsign rounds up the length of certificate table (in optional |
---|
| 139 | + * header data directories) to 8 byte alignment. However, the PE |
---|
| 140 | + * specification states that while entries are 8-byte aligned, this is |
---|
| 141 | + * not included in their length, and as a result, pesign has not |
---|
| 142 | + * rounded up since 0.110. |
---|
144 | 143 | */ |
---|
145 | | - if (round_up(wrapper.length, 8) != ctx->sig_len) { |
---|
146 | | - pr_debug("Signature wrapper len wrong\n"); |
---|
| 144 | + if (wrapper.length > ctx->sig_len) { |
---|
| 145 | + pr_warn("Signature wrapper bigger than sig len (%x > %x)\n", |
---|
| 146 | + ctx->sig_len, wrapper.length); |
---|
147 | 147 | return -ELIBBAD; |
---|
148 | 148 | } |
---|
149 | 149 | if (wrapper.revision != WIN_CERT_REVISION_2_0) { |
---|
150 | | - pr_debug("Signature is not revision 2.0\n"); |
---|
| 150 | + pr_warn("Signature is not revision 2.0\n"); |
---|
151 | 151 | return -ENOTSUPP; |
---|
152 | 152 | } |
---|
153 | 153 | if (wrapper.cert_type != WIN_CERT_TYPE_PKCS_SIGNED_DATA) { |
---|
154 | | - pr_debug("Signature certificate type is not PKCS\n"); |
---|
| 154 | + pr_warn("Signature certificate type is not PKCS\n"); |
---|
155 | 155 | return -ENOTSUPP; |
---|
156 | 156 | } |
---|
157 | 157 | |
---|
.. | .. |
---|
164 | 164 | ctx->sig_offset += sizeof(wrapper); |
---|
165 | 165 | ctx->sig_len -= sizeof(wrapper); |
---|
166 | 166 | if (ctx->sig_len < 4) { |
---|
167 | | - pr_debug("Signature data missing\n"); |
---|
| 167 | + pr_warn("Signature data missing\n"); |
---|
168 | 168 | return -EKEYREJECTED; |
---|
169 | 169 | } |
---|
170 | 170 | |
---|
.. | .. |
---|
198 | 198 | return 0; |
---|
199 | 199 | } |
---|
200 | 200 | not_pkcs7: |
---|
201 | | - pr_debug("Signature data not PKCS#7\n"); |
---|
| 201 | + pr_warn("Signature data not PKCS#7\n"); |
---|
202 | 202 | return -ELIBBAD; |
---|
203 | 203 | } |
---|
204 | 204 | |
---|
.. | .. |
---|
341 | 341 | digest_size = crypto_shash_digestsize(tfm); |
---|
342 | 342 | |
---|
343 | 343 | if (digest_size != ctx->digest_len) { |
---|
344 | | - pr_debug("Digest size mismatch (%zx != %x)\n", |
---|
345 | | - digest_size, ctx->digest_len); |
---|
| 344 | + pr_warn("Digest size mismatch (%zx != %x)\n", |
---|
| 345 | + digest_size, ctx->digest_len); |
---|
346 | 346 | ret = -EBADMSG; |
---|
347 | 347 | goto error_no_desc; |
---|
348 | 348 | } |
---|
.. | .. |
---|
354 | 354 | goto error_no_desc; |
---|
355 | 355 | |
---|
356 | 356 | desc->tfm = tfm; |
---|
357 | | - desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
---|
358 | 357 | ret = crypto_shash_init(desc); |
---|
359 | 358 | if (ret < 0) |
---|
360 | 359 | goto error; |
---|
.. | .. |
---|
374 | 373 | * PKCS#7 certificate. |
---|
375 | 374 | */ |
---|
376 | 375 | if (memcmp(digest, ctx->digest, ctx->digest_len) != 0) { |
---|
377 | | - pr_debug("Digest mismatch\n"); |
---|
| 376 | + pr_warn("Digest mismatch\n"); |
---|
378 | 377 | ret = -EKEYREJECTED; |
---|
379 | 378 | } else { |
---|
380 | 379 | pr_debug("The digests match!\n"); |
---|
381 | 380 | } |
---|
382 | 381 | |
---|
383 | 382 | error: |
---|
384 | | - kzfree(desc); |
---|
| 383 | + kfree_sensitive(desc); |
---|
385 | 384 | error_no_desc: |
---|
386 | 385 | crypto_free_shash(tfm); |
---|
387 | 386 | kleave(" = %d", ret); |
---|
.. | .. |
---|
407 | 406 | * |
---|
408 | 407 | * (*) 0 if at least one signature chain intersects with the keys in the trust |
---|
409 | 408 | * keyring, or: |
---|
| 409 | + * |
---|
| 410 | + * (*) -ENODATA if there is no signature present. |
---|
410 | 411 | * |
---|
411 | 412 | * (*) -ENOPKG if a suitable crypto module couldn't be found for a check on a |
---|
412 | 413 | * chain. |
---|
.. | .. |
---|
450 | 451 | ret = pefile_digest_pe(pebuf, pelen, &ctx); |
---|
451 | 452 | |
---|
452 | 453 | error: |
---|
453 | | - kzfree(ctx.digest); |
---|
| 454 | + kfree_sensitive(ctx.digest); |
---|
454 | 455 | return ret; |
---|
455 | 456 | } |
---|