^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Parse a signed PE binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define pr_fmt(fmt) "PEFILE: "fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/pe.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/asn1.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/verification.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <crypto/hash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "verify_pefile.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Parse a PE binary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static int pefile_parse_binary(const void *pebuf, unsigned int pelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct pefile_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) const struct mz_hdr *mz = pebuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) const struct pe_hdr *pe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) const struct pe32_opt_hdr *pe32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) const struct pe32plus_opt_hdr *pe64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) const struct data_directory *ddir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) const struct data_dirent *dde;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) const struct section_header *secs, *sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) size_t cursor, datalen = pelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) kenter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define chkaddr(base, x, s) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if ((x) < base || (s) >= datalen || (x) > datalen - (s)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return -ELIBBAD; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) chkaddr(0, 0, sizeof(*mz));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (mz->magic != MZ_MAGIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return -ELIBBAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) cursor = sizeof(*mz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) chkaddr(cursor, mz->peaddr, sizeof(*pe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) pe = pebuf + mz->peaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (pe->magic != PE_MAGIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return -ELIBBAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) cursor = mz->peaddr + sizeof(*pe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) chkaddr(0, cursor, sizeof(pe32->magic));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) pe32 = pebuf + cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) pe64 = pebuf + cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) switch (pe32->magic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) case PE_OPT_MAGIC_PE32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) chkaddr(0, cursor, sizeof(*pe32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) ctx->image_checksum_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) (unsigned long)&pe32->csum - (unsigned long)pebuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ctx->header_size = pe32->header_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) cursor += sizeof(*pe32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ctx->n_data_dirents = pe32->data_dirs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) case PE_OPT_MAGIC_PE32PLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) chkaddr(0, cursor, sizeof(*pe64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ctx->image_checksum_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) (unsigned long)&pe64->csum - (unsigned long)pebuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ctx->header_size = pe64->header_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) cursor += sizeof(*pe64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ctx->n_data_dirents = pe64->data_dirs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) pr_debug("Unknown PEOPT magic = %04hx\n", pe32->magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return -ELIBBAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) pr_debug("checksum @ %x\n", ctx->image_checksum_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) pr_debug("header size = %x\n", ctx->header_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (cursor >= ctx->header_size || ctx->header_size >= datalen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return -ELIBBAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (ctx->n_data_dirents > (ctx->header_size - cursor) / sizeof(*dde))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return -ELIBBAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ddir = pebuf + cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) cursor += sizeof(*dde) * ctx->n_data_dirents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ctx->cert_dirent_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) (unsigned long)&ddir->certs - (unsigned long)pebuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ctx->certs_size = ddir->certs.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (!ddir->certs.virtual_address || !ddir->certs.size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) pr_debug("Unsigned PE binary\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) chkaddr(ctx->header_size, ddir->certs.virtual_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ddir->certs.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ctx->sig_offset = ddir->certs.virtual_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ctx->sig_len = ddir->certs.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) pr_debug("cert = %x @%x [%*ph]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) ctx->sig_len, ctx->sig_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ctx->sig_len, pebuf + ctx->sig_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ctx->n_sections = pe->sections;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (ctx->n_sections > (ctx->header_size - cursor) / sizeof(*sec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return -ELIBBAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ctx->secs = secs = pebuf + cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * Check and strip the PE wrapper from around the signature and check that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * remnant looks something like PKCS#7.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int pefile_strip_sig_wrapper(const void *pebuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct pefile_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct win_certificate wrapper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) const u8 *pkcs7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) unsigned len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (ctx->sig_len < sizeof(wrapper)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) pr_debug("Signature wrapper too short\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return -ELIBBAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) memcpy(&wrapper, pebuf + ctx->sig_offset, sizeof(wrapper));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) pr_debug("sig wrapper = { %x, %x, %x }\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) wrapper.length, wrapper.revision, wrapper.cert_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* Both pesign and sbsign round up the length of certificate table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * (in optional header data directories) to 8 byte alignment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (round_up(wrapper.length, 8) != ctx->sig_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) pr_debug("Signature wrapper len wrong\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return -ELIBBAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (wrapper.revision != WIN_CERT_REVISION_2_0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) pr_debug("Signature is not revision 2.0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (wrapper.cert_type != WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) pr_debug("Signature certificate type is not PKCS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* It looks like the pkcs signature length in wrapper->length and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * size obtained from the data dir entries, which lists the total size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * of certificate table, are both aligned to an octaword boundary, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * we may have to deal with some padding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ctx->sig_len = wrapper.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ctx->sig_offset += sizeof(wrapper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ctx->sig_len -= sizeof(wrapper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (ctx->sig_len < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) pr_debug("Signature data missing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return -EKEYREJECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* What's left should be a PKCS#7 cert */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) pkcs7 = pebuf + ctx->sig_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (pkcs7[0] != (ASN1_CONS_BIT | ASN1_SEQ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) goto not_pkcs7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) switch (pkcs7[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) case 0 ... 0x7f:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) len = pkcs7[1] + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) goto check_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case ASN1_INDEFINITE_LENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) case 0x81:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) len = pkcs7[2] + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) goto check_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) case 0x82:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) len = ((pkcs7[2] << 8) | pkcs7[3]) + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) goto check_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case 0x83 ... 0xff:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) goto not_pkcs7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) check_len:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (len <= ctx->sig_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /* There may be padding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ctx->sig_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) not_pkcs7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) pr_debug("Signature data not PKCS#7\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return -ELIBBAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * Compare two sections for canonicalisation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static int pefile_compare_shdrs(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) const struct section_header *shdra = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) const struct section_header *shdrb = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (shdra->data_addr > shdrb->data_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (shdrb->data_addr > shdra->data_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (shdra->virtual_address > shdrb->virtual_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (shdrb->virtual_address > shdra->virtual_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) rc = strcmp(shdra->name, shdrb->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (shdra->virtual_size > shdrb->virtual_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (shdrb->virtual_size > shdra->virtual_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (shdra->raw_data_size > shdrb->raw_data_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (shdrb->raw_data_size > shdra->raw_data_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * Load the contents of the PE binary into the digest, leaving out the image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * checksum and the certificate data block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int pefile_digest_pe_contents(const void *pebuf, unsigned int pelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct pefile_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct shash_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) unsigned *canon, tmp, loop, i, hashed_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* Digest the header and data directory, but leave out the image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * checksum and the data dirent for the signature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ret = crypto_shash_update(desc, pebuf, ctx->image_checksum_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) tmp = ctx->image_checksum_offset + sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ret = crypto_shash_update(desc, pebuf + tmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ctx->cert_dirent_offset - tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) tmp = ctx->cert_dirent_offset + sizeof(struct data_dirent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ret = crypto_shash_update(desc, pebuf + tmp, ctx->header_size - tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) canon = kcalloc(ctx->n_sections, sizeof(unsigned), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (!canon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* We have to canonicalise the section table, so we perform an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * insertion sort.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) canon[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) for (loop = 1; loop < ctx->n_sections; loop++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) for (i = 0; i < loop; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (pefile_compare_shdrs(&ctx->secs[canon[i]],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) &ctx->secs[loop]) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) memmove(&canon[i + 1], &canon[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) (loop - i) * sizeof(canon[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) canon[i] = loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) hashed_bytes = ctx->header_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) for (loop = 0; loop < ctx->n_sections; loop++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) i = canon[loop];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (ctx->secs[i].raw_data_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) ret = crypto_shash_update(desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) pebuf + ctx->secs[i].data_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ctx->secs[i].raw_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) kfree(canon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) hashed_bytes += ctx->secs[i].raw_data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) kfree(canon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (pelen > hashed_bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) tmp = hashed_bytes + ctx->certs_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ret = crypto_shash_update(desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) pebuf + hashed_bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) pelen - tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * Digest the contents of the PE binary, leaving out the image checksum and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * certificate data block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static int pefile_digest_pe(const void *pebuf, unsigned int pelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct pefile_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct crypto_shash *tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct shash_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) size_t digest_size, desc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) void *digest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) kenter(",%s", ctx->digest_algo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /* Allocate the hashing algorithm we're going to need and find out how
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * big the hash operational data will be.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) tfm = crypto_alloc_shash(ctx->digest_algo, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (IS_ERR(tfm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) digest_size = crypto_shash_digestsize(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (digest_size != ctx->digest_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) pr_debug("Digest size mismatch (%zx != %x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) digest_size, ctx->digest_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) ret = -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) goto error_no_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) pr_debug("Digest: desc=%zu size=%zu\n", desc_size, digest_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) desc = kzalloc(desc_size + digest_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (!desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) goto error_no_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) desc->tfm = tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ret = crypto_shash_init(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ret = pefile_digest_pe_contents(pebuf, pelen, ctx, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) digest = (void *)desc + desc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) ret = crypto_shash_final(desc, digest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) pr_debug("Digest calc = [%*ph]\n", ctx->digest_len, digest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* Check that the PE file digest matches that in the MSCODE part of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * PKCS#7 certificate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (memcmp(digest, ctx->digest, ctx->digest_len) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) pr_debug("Digest mismatch\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ret = -EKEYREJECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) pr_debug("The digests match!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) kfree_sensitive(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) error_no_desc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) crypto_free_shash(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) kleave(" = %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * verify_pefile_signature - Verify the signature on a PE binary image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * @pebuf: Buffer containing the PE binary image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * @pelen: Length of the binary image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * @trust_keys: Signing certificate(s) to use as starting points
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * @usage: The use to which the key is being put.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * Validate that the certificate chain inside the PKCS#7 message inside the PE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * binary image intersects keys we already know and trust.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * Returns, in order of descending priority:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * (*) -ELIBBAD if the image cannot be parsed, or:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * (*) -EKEYREJECTED if a signature failed to match for which we have a valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * key, or:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * (*) 0 if at least one signature chain intersects with the keys in the trust
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * keyring, or:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * (*) -ENODATA if there is no signature present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * (*) -ENOPKG if a suitable crypto module couldn't be found for a check on a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * chain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * (*) -ENOKEY if we couldn't find a match for any of the signature chains in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * the message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * May also return -ENOMEM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) int verify_pefile_signature(const void *pebuf, unsigned pelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct key *trusted_keys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) enum key_being_used_for usage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct pefile_context ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) kenter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) memset(&ctx, 0, sizeof(ctx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ret = pefile_parse_binary(pebuf, pelen, &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ret = pefile_strip_sig_wrapper(pebuf, &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ret = verify_pkcs7_signature(NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) pebuf + ctx.sig_offset, ctx.sig_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) trusted_keys, usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) mscode_parse, &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) pr_debug("Digest: %u [%*ph]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ctx.digest_len, ctx.digest_len, ctx.digest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /* Generate the digest and check against the PKCS7 certificate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * contents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) ret = pefile_digest_pe(pebuf, pelen, &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) kfree_sensitive(ctx.digest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }