Enabling RISC-V Secure Boot on openRuyi: A Practical Guide from Firmware to Kernel
Secure Boot is an important mechanism for establishing a trusted verification chain during system startup. For system adaptation, firmware debugging, and boot process validation on RISC-V platforms, a reproducible configuration workflow helps developers understand the trust relationships among boot components.
Based on the openRuyi Documentation Center guide, "Enable Secure Boot on openRuyi"[1], this article uses the openRuyi UEFI firmware and the openRuyi Server edition QCOW2 image as examples to outline the main steps for configuring Secure Boot in a QEMU environment. The process begins with preparing the firmware and system image.
1. Prepare the UEFI Firmware and System Image
Before enabling Secure Boot, prepare the openRuyi UEFI firmware and the openRuyi Server edition QCOW2 system image. The UEFI firmware can be obtained from the ovmf package in the openRuyi package repository[2]. Extracting the package produces the .fd files.
wget https://boat.openruyi.cn/stable/rva23/riscv64/ovmf-202602-11.3.or.riscv64.rpm
rpm2cpio ovmf-202602-11.3.or.riscv64.rpm | cpio -idmv
cp ./usr/share/ovmf/*.fd ./
The openRuyi Server edition QCOW2 system image used in this article can be obtained from the openRuyi releases page[3].
Note: If the
ovmfpackage or system image has been updated by the time you follow this guide, use the latest files available in the openRuyi package repository and releases page, and update the filenames in the scripts below accordingly.
2. Create a QEMU Quick-Start Script
After preparing the firmware and system image, create a QEMU startup script named start_or.sh and make it executable:
touch start_or.sh
chmod +x start_or.sh
Write the following content to start_or.sh:
#!/usr/bin/env bash
# The script is created for starting a riscv64 qemu virtual machine with specific parameters.
RESTORE=$(echo -en '\001\033[0m\002')
YELLOW=$(echo -en '\001\033[00;33m\002')
## Configuration
vcpu=2
memory=8
drive="openRuyi-2026.04-Server-cloud.qcow2"
fw1="virt_code.fd"
fw2="virt_vars.fd"
ssh_port=12055
cmd="qemu-system-riscv64 \
-nographic -machine virt,pflash0=pflash0,pflash1=pflash1,acpi=off \
-cpu rva23s64,sv39=on \
-smp "$vcpu" -m "$memory"G \
-blockdev node-name=pflash0,driver=file,read-only=on,filename="$fw1" \
-blockdev node-name=pflash1,driver=file,filename="$fw2" \
-drive file="$drive",format=qcow2,id=hd0,if=none \
-object rng-random,filename=/dev/urandom,id=rng0 \
-device virtio-vga \
-device virtio-rng-device,rng=rng0 \
-device virtio-blk-device,drive=hd0 \
-device virtio-net-device,netdev=usernet \
-netdev user,id=usernet,hostfwd=tcp::"$ssh_port"-:22 \
-device qemu-xhci -usb -device usb-kbd -device usb-tablet"
echo ${YELLOW}:: Starting VM...${RESTORE}
echo ${YELLOW}:: Using following configuration${RESTORE}
echo ""
echo ${YELLOW}vCPU Cores: "$vcpu"${RESTORE}
echo ${YELLOW}Memory: "$memory"G${RESTORE}
echo ${YELLOW}Disk: "$drive"${RESTORE}
echo ${YELLOW}SSH Port: "$ssh_port"${RESTORE}
echo ""
echo ${YELLOW}:: NOTE: Make sure ONLY ONE .qcow2 file is${RESTORE}
echo ${YELLOW}in the current directory${RESTORE}
echo ""
echo ${YELLOW}:: Tip: Try setting DNS manually if QEMU user network doesn\'t work well. ${RESTORE}
echo ${YELLOW}:: HOWTO -\> https://serverfault.com/a/810639 ${RESTORE}
echo ""
echo ${YELLOW}:: Tip: If \'ping\' reports permission error, try reinstalling \'iputils\'. ${RESTORE}
echo ${YELLOW}:: HOWTO -\> \'sudo dnf reinstall iputils\' ${RESTORE}
echo ""
sleep 2
eval $cmd
This script starts an openRuyi virtual machine using qemu-system-riscv64 and specifies parameters including the RISC-V virt machine, UEFI pflash devices, QCOW2 disk, virtio devices, and SSH port forwarding. Here, drive points to the openRuyi Server QCOW2 image, fw1 and fw2 correspond to virt_code.fd and virt_vars.fd, and ssh_port configures SSH port forwarding.
Run the startup script to enter the openRuyi environment:
./start_or.sh
After the system starts, log in using either of the following accounts:
root / openruyi
openruyi / openruyi
3. Install the Tools Required for Secure Boot
After entering the system, install the tools required to configure Secure Boot:
dnf install -y efibootmgr efitools grub-unsigned mokutil sbsigntools shim wget
After installation, copy grub.cfg and grubriscv64.efi to the /boot/efi/EFI/openruyi directory:
cp /boot/efi/EFI/BOOT/grub.cfg /boot/efi/EFI/openruyi/
cp /lib/grub/riscv64-efi/monolithic/grubriscv64.efi /boot/efi/EFI/openruyi/
4. Download the Secure Boot Helper Scripts
From this point onward, all commands in this section must be run as the root user. If you are logged in as the openruyi user, add sudo before each command.
wget https://github.com/wxjstz/secureboot-setup/archive/refs/heads/main.tar.gz
tar xvf main.tar.gz
cd secureboot-setup-main
The repository mainly contains three scripts:
1.gen_keys # Generate PK, KEK, db, and MOK keys
2.import_mok # Initiate MOK enrollment through mokutil
3.import_uefi_cert # Import PK, KEK, and db into the UEFI variable store
Note: After completing Secure Boot key enrollment, continue using the same
virt_vars.fdfile. QEMU stores UEFI variables in this file. Replacing it with a newvirt_vars.fdwill cause the system to lose the enrolled keys.
5. Confirm That the Firmware Is in Setup Mode
Before creating or importing keys, confirm that the firmware is in Setup Mode:
mokutil --sb-state
The expected output is:
SecureBoot disabled
Platform is in Setup Mode
If the firmware is not in Setup Mode, restart QEMU with a clean virt_vars.fd, or enter the BIOS/UEFI interface and clear the Secure Boot keys.
6. Generate Secure Boot Signing Keys
After confirming that the firmware is in Setup Mode, generate the keys and certificates required for Secure Boot:
./1.gen_keys
When the script runs, it prompts you to enter the certificate owner name. This name is written to the Common Name field of the generated certificate. Press Enter to use the default value.
After the script finishes, it generates the following directory structure:
secureboot/
├── cert/ # Private keys, certificates, and MOK.der
├── esl/ # EFI Signature Lists
└── keystore/ # Signed .auth files for UEFI enrollment
Backup Reminder
Back up the entire secureboot/ directory, especially the private key files under secureboot/cert.
7. Sign the Key Files in the Boot Chain
Secure Boot is not simply a matter of enabling a boot option. More importantly, the key files in the boot chain must carry valid signatures.
UEFI firmware → trust through db → shim → trust through MOK → MokManager / GRUB / Linux kernel
This workflow uses the following signing strategy:
- Use the db key to sign shim.
- Use the MOK key to sign MokManager, GRUB, and the Linux kernel.
Before signing, back up the original files:
mkdir -p orig
cp /boot/linux orig/
cp /boot/efi/EFI/openruyi/shimriscv64.efi orig/
cp /boot/efi/EFI/openruyi/mmriscv64.efi orig/
cp /boot/efi/EFI/openruyi/grubriscv64.efi orig/
Use the db key to sign shim:
sbsign \
--key secureboot/cert/db.key \
--cert secureboot/cert/db.crt \
--output /boot/efi/EFI/openruyi/shimriscv64.efi \
orig/shimriscv64.efi
Use the MOK key to sign MokManager, GRUB, and the Linux kernel:
sbsign \
--key secureboot/cert/MOK.key \
--cert secureboot/cert/MOK.crt \
--output /boot/efi/EFI/openruyi/mmriscv64.efi \
orig/mmriscv64.efi
sbsign \
--key secureboot/cert/MOK.key \
--cert secureboot/cert/MOK.crt \
--output /boot/efi/EFI/openruyi/grubriscv64.efi \
orig/grubriscv64.efi
sbsign \
--key secureboot/cert/MOK.key \
--cert secureboot/cert/MOK.crt \
--output /boot/linux \
orig/linux
8. Enroll the MOK Certificate
Before importing the UEFI certificates, enroll the MOK certificate. shim will use MOK to trust the signed MokManager, GRUB, and kernel.
Run the following command to initiate the MOK enrollment request:
./2.import_mok
During this process, you need to set an enrollment password. After rebooting into MokManager, use this password to confirm the enrollment.
reboot
After the system restarts, MokManager opens the blue Mok Management interface. Complete the enrollment as follows:
- Select
Enroll MOK→Continue. - Enter the password you just set.
- Select
Yesto confirm the enrollment. - Select
Reboot.
After the second reboot, use the following command to confirm that the MOK certificate has been enrolled:
mokutil --list-enrolled
9. Import the UEFI Certificates
After enrolling the MOK certificate, import PK, KEK, and db into the UEFI variable store:
./3.import_uefi_cert
After the import completes, check each UEFI key database:
mokutil --pk
mokutil --kek
mokutil --db
After confirming that the command output includes the certificates generated earlier, reboot the system again:
reboot
10. Verify That Secure Boot Is Enabled
After the system restarts, run:
mokutil --sb-state
If the output is:
SecureBoot enabled
Secure Boot has been successfully enabled on openRuyi.
Summary
This guide enables developers to walk through the complete Secure Boot configuration process in an openRuyi QEMU environment. From firmware preparation and QEMU startup to key generation, boot-file signing, and MOK and UEFI certificate enrollment, the workflow demonstrates how Secure Boot works on openRuyi.
For developers interested in RISC-V system security, UEFI firmware adaptation, and boot-chain verification, this is not only a hands-on Secure Boot configuration exercise, but also an introduction to the trusted boot mechanism of RISC-V systems.
Related Links
[1] openRuyi Secure Boot Guide: https://openruyi.cn/zh-Hans/docs/guide/enable-secure-boot/
[2] openRuyi Package Repository: https://boat.openruyi.cn/stable/rva23/
[3] openRuyi Releases: https://releases.openruyi.cn/
Contact Us
If you are interested in openRuyi, follow the project on GitHub, visit the openRuyi Documentation Center for more information, or join the Discord community to participate in discussions. The team is continuously recruiting full-time employees, part-time contributors, and interns. Please send your resume to Jingwei Wang at wangjingwei@iscas.ac.cn.