OpenCore y UEFI Secure Boot con WSL

El firmware UEFI de las placas base tiene la capacidad de arranque seguro de forma que sólo se permiten los archivos del boot loader firmados digitalmente con las claves que están integradas en el firmware. Con UEFI Secure Boot habilitado:
- Windows puede arrancar ya que los firmware incorporan certificados de Microsoft (a veces también certificados del fabricante de la placa base)
- macOS no puede arrancar; es necesario un sistema Linux en el que generar las claves y firmar con ellas los archivos de OpenCore, este es el motivo por el que actualmente arrancamos OpenCore con UEFI Secure Boot deshabilitado.

Este texto se basa en los artículos de:

Los artículos de sakaki y de Ubuntu plantean cómo arrancar Linux con UEFI Secure Boot activado pero khronokernel y profzei se refieren específicamente a OpenCore y macOS. Los 4 artículos coinciden en la necesidad de hacerlo desde un sistema Linux ya que las herramientas requeridas no existen para macOS. El sistema Linux necesario para firmar los archivos de OpenCore puede suponer un inconveniente significativo por el trabajo que conlleva su instalación y configuración (bien en disco independiente o en máquina virtual).
Una vez en Linux, todo se hace desde Terminal por lo que gran parte del sistema instalado realmente no hace falta.
Esta tarea se puede simplificar gracias a una infraestructura no demasiado utilizada que existe en Windows 10 (compilación 18917 o posterior) y Windows 11: Windows Subsystem for Linux (WSL), gracias a la cual podemos arrancar una imagen genuina de Ubuntu proporcionada por Canonical. Esto posibilita la ejecución de comandos de forma nativa en un terminal de Bash dentro de un entorno Windows que se comporta como Linux.

En este texto se propone la activación de UEFI Secure Boot en OpenCore desde un sistema Windows 11 con WSL instalado, sin tener que recurrir a la instalación y configuración de un sistema Linux completo por separado o en máquina virtual. Sigue siendo necesario un cierto conocimiento de los comandos básicos de Linux pero se requieren menos tiempo y esfuerzo que con la opción nativa.

Nota: en la tienda de aplicaciones de Microsoft hay otras distribuciones Linux disponibles para instalar en WSL, incluso es posible tener más de una y pueden ser gestionadas con la aplicación WSL Manager.

Instalar WSL desde línea de comandos (instala Ubuntu de forma predeterminada)

Abrir PowerShell como Administrador >> ejecutar el comando wsl --install

PS C:/Users/miliuco> wsl --install
Instalando: Plataforma de máquina virtual
Se ha instalado Plataforma de máquina virtual.
Instalando: Subsistema de Windows para Linux
Se ha instalado Subsistema de Windows para Linux.
Descargando: Kernel de WSL
Instalando: Kernel de WSL
Se ha instalado Kernel de WSL.
Descargando: Soporte técnico de la aplicación de GUI
Instalando: Soporte técnico de la aplicación de GUI
Se ha instalado Soporte técnico de la aplicación de GUI .
Descargando: Ubuntu
La operación solicitada se realizó correctamente. Los cambios se aplicarán una vez que se reinicie el sistema.

Al finalizar solicita la creación de un nombre de usuario y una contraseña (no tienen relación con los que utilizas en Windows). Esta será la cuenta predeterminada e iniciará la sesión automáticamente en la carpeta home. Es cuenta de administrador y puede ejecutar comandos con sudo.

WSL arranca desde el icono Ubuntu del menú de aplicaciones o escribiendo ubuntu en la ventana de línea de comandos. Se muestra una ventana de Terminal de Bash con el prompt en nuestra carpeta de usuario.
Los discos de Windows son accesibles en la ruta /mnt/c, /mnt/d y así sucesivamente. El sistema Limux es accesible desde Explorador de Windows >> Linux. No se recomienda modificar elementos de Ubuntu desde el explorador de Windows, es preferible hacerlo desde dentro de WSL.

Si en algún momento olvidas la contraseña de Linux >> abre PowerShell >> wsl -u root (abre Ubuntu en el directorio del usuario Windows) >> passwd >> solicita una contraseña nueva >> exit.

Instalar las herramientas

En la ventana de Terminal de Ubuntu:

  • sudo apt update && sudo apt upgrade (para actualizar repositorios de paquetes de instalación)
  • sudo apt-get install unzip (unzip no se instala por defecto con Ubuntu de WSL, la utilidad zip en cambio si está instalada)
  • sudo apt-get install sbsigntool (utilidad de firma digital para UEFI Secure Boot)
  • sudo apt-get install efitools (herramientas para gestionar variables de UEFI Secure Boot)

La herramienta openssl también es necesaria pero ya está instalada en Ubuntu.

Si queremos ver las utilidades ya instaladas en Ubuntu podemos usar el comando:
sudo apt list --installed

Crear las claves para incluir en el firmware y firmar OpenCore

Crear una carpeta de trabajo:

mkdir efykeys
cd efykeys

Crear PK (Platform Key):

openssl req -new -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes -subj "/CN=NAME PK/" -keyout PK.key -out PK.pem

Crear KEK (Key Exchange Key):

openssl req -new -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes -subj "/CN=NAME KEK/" -keyout KEK.key -out KEK.pem

Crear ISK (Initial Supplier Key):

openssl req -new -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes -subj "/CN=NAME ISK/" -keyout ISK.key -out ISK.pem

Nota: reemplaza NAME por algo característico que te ayude a reconocerlas cuando las consultes desde el menú de UEFI, por ejemplo CLAVES2021.

Permisos correctos para los archivos de claves:

chmod 0600 *.key

Descargar los certificados de Microsoft para arrancar Windows:
Microsoft Windows Production CA 2011
Microsoft UEFI driver signing CA key

Copiar los certificados de Windows a la carpeta de trabajo:

cp /mnt/c/Users/yo/Downloads/MicCorUEFCA2011_2011-06-27.crt /home/yo/efikeys/
cp /mnt/c/Users/yo/Downloads/MicWinProPCA2011_2011-10-19.crt /home/yo/efikeys/

Firmar digitalmente los certificados de Microsoft:

openssl x509 -in MicWinProPCA2011_2011-10-19.crt -inform DER -out MicWinProPCA2011_2011-10-19.pem -outform PEM
openssl x509 -in MicCorUEFCA2011_2011-06-27.crt -inform DER -out MicCorUEFCA2011_2011-06-27.pem -outform PEM

Convertir los archivos PEM al formato ESL apto para UEFI Secure Boot:

cert-to-efi-sig-list -g $(uuidgen) PK.pem PK.esl
cert-to-efi-sig-list -g $(uuidgen) KEK.pem KEK.esl
cert-to-efi-sig-list -g $(uuidgen) ISK.pem ISK.esl
cert-to-efi-sig-list -g $(uuidgen) MicWinProPCA2011_2011-10-19.pem MicWinProPCA2011_2011-10-19.esl
cert-to-efi-sig-list -g $(uuidgen) MicCorUEFCA2011_2011-06-27.pem MicCorUEFCA2011_2011-06-27.esl

Crear la base de datos de firmas permitidas incluyendo los certificados de Microsoft firmados:

cat ISK.esl MicWinProPCA2011_2011-10-19.esl MicCorUEFCA2011_2011-06-27.esl > db.esl

Firmar digitalmente los archivos ESL:

//(PK se firma con ella misma)
sign-efi-sig-list -k PK.key -c PK.pem PK PK.esl PK.auth
Timestamp is 2021-11-2 00:05:40
Authentication Payload size 887
Signature of size 1221
Signature at: 40
//(KEK se firma con PK)
sign-efi-sig-list -k PK.key -c PK.pem KEK KEK.esl KEK.auth
Timestamp is 2021-11-2 00:05:47
Authentication Payload size 891
Signature of size 1221
Signature at: 40
//(la base de datos se firma con KEK).
sign-efi-sig-list -k KEK.key -c KEK.pem db db.esl db.auth
Timestamp is 2021-11-2 00:05:52
Authentication Payload size 4042
Signature of size 1224
Signature at: 40

Los archivos .auth (PK.auth, kek.auth y db.auth) serán utilizados para integrar nuestras firmas en el firmware. Copia estos archivos a una carpeta fuera de Ubuntu para que sean accesibles desde Windows.
Los archivos ISK.key y ISK.pem serán utilizados para firmar los archivos de OpenCore.

Firmar los archivos de OpenCore

Es necesario firmar los archivos con extensión .efi: OpenCore.efi, BOOTx64.efi y contenido de las carpetas Drivers y Tools.

Crear directorio de trabajo:

mkdir oc
cd oc

Copiar ISK.key y ISK.pem a la carpeta oc:

cp ISK.key ISK.pem oc
cd oc

El usuario profzei ha creado un script sign_opencore.sh que automatiza este proceso: descarga y descomprime OpenCore versión actual (0.7.5 en el momento de escribir este texto), descarga HFSPlus.efi, comprueba las claves ISK, firma digitalmente los archivos y los copia a la carpeta Signed. El script ha de estar en la carpeta oc junto a ISK.key y ISK.pem. Está ligeramente modificado por mí para adaptarlo a mis necesidades. Tú también puedes modificarlo a tu gusto.
Copia este texto en un editor de texto y guárdalo con el nombre sign_opencore.sh (puedes hacerlo en Windows):

#!/bin/bash
# Copyright (c) 2021 by profzei
# Licensed under the terms of the GPL v3

# OpenCore download link
LINK=$1
# https://github.com/acidanthera/OpenCorePkg/releases/download/0.7.5/OpenCore-0.7.5-RELEASE.zip
VERSION=$2
# 0.7.5 current

# Terminal command in Linux
# sh ./sign_opencore.sh https://github.com/acidanthera/OpenCorePkg/releases/download/0.7.5/OpenCore-0.7.5-RELEASE.zip 0.7.5

echo "==============================="
echo "Creating required directories"
mkdir Signed
mkdir Signed/Drivers
mkdir Signed/Tools
mkdir Signed/Download
mkdir Signed/BOOT
echo "==============================="
echo Downloading HfsPlus
wget -nv https://github.com/acidanthera/OcBinaryData/raw/master/Drivers/HfsPlus.efi -O ./Signed/Download/HfsPlus.efi
#echo "==============================="
# uncomment the next 2 lines if you use OpenLinuxBoot
#echo Downloading ext4_x64.efi
#wget -nv https://github.com/acidanthera/OcBinaryData/raw/master/Drivers/ext4_x64.efi -O ./Signed/Download/ext4_x64.efi
echo "==============================="
echo Downloading and unziping OpenCore
wget -nv $LINK
unzip "OpenCore-${VERSION}-RELEASE.zip" "X64/*" -d "./Signed/Download"
echo "==============================="
# If you don't want to delete downloaded OpenCore zip file, comment next line
rm "OpenCore-${VERSION}-RELEASE.zip"
echo "==============================="
echo "Checking ISK files"
if [ -f "./ISK.key" ]; then
    echo "ISK.key was decrypted successfully"
fi

if [ -f "./ISK.pem" ]; then
    echo "ISK.pem was decrypted successfully"
fi
echo "==============================="
echo "Signing drivers, tools, BOOTx64.efi and OpenCore.efi"
sleep 2
# You can modify drivers and tools to be signed to your like
echo ""
sbsign --key ISK.key --cert ISK.pem --output ./Signed/BOOT/BOOTx64.efi ./Signed/Download/X64/EFI/BOOT/BOOTx64.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/OpenCore.efi ./Signed/Download/X64/EFI/OC/OpenCore.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/Drivers/OpenRuntime.efi ./Signed/Download/X64/EFI/OC/Drivers/OpenRuntime.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/Drivers/OpenCanopy.efi ./Signed/Download/X64/EFI/OC/Drivers/OpenCanopy.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/Drivers/CrScreenshotDxe.efi ./Signed/Download/X64/EFI/OC/Drivers/CrScreenshotDxe.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/Tools/OpenShell.efi ./Signed/Download/X64/EFI/OC/Tools/OpenShell.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/Drivers/HfsPlus.efi ./Signed/Download/HfsPlus.efi

# You can sign also keytool to boot from USB with UEFI Secure Boot enabled
sbsign --key ISK.key --cert ISK.pem --output ./Signed/KeyTool.efi ./KeyTool.efi

# uncomment the next 2 lines if you use OpenLinuxBoot
#sbsign --key ISK.key --cert ISK.pem --output ./Signed/Drivers/OpenLinuxBoot.efi ./Signed/Download/X64/EFI/OC/Drivers/OpenLinuxBoot.efi
#sbsign --key ISK.key --cert ISK.pem --output ./Signed/Drivers/ext4_x64.efi ./Signed/Download/ext4_x64.efi
echo "==============================="
# Clean: remove downloaded files
rm -rf ./Signed/Download
echo "Cleaned."

Copia el script a la carpeta oc:

cp /mnt/c/Users/yo/Downloads/sign_opencore.sh /home/yo/efikeys/oc

Este script se ejecuta con 2 parámetros: el sitio de descarga de OpenCore y el número de versión. Por ejemplo, con la versión 0.7.5 (en una sola línea):

sh ./sign_opencore.sh https://github.com/acidanthera/OpenCorePkg/releases/download/0.7.5/OpenCore-0.7.5-RELEASE.zip 0.7.5

Al finalizar tendremos en la carpeta Signed los archivos .efi de OpenCore firmados digitalmente con nuestras propias claves. Copia la carpeta Signed a una localización (fuera de Ubuntu) que sea accesible desde Windows y/o macOS y pon los archivos .efi firmados en la carpeta EFI de OpenCore reemplazando a los del mismo nombre.

Incluir los archivos en el firmware

El paso final es introducir en el firmware los archivos de firma reemplazando las variables existentes:

  • db.auth >> Authorized Signatures
  • kek.auth >> KEK (Key Exchange Keys)
  • pk.auth >> PK (Platform key).

Esto puede ser realizado de 2 maneras: desde el menú de configuración de la placa base o con la herramienta especializada KeyTool.

  1. BIOS

En la sección Secure Boot suele haber opciones para restaurar las claves que vienen de fábrica (borrar lo que hayamos configurado y recuperar la lista original de firmas autorizadas, Microsoft y Gigabyte) o para editar las variables por separado (se pueden exportar, actualizar, eliminar o mostrar detalles).
En mi placa base (Z390 Aorus Elite) este menú está en la pestaña Boot >> Secure Boot (que por ahora está deshabilitado) >> Key Management.
Si has modificado los almacenes de claves anteriormente (no es la primera vez que lo haces) es muy recomendable, para evitar errores, restaurar las claves predeterminadas antes de añadir las nuevas >> Restore Factory Keys >> Install factory defaults >> Yes.

Ahora puedes editar las claves. Seleccionas la variable que vas a modificar por este orden: Authorized Signatures >> Key Exchange Keys >> Platform Key (PK).
En cada variable puedes ver las opciones existentes. Por ejemplo, con Authorized Signatures el menú de opciones es Details / Export / Update / Append / Delete.

Para reemplazar una variable por otra eliges Update >> buscas en el dispositivo USB >> localizas y seleccionas db.auth >> esta base de datos de firmas permitidas reemplaza a la actual. Igualmente con Append si quieres añadirla a la existente en lugar de reemplazarla. Puedes utilizar Append con db.auth y kek.auth pero pk.auth sólo permite Update.
Para ver los detalles seleccionas Details >> se muestran los detalles de la variable. En el caso de Authorized Signatures, después de añadir db.auth veo las 4 firmas autorizadas: la que yo he creado (ISK Image Signing Key), las 2 de Microsoft para poder arrancar Windows con UEFI Secure Boot habilitado y la de Canonical (extraída desde el archivo shimx64.efi de Ubuntu con la herramienta shim-to-cert.tool incluida en OpenCore) para poder arrancar también Ubuntu con UEFI Secure Boot.

2. KeyTool

KeyTool se incluye en el paquete efitools de Linux, puedes encontrar la utilidad en la carpeta /usr/share/efitools/efi/KeyTool.efi. Copia este archivo a la carpeta EFI de un dispositivo USB (formateado como FAT32 y MBR) con el nombre bootx64.efi. Junto a bootx64.efi, en la carpeta EFI del dispositivo USB hay que incluir también los archivos db.auth, kek.auth y pk.auth.
Al arrancar desde este USB de arranque, se ejecuta la interfaz gráfica de la herramienta. Cuando arranca keytool vemos un menú con las opciones Save Keys / Edit Keys / Execute Binary / Exit. Hacemos clic en Edit Keys.

Seleccionamos la variable que vamos a modificar por este orden: The Allowed Signature Database (db) >> The Key Exchange Keys Database (kek) >> The Platform Key (pk).
Selecciona en primer lugar The Allowed Signature Database (db) >> Replace Keys >> dispositivo USB >> db.auth >> pulsa Enter >> vuelves a la lista de variables (sólo muestra mensaje en caso de error). Repite lo mismo para The Key Exchange Keys Database (kek) y The Platform Key (pk).

Después de introducir db.auth, kek.auth y pk.auth en el firmware podemos arrancar OpenCore y macOS con UEFI Secure Boot habilitado.

2 respuestas a «OpenCore y UEFI Secure Boot con WSL»

  1. Gracias por el artículo. Muy interesante pero difícil de llevar a cabo. Sabes si en OpenCore están trabajando en un método más sencillo?

    1. Sí, pienso que están trabajando en ello aunque la prioridad es baja.
      Por un lado OpenCore incorpora desde hace pocas versiones la herramienta shim-to-cert.tool para extraer la clave pública del certificado de firma OEM (y las bases de datos db y dbx, si existen) del archivo shim de grub.
      Por otro lado en el bug tracker hay un tema titulado Support UEFI SecureBoot within OpenCore del que se deduce que hay interés en crear un método más sencillo para esta tarea.

Deja una respuesta

(La dirección de email no es necesaria)