// SPDX-License-Identifier: GPL-2.0-or-later /* Parse a signed PE binary * * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved. * Written by David Howells ([email protected]) */ #define pr_fmt(fmt) … #include <linux/module.h> #include <linux/kernel.h> #include <linux/slab.h> #include <linux/err.h> #include <linux/pe.h> #include <linux/asn1.h> #include <linux/verification.h> #include <crypto/hash.h> #include "verify_pefile.h" /* * Parse a PE binary. */ static int pefile_parse_binary(const void *pebuf, unsigned int pelen, struct pefile_context *ctx) { … } /* * Check and strip the PE wrapper from around the signature and check that the * remnant looks something like PKCS#7. */ static int pefile_strip_sig_wrapper(const void *pebuf, struct pefile_context *ctx) { … } /* * Compare two sections for canonicalisation. */ static int pefile_compare_shdrs(const void *a, const void *b) { … } /* * Load the contents of the PE binary into the digest, leaving out the image * checksum and the certificate data block. */ static int pefile_digest_pe_contents(const void *pebuf, unsigned int pelen, struct pefile_context *ctx, struct shash_desc *desc) { … } /* * Digest the contents of the PE binary, leaving out the image checksum and the * certificate data block. */ static int pefile_digest_pe(const void *pebuf, unsigned int pelen, struct pefile_context *ctx) { … } /** * verify_pefile_signature - Verify the signature on a PE binary image * @pebuf: Buffer containing the PE binary image * @pelen: Length of the binary image * @trusted_keys: Signing certificate(s) to use as starting points * @usage: The use to which the key is being put. * * Validate that the certificate chain inside the PKCS#7 message inside the PE * binary image intersects keys we already know and trust. * * Returns, in order of descending priority: * * (*) -ELIBBAD if the image cannot be parsed, or: * * (*) -EKEYREJECTED if a signature failed to match for which we have a valid * key, or: * * (*) 0 if at least one signature chain intersects with the keys in the trust * keyring, or: * * (*) -ENODATA if there is no signature present. * * (*) -ENOPKG if a suitable crypto module couldn't be found for a check on a * chain. * * (*) -ENOKEY if we couldn't find a match for any of the signature chains in * the message. * * May also return -ENOMEM. */ int verify_pefile_signature(const void *pebuf, unsigned pelen, struct key *trusted_keys, enum key_being_used_for usage) { … }