Skip to content

sign: Sign spawn kernels for kexec_file_load() verification - #21

Merged
congwang-mk merged 1 commit into
mainfrom
kerf-sign
Sep 30, 2026
Merged

congwang-mk merged 1 commit into
mainfrom
kerf-sign

Conversation

@congwang-mk

Copy link
Copy Markdown
Contributor

Summary

kerf extracts the ELF vmlinux from a bzImage before kexec_file_load(), so the bzImage's PE signature never reaches the kernel, and a host that enforces kexec signatures (CONFIG_KEXEC_SIG_FORCE or lockdown) refuses every spawn kernel. The multikernel kernel now verifies a PKCS#7 signature appended to the ELF vmlinux in the module signature format (multikernel/linux 3f867f5f5c67).

  • kerf sign KERNEL -o OUTPUT --key KEY [--cert CERT] [--hash sha256|sha384|sha512] extracts the vmlinux from a bzImage when needed and appends that signature, with an RSA or ECDSA key. It is a separate command so the signing key stays on the build machine instead of every host that loads kernels.
  • The PKCS#7 message is assembled by kerf, with cryptography doing the signing. cryptography's PKCS#7 builder labels RSA signatures sha256WithRSAEncryption, which the kernel's PKCS#7 parser rejects (-ENOPKG); it only accepts rsaEncryption. For RSA the output is byte-for-byte what scripts/sign-file writes.
  • kerf load warns when it loads a bzImage on a host that enforces signatures, and explains signature errors from kexec_file_load() (ENODATA, ENOKEY/EKEYREJECTED, and EPERM from lockdown, which it used to report as a missing root privilege).
  • Adds cryptography as a dependency.

Test plan

  • pytest: 433 passed, including 31 new tests in tests/test_signature.py
  • RSA output byte-identical to scripts/sign-file; ECDSA structure identical field by field
  • On a VM whose host kernel enforces signatures and trusts a test key: bzImage and unsigned vmlinux refused with ENODATA, vmlinux signed with an untrusted key refused with ENOKEY, vmlinux signed with the trusted key loaded and booted twice (start, kill, start)
  • Not tested with a MOK-enrolled key on a Secure Boot host (the VM boots without UEFI)
  • The bzImage warning relies on lockdown state or /proc/config.gz; a kernel exposing neither gets only the error note

🤖 Generated with Claude Code

A bzImage's PE signature does not survive kerf extracting the ELF
vmlinux, so a host that enforces kexec signatures refuses every spawn
kernel kerf loads. The multikernel kernel now verifies a PKCS#7
signature appended to the ELF vmlinux in the module signature format.

Add "kerf sign", which extracts the vmlinux from a bzImage when needed
and appends that signature with an RSA or ECDSA key. It is a separate
command so the signing key stays on the build machine rather than on
every host that loads kernels.

The PKCS#7 message is assembled here instead of by cryptography's
PKCS#7 builder, which labels RSA signatures sha256WithRSAEncryption; the
kernel only accepts rsaEncryption and would refuse them. For RSA the
output is byte-for-byte what scripts/sign-file writes.

kerf load now warns when it loads a bzImage on a host that enforces
signatures, and explains signature errors from kexec_file_load(),
including EPERM from lockdown, which it used to report as a missing
root privilege.

Signed-off-by: Cong Wang <cwang@multikernel.io>
@congwang-mk
congwang-mk merged commit bf07bb0 into main Sep 30, 2026
4 checks passed
@congwang-mk
congwang-mk deleted the kerf-sign branch September 30, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant