linux-imx/scripts/sign-file.c
Greg Kroah-Hartman 72861b2e9f Merge 6.6.8 into android15-6.6
Changes in 6.6.8
	r8152: add vendor/device ID pair for ASUS USB-C2500
	ext4: fix warning in ext4_dio_write_end_io()
	ksmbd: fix memory leak in smb2_lock()
	efi/x86: Avoid physical KASLR on older Dell systems
	afs: Fix refcount underflow from error handling race
	HID: lenovo: Restrict detection of patched firmware only to USB cptkbd
	net/mlx5e: Honor user choice of IPsec replay window size
	net/mlx5e: Ensure that IPsec sequence packet number starts from 1
	net/mlx5e: Unify esw and normal IPsec status table creation/destruction
	net/mlx5e: Tidy up IPsec NAT-T SA discovery
	net/mlx5e: Reduce eswitch mode_lock protection context
	net/mlx5e: Check the number of elements before walk TC rhashtable
	RDMA/mlx5: Send events from IB driver about device affiliation state
	net/mlx5e: Disable IPsec offload support if not FW steering
	net/mlx5e: Fix possible deadlock on mlx5e_tx_timeout_work
	net/mlx5e: TC, Don't offload post action rule if not supported
	net/mlx5: Nack sync reset request when HotPlug is enabled
	net/mlx5e: Check netdev pointer before checking its net ns
	net/mlx5: Fix a NULL vs IS_ERR() check
	net: ipv6: support reporting otherwise unknown prefix flags in RTM_NEWPREFIX
	qca_debug: Prevent crash on TX ring changes
	qca_debug: Fix ethtool -G iface tx behavior
	qca_spi: Fix reset behavior
	bnxt_en: Clear resource reservation during resume
	bnxt_en: Fix skb recycling logic in bnxt_deliver_skb()
	bnxt_en: Fix wrong return value check in bnxt_close_nic()
	bnxt_en: Fix HWTSTAMP_FILTER_ALL packet timestamp logic
	atm: solos-pci: Fix potential deadlock on &cli_queue_lock
	atm: solos-pci: Fix potential deadlock on &tx_queue_lock
	net: fec: correct queue selection
	octeontx2-af: fix a use-after-free in rvu_nix_register_reporters
	net/sched: act_ct: Take per-cb reference to tcf_ct_flow_table
	octeon_ep: explicitly test for firmware ready value
	octeontx2-pf: Fix promisc mcam entry action
	octeontx2-af: Update RSS algorithm index
	octeontx2-af: Fix pause frame configuration
	atm: Fix Use-After-Free in do_vcc_ioctl
	net/rose: Fix Use-After-Free in rose_ioctl
	iavf: Introduce new state machines for flow director
	iavf: Handle ntuple on/off based on new state machines for flow director
	iavf: Fix iavf_shutdown to call iavf_remove instead iavf_close
	qed: Fix a potential use-after-free in qed_cxt_tables_alloc
	net: Remove acked SYN flag from packet in the transmit queue correctly
	net: ena: Destroy correct number of xdp queues upon failure
	net: ena: Fix xdp drops handling due to multibuf packets
	net: ena: Fix DMA syncing in XDP path when SWIOTLB is on
	net: ena: Fix XDP redirection error
	stmmac: dwmac-loongson: Make sure MDIO is initialized before use
	sign-file: Fix incorrect return values check
	vsock/virtio: Fix unsigned integer wrap around in virtio_transport_has_space()
	dpaa2-switch: fix size of the dma_unmap
	dpaa2-switch: do not ask for MDB, VLAN and FDB replay
	net: stmmac: dwmac-qcom-ethqos: Fix drops in 10M SGMII RX
	net: stmmac: Handle disabled MDIO busses from devicetree
	appletalk: Fix Use-After-Free in atalk_ioctl
	net: atlantic: fix double free in ring reinit logic
	cred: switch to using atomic_long_t
	cred: get rid of CONFIG_DEBUG_CREDENTIALS
	HID: i2c-hid: Add IDEA5002 to i2c_hid_acpi_blacklist[]
	HID: Add quirk for Labtec/ODDOR/aikeec handbrake
	fuse: Rename DIRECT_IO_RELAX to DIRECT_IO_ALLOW_MMAP
	fuse: share lookup state between submount and its parent
	fuse: disable FOPEN_PARALLEL_DIRECT_WRITES with FUSE_DIRECT_IO_ALLOW_MMAP
	fuse: dax: set fc->dax to NULL in fuse_dax_conn_free()
	io_uring/cmd: fix breakage in SOCKET_URING_OP_SIOC* implementation
	ALSA: hda/hdmi: add force-connect quirk for NUC5CPYB
	ALSA: hda/hdmi: add force-connect quirks for ASUSTeK Z170 variants
	ALSA: hda/realtek: Apply mute LED quirk for HP15-db
	ALSA: hda/tas2781: leave hda_component in usable state
	ALSA: hda/tas2781: handle missing EFI calibration data
	ALSA: hda/tas2781: call cleanup functions only once
	ALSA: hda/tas2781: reset the amp before component_add
	Revert "PCI: acpiphp: Reassign resources on bridge if necessary"
	PCI: loongson: Limit MRRS to 256
	PCI/ASPM: Add pci_enable_link_state_locked()
	ksmbd: fix wrong name of SMB2_CREATE_ALLOCATION_SIZE
	PCI: vmd: Fix potential deadlock when enabling ASPM
	drm/mediatek: fix kernel oops if no crtc is found
	drm/mediatek: Add spinlock for setting vblank event in atomic_begin
	accel/ivpu: Print information about used workarounds
	accel/ivpu/37xx: Fix interrupt_clear_with_0 WA initialization
	drm/i915/selftests: Fix engine reset count storage for multi-tile
	drm/i915: Use internal class when counting engine resets
	selftests/mm: cow: print ksft header before printing anything else
	x86/hyperv: Fix the detection of E820_TYPE_PRAM in a Gen2 VM
	usb: aqc111: check packet for fixup for true limit
	stmmac: dwmac-loongson: Add architecture dependency
	rxrpc: Fix some minor issues with bundle tracing
	blk-throttle: fix lockdep warning of "cgroup_mutex or RCU read lock required!"
	blk-cgroup: bypass blkcg_deactivate_policy after destroying
	bcache: avoid oversize memory allocation by small stripe_size
	bcache: remove redundant assignment to variable cur_idx
	bcache: add code comments for bch_btree_node_get() and __bch_btree_node_alloc()
	bcache: avoid NULL checking to c->root in run_cache_set()
	nbd: fold nbd config initialization into nbd_alloc_config()
	nbd: factor out a helper to get nbd_config without holding 'config_lock'
	nbd: fix null-ptr-dereference while accessing 'nbd->config'
	nvme-auth: set explanation code for failure2 msgs
	nvme: catch errors from nvme_configure_metadata()
	selftests/bpf: fix bpf_loop_bench for new callback verification scheme
	LoongArch: Add dependency between vmlinuz.efi and vmlinux.efi
	LoongArch: Record pc instead of offset in la_abs relocation
	LoongArch: Silence the boot warning about 'nokaslr'
	LoongArch: Mark {dmw,tlb}_virt_to_page() exports as non-GPL
	LoongArch: Implement constant timer shutdown interface
	platform/x86: intel_telemetry: Fix kernel doc descriptions
	HID: mcp2221: Set driver data before I2C adapter add
	HID: mcp2221: Allow IO to start during probe
	HID: apple: add Jamesdonkey and A3R to non-apple keyboards list
	HID: glorious: fix Glorious Model I HID report
	HID: add ALWAYS_POLL quirk for Apple kb
	nbd: pass nbd_sock to nbd_read_reply() instead of index
	HID: hid-asus: reset the backlight brightness level on resume
	HID: multitouch: Add quirk for HONOR GLO-GXXX touchpad
	nfc: virtual_ncidev: Add variable to check if ndev is running
	scripts/checkstack.pl: match all stack sizes for s390
	asm-generic: qspinlock: fix queued_spin_value_unlocked() implementation
	eventfs: Do not allow NULL parent to eventfs_start_creating()
	net: usb: qmi_wwan: claim interface 4 for ZTE MF290
	smb: client: implement ->query_reparse_point() for SMB1
	smb: client: introduce ->parse_reparse_point()
	smb: client: set correct file type from NFS reparse points
	arm64: add dependency between vmlinuz.efi and Image
	HID: hid-asus: add const to read-only outgoing usb buffer
	perf: Fix perf_event_validate_size() lockdep splat
	btrfs: do not allow non subvolume root targets for snapshot
	cxl/hdm: Fix dpa translation locking
	soundwire: stream: fix NULL pointer dereference for multi_link
	ext4: prevent the normalized size from exceeding EXT_MAX_BLOCKS
	Revert "selftests: error out if kernel header files are not yet built"
	arm64: mm: Always make sw-dirty PTEs hw-dirty in pte_modify
	team: Fix use-after-free when an option instance allocation fails
	drm/amdgpu/sdma5.2: add begin/end_use ring callbacks
	drm/mediatek: Fix access violation in mtk_drm_crtc_dma_dev_get
	dmaengine: stm32-dma: avoid bitfield overflow assertion
	dmaengine: fsl-edma: fix DMA channel leak in eDMAv4
	mm/mglru: fix underprotected page cache
	mm/mglru: try to stop at high watermarks
	mm/mglru: respect min_ttl_ms with memcgs
	mm/mglru: reclaim offlined memcgs harder
	mm/shmem: fix race in shmem_undo_range w/THP
	kexec: drop dependency on ARCH_SUPPORTS_KEXEC from CRASH_DUMP
	btrfs: free qgroup reserve when ORDERED_IOERR is set
	btrfs: fix qgroup_free_reserved_data int overflow
	btrfs: don't clear qgroup reserved bit in release_folio
	drm/amdgpu: fix tear down order in amdgpu_vm_pt_free
	drm/edid: also call add modes in EDID connector update fallback
	drm/amd/display: Restore guard against default backlight value < 1 nit
	drm/amd/display: Disable PSR-SU on Parade 0803 TCON again
	drm/i915: Fix ADL+ tiled plane stride when the POT stride is smaller than the original
	drm/i915: Fix intel_atomic_setup_scalers() plane_state handling
	drm/i915: Fix remapped stride with CCS on ADL+
	smb: client: fix OOB in receive_encrypted_standard()
	smb: client: fix potential OOBs in smb2_parse_contexts()
	smb: client: fix NULL deref in asn1_ber_decoder()
	smb: client: fix OOB in smb2_query_reparse_point()
	ring-buffer: Fix memory leak of free page
	tracing: Update snapshot buffer on resize if it is allocated
	ring-buffer: Do not update before stamp when switching sub-buffers
	ring-buffer: Have saved event hold the entire event
	ring-buffer: Fix writing to the buffer with max_data_size
	ring-buffer: Fix a race in rb_time_cmpxchg() for 32 bit archs
	ring-buffer: Do not try to put back write_stamp
	ring-buffer: Have rb_time_cmpxchg() set the msb counter too
	x86/speculation, objtool: Use absolute relocations for annotations
	RDMA/mlx5: Change the key being sent for MPV device affiliation
	Linux 6.6.8

Change-Id: If1768daf2d29c66ae271cde6f56664d10d500b77
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
2024-01-02 10:34:37 +00:00

410 lines
10 KiB
C

/* Sign a module file using the given key.
*
* Copyright © 2014-2016 Red Hat, Inc. All Rights Reserved.
* Copyright © 2015 Intel Corporation.
* Copyright © 2016 Hewlett Packard Enterprise Development LP
*
* Authors: David Howells <dhowells@redhat.com>
* David Woodhouse <dwmw2@infradead.org>
* Juerg Haefliger <juerg.haefliger@hpe.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the licence, or (at your option) any later version.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <getopt.h>
#include <err.h>
#include <arpa/inet.h>
#include <openssl/opensslv.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/engine.h>
/*
* OpenSSL 3.0 deprecates the OpenSSL's ENGINE API.
*
* Remove this if/when that API is no longer used
*/
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
/*
* Use CMS if we have openssl-1.0.0 or newer available - otherwise we have to
* assume that it's not available and its header file is missing and that we
* should use PKCS#7 instead. Switching to the older PKCS#7 format restricts
* the options we have on specifying the X.509 certificate we want.
*
* Further, older versions of OpenSSL don't support manually adding signers to
* the PKCS#7 message so have to accept that we get a certificate included in
* the signature message. Nor do such older versions of OpenSSL support
* signing with anything other than SHA1 - so we're stuck with that if such is
* the case.
*/
#if defined(LIBRESSL_VERSION_NUMBER) || \
OPENSSL_VERSION_NUMBER < 0x10000000L || \
defined(OPENSSL_NO_CMS)
#define USE_PKCS7
#endif
#ifndef USE_PKCS7
#include <openssl/cms.h>
#else
#include <openssl/pkcs7.h>
#endif
struct module_signature {
uint8_t algo; /* Public-key crypto algorithm [0] */
uint8_t hash; /* Digest algorithm [0] */
uint8_t id_type; /* Key identifier type [PKEY_ID_PKCS7] */
uint8_t signer_len; /* Length of signer's name [0] */
uint8_t key_id_len; /* Length of key identifier [0] */
uint8_t __pad[3];
uint32_t sig_len; /* Length of signature data */
};
#define PKEY_ID_PKCS7 2
static char magic_number[] = "~Module signature appended~\n";
static __attribute__((noreturn))
void format(void)
{
fprintf(stderr,
"Usage: scripts/sign-file [-dp] <hash algo> <key> <x509> <module> [<dest>]\n");
fprintf(stderr,
" scripts/sign-file -s <raw sig> <hash algo> <x509> <module> [<dest>]\n");
exit(2);
}
static void display_openssl_errors(int l)
{
const char *file;
char buf[120];
int e, line;
if (ERR_peek_error() == 0)
return;
fprintf(stderr, "At main.c:%d:\n", l);
while ((e = ERR_get_error_line(&file, &line))) {
ERR_error_string(e, buf);
fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line);
}
}
#ifndef OPENSSL_NO_ENGINE
static void drain_openssl_errors(void)
{
const char *file;
int line;
if (ERR_peek_error() == 0)
return;
while (ERR_get_error_line(&file, &line)) {}
}
#endif
#define ERR(cond, fmt, ...) \
do { \
bool __cond = (cond); \
display_openssl_errors(__LINE__); \
if (__cond) { \
errx(1, fmt, ## __VA_ARGS__); \
} \
} while(0)
static const char *key_pass;
static int pem_pw_cb(char *buf, int len, int w, void *v)
{
int pwlen;
if (!key_pass)
return -1;
pwlen = strlen(key_pass);
if (pwlen >= len)
return -1;
strcpy(buf, key_pass);
/* If it's wrong, don't keep trying it. */
key_pass = NULL;
return pwlen;
}
static EVP_PKEY *read_private_key(const char *private_key_name)
{
EVP_PKEY *private_key;
BIO *b;
#ifndef OPENSSL_NO_ENGINE
if (!strncmp(private_key_name, "pkcs11:", 7)) {
ENGINE *e;
ENGINE_load_builtin_engines();
drain_openssl_errors();
e = ENGINE_by_id("pkcs11");
ERR(!e, "Load PKCS#11 ENGINE");
if (ENGINE_init(e))
drain_openssl_errors();
else
ERR(1, "ENGINE_init");
if (key_pass)
ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0),
"Set PKCS#11 PIN");
private_key = ENGINE_load_private_key(e, private_key_name,
NULL, NULL);
ERR(!private_key, "%s", private_key_name);
return private_key;
}
#endif
b = BIO_new_file(private_key_name, "rb");
ERR(!b, "%s", private_key_name);
private_key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb,
NULL);
ERR(!private_key, "%s", private_key_name);
BIO_free(b);
return private_key;
}
static X509 *read_x509(const char *x509_name)
{
unsigned char buf[2];
X509 *x509;
BIO *b;
int n;
b = BIO_new_file(x509_name, "rb");
ERR(!b, "%s", x509_name);
/* Look at the first two bytes of the file to determine the encoding */
n = BIO_read(b, buf, 2);
if (n != 2) {
if (BIO_should_retry(b)) {
fprintf(stderr, "%s: Read wanted retry\n", x509_name);
exit(1);
}
if (n >= 0) {
fprintf(stderr, "%s: Short read\n", x509_name);
exit(1);
}
ERR(1, "%s", x509_name);
}
ERR(BIO_reset(b) != 0, "%s", x509_name);
if (buf[0] == 0x30 && buf[1] >= 0x81 && buf[1] <= 0x84)
/* Assume raw DER encoded X.509 */
x509 = d2i_X509_bio(b, NULL);
else
/* Assume PEM encoded X.509 */
x509 = PEM_read_bio_X509(b, NULL, NULL, NULL);
BIO_free(b);
ERR(!x509, "%s", x509_name);
return x509;
}
int main(int argc, char **argv)
{
struct module_signature sig_info = { .id_type = PKEY_ID_PKCS7 };
char *hash_algo = NULL;
char *private_key_name = NULL, *raw_sig_name = NULL;
char *x509_name, *module_name, *dest_name;
bool save_sig = false, replace_orig;
bool sign_only = false;
bool raw_sig = false;
unsigned char buf[4096];
unsigned long module_size, sig_size;
unsigned int use_signed_attrs;
const EVP_MD *digest_algo;
EVP_PKEY *private_key;
#ifndef USE_PKCS7
CMS_ContentInfo *cms = NULL;
unsigned int use_keyid = 0;
#else
PKCS7 *pkcs7 = NULL;
#endif
X509 *x509;
BIO *bd, *bm;
int opt, n;
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
ERR_clear_error();
key_pass = getenv("KBUILD_SIGN_PIN");
#ifndef USE_PKCS7
use_signed_attrs = CMS_NOATTR;
#else
use_signed_attrs = PKCS7_NOATTR;
#endif
do {
opt = getopt(argc, argv, "sdpk");
switch (opt) {
case 's': raw_sig = true; break;
case 'p': save_sig = true; break;
case 'd': sign_only = true; save_sig = true; break;
#ifndef USE_PKCS7
case 'k': use_keyid = CMS_USE_KEYID; break;
#endif
case -1: break;
default: format();
}
} while (opt != -1);
argc -= optind;
argv += optind;
if (argc < 4 || argc > 5)
format();
if (raw_sig) {
raw_sig_name = argv[0];
hash_algo = argv[1];
} else {
hash_algo = argv[0];
private_key_name = argv[1];
}
x509_name = argv[2];
module_name = argv[3];
if (argc == 5 && strcmp(argv[3], argv[4]) != 0) {
dest_name = argv[4];
replace_orig = false;
} else {
ERR(asprintf(&dest_name, "%s.~signed~", module_name) < 0,
"asprintf");
replace_orig = true;
}
#ifdef USE_PKCS7
if (strcmp(hash_algo, "sha1") != 0) {
fprintf(stderr, "sign-file: %s only supports SHA1 signing\n",
OPENSSL_VERSION_TEXT);
exit(3);
}
#endif
/* Open the module file */
bm = BIO_new_file(module_name, "rb");
ERR(!bm, "%s", module_name);
if (!raw_sig) {
/* Read the private key and the X.509 cert the PKCS#7 message
* will point to.
*/
private_key = read_private_key(private_key_name);
x509 = read_x509(x509_name);
/* Digest the module data. */
OpenSSL_add_all_digests();
display_openssl_errors(__LINE__);
digest_algo = EVP_get_digestbyname(hash_algo);
ERR(!digest_algo, "EVP_get_digestbyname");
#ifndef USE_PKCS7
/* Load the signature message from the digest buffer. */
cms = CMS_sign(NULL, NULL, NULL, NULL,
CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY |
CMS_DETACHED | CMS_STREAM);
ERR(!cms, "CMS_sign");
ERR(!CMS_add1_signer(cms, x509, private_key, digest_algo,
CMS_NOCERTS | CMS_BINARY |
CMS_NOSMIMECAP | use_keyid |
use_signed_attrs),
"CMS_add1_signer");
ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) != 1,
"CMS_final");
#else
pkcs7 = PKCS7_sign(x509, private_key, NULL, bm,
PKCS7_NOCERTS | PKCS7_BINARY |
PKCS7_DETACHED | use_signed_attrs);
ERR(!pkcs7, "PKCS7_sign");
#endif
if (save_sig) {
char *sig_file_name;
BIO *b;
ERR(asprintf(&sig_file_name, "%s.p7s", module_name) < 0,
"asprintf");
b = BIO_new_file(sig_file_name, "wb");
ERR(!b, "%s", sig_file_name);
#ifndef USE_PKCS7
ERR(i2d_CMS_bio_stream(b, cms, NULL, 0) != 1,
"%s", sig_file_name);
#else
ERR(i2d_PKCS7_bio(b, pkcs7) != 1,
"%s", sig_file_name);
#endif
BIO_free(b);
}
if (sign_only) {
BIO_free(bm);
return 0;
}
}
/* Open the destination file now so that we can shovel the module data
* across as we read it.
*/
bd = BIO_new_file(dest_name, "wb");
ERR(!bd, "%s", dest_name);
/* Append the marker and the PKCS#7 message to the destination file */
ERR(BIO_reset(bm) < 0, "%s", module_name);
while ((n = BIO_read(bm, buf, sizeof(buf))),
n > 0) {
ERR(BIO_write(bd, buf, n) < 0, "%s", dest_name);
}
BIO_free(bm);
ERR(n < 0, "%s", module_name);
module_size = BIO_number_written(bd);
if (!raw_sig) {
#ifndef USE_PKCS7
ERR(i2d_CMS_bio_stream(bd, cms, NULL, 0) != 1, "%s", dest_name);
#else
ERR(i2d_PKCS7_bio(bd, pkcs7) != 1, "%s", dest_name);
#endif
} else {
BIO *b;
/* Read the raw signature file and write the data to the
* destination file
*/
b = BIO_new_file(raw_sig_name, "rb");
ERR(!b, "%s", raw_sig_name);
while ((n = BIO_read(b, buf, sizeof(buf))), n > 0)
ERR(BIO_write(bd, buf, n) < 0, "%s", dest_name);
BIO_free(b);
}
sig_size = BIO_number_written(bd) - module_size;
sig_info.sig_len = htonl(sig_size);
ERR(BIO_write(bd, &sig_info, sizeof(sig_info)) < 0, "%s", dest_name);
ERR(BIO_write(bd, magic_number, sizeof(magic_number) - 1) < 0, "%s", dest_name);
ERR(BIO_free(bd) != 1, "%s", dest_name);
/* Finally, if we're signing in place, replace the original. */
if (replace_orig)
ERR(rename(dest_name, module_name) < 0, "%s", dest_name);
return 0;
}