UEFI Secure Boot y OpenCore (1)

UEFI Secure Boot y OpenCore con máquina virtual de Ubuntu en macOS: Esta es una forma de habilitar UEFI Secure Boot con OpenCore sin tener que instalar Windows o crear un dispositivo USB con Linux. Todo se realiza desde macOS. La función de portapapeles y carpeta compartidos, que permiten intercambiar texto y archivos entre macOS y Linux, facilita la tarea.

UTM

UTM es una aplicación que permite utilizar máquinas virtuales en macOS e iOS. Es un software gratuito y abierto. Información y descargas están disponibles en GitHub y en el sitio web.

UTM ofrece máquinas virtuales preconfiguradas que sólo debes adjuntar a la app e iniciar, no es necesario instalar previamente el sistema operativo. Puedes visitar la Galería de Máquinas Virtuales.

Entre las máquinas virtuales preinstaladas no existe Ubuntu 22.04 pero UTM tiene una guía para descargar e instalar esta versión de Ubuntu. He seguido esta guía para tener un sistema virtual Ubuntu 22.04 en macOS.

Es importante configurar portapapeles y carpeta compartidos entre macOS y Linux. La guía explica cómo hacerlo. El portapapeles compartido funciona después de instalar SPICE Agent, que también mejora las resoluciones de pantalla y el cambio dinámico entre ellas. Se recomienda encarecidamente su instalación, al igual que QEMU Agent (funciones adicionales como sincronización de hora, etc.).

El intercambio de directorios puede funcionar de 2 maneras diferentes: SPICE WebDav o VirtFS. He usado VirtFS que permite mostrar la carpeta compartida de macOS en el sistema de archivos de Ubuntu. Para ello hay que hacer en Terminal:

1.- Crear el directorio compartido

sudo mkdir Shared

2.- Montar el directorio compartido

sudo mount -t 9p -o trans=virtio share Compartido -oversion=9p2000.L

3.- Agregar una entrada en fstab para montar la carpeta compartida en el arranque.Abrir fstab

sudo pico /etc/fstab

4.- Añadir esta entrada

share /home/yo/Shared 9p trans=virtio,version=9p2000.L,rw,_netdev,nofail 0 0

5.- Guardar con Ctrl + O y salir con Ctrl + X.

Crear las claves seguras y firmar OpenCore

En mi carpeta de Inicio he creado una carpeta de trabajo. La he llamado Uefi-SB. Dentro de esta carpeta sólo necesito tener un script que automatice el proceso y realice todas las tareas sin intervención del usuario:

  • Crear una carpeta llamada efikeys y cambiar a esta carpeta
  • Crear claves PK, KEK y db
  • Descargar los certificados de Microsoft 2011
  • Firmar certificados de Microsoft
  • Convertir archivos PEM a ESL
  • Crear la base de datos de firmas y hashes permitidos
  • Firmar archivos ESL >> AUTH adecuados para su integración en el firmware
  • Salir de efikeys, crear la carpeta oc y cambiar a ella
  • Copiar los archivos ISK.key, ISK.pem, PK.auth, KEK.auth y db.auth a oc (ISK para firmar OpenCore y auth para insertar en el firmware)
  • Descargar y descomprimir OpenCore 1.0.0 (se puede configurar la versión en el script y en el comando de Terminal que lo ejecuta)
  • Descargar HFSPlus
  • Firmar archivos OpenCore .efi (Drivers, Tools y OpenCore.efi).

El script original es del usuario Profzei basado en Roderick W Smith. Yo uso 2 versiones ligeramente modificadas:

1.- sign1.sh: contribuciones de Andres Hurtado (descargar y firmar HFSPlus.efi) y de Lukakeiton (preguntar si se utiliza OpenLinuxBoot.efi y, de ser así, descargar y firmar los drivers necesarios), al final no se firman todos los drivers sino sólo los seleccionados por el usuario y se guardan en la carpeta Uefi-SB/oc/Signed.

#!/bin/bash
# Copyright (c) 2015 by Roderick W. Smith
# Copyrigth (c) 2021 by profzei
# Licensed under the terms of the GPL v3
# Modified by LUKAKEITON and perez987

# Linux command in Terminal
# sh ./sign.sh 1.0.0


# Block for the first boot or updating Ubuntu
# Uncommnet if desired
#sudo apt update && sudo apt upgrade

#if ! command -v unzip &> /dev/null
#then
# echo "Installing unzip..."
# sudo apt install unzip
#fi

#if ! command -v sbsign &> /dev/null
#then
# echo "Installing sbsigntool..."
# sudo apt-get install sbsigntool
#fi

#if ! command -v cert-to-efi-sig-list &> /dev/null
#then
# echo "Installing efitools..."
# sudo apt-get install efitools
#fi

VERSION=$1

echo "==================================="
echo "Creating efikeys folder"
echo "==================================="
mkdir efikeys
echo "==================================="
echo "Copying 2023 cert to efikeys"
echo "==================================="
cp WinUEFCA2023.crt efikeys/
cd efikeys
echo "==================================="
echo "Creating PK, KEK and db keys"
echo "==================================="
openssl req -new -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes -subj "/CN=ROBLA 2024/" -keyout PK.key -out PK.pem
openssl req -new -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes -subj "/CN=ROBLA 2024/" -keyout KEK.key -out KEK.pem
openssl req -new -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes -subj "/CN=ROBLA 2024/" -keyout ISK.key -out ISK.pem
chmod 0600 *.key

echo "==================================="
echo "Downloading 2011 certificates"
echo "==================================="
wget --user-agent="Mozilla" https://www.microsoft.com/pkiops/certs/MicWinProPCA2011_2011-10-19.crt
wget --user-agent="Mozilla" https://www.microsoft.com/pkiops/certs/MicCorUEFCA2011_2011-06-27.crt

echo "==================================="
echo "Signing Microsoft certificates"
echo "==================================="
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
openssl x509 -in WinUEFCA2023.crt -inform DER -out WinUEFCA2023pem -outform PEM

echo "==================================="
echo "Converting PEM files to ESL"
echo "==================================="
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
cert-to-efi-sig-list -g $(uuidgen) WinUEFCA2023.pem WinUEFCA2023.esl

echo "==================================="
echo "Creating allowed database"
echo "==================================="
cat ISK.esl MicWinProPCA2011_2011-10-19.esl MicCorUEFCA2011_2011-06-27.esl WinUEFCA2023.esl > db.esl


echo "==================================="
echo "Signing ESL files to auth"
echo "==================================="
sign-efi-sig-list -k PK.key -c PK.pem PK PK.esl PK.auth
sign-efi-sig-list -k PK.key -c PK.pem KEK KEK.esl KEK.auth
sign-efi-sig-list -k KEK.key -c KEK.pem db db.esl db.auth

echo "==================================="
echo "Copying files to oc folder"
echo "==================================="
cd ..
mkdir oc
cp efikeys/ISK.key oc
cp efikeys/ISK.pem oc
cp efikeys/PK.auth oc
cp efikeys/KEK.auth oc
cp efikeys/db.auth oc
cd oc

echo "==================================="
echo "Creating required directories"
echo "==================================="
mkdir Signed
mkdir Signed/EFI
mkdir Signed/EFI/BOOT
mkdir Signed/EFI/OC
mkdir Signed/EFI/OC/Drivers
mkdir Signed/EFI/OC/Tools
mkdir Signed/Download

echo "==================================="
#LINK="https://github.com/acidanthera/OpenCorePkg/releases/download/${VERSION}/OpenCore-${VERSION}-RELEASE.zip"
LINK="https://github.com/acidanthera/OpenCorePkg/releases/download/1.0.0/OpenCore-1.0.0-RELEASE.zip"
echo "Downlading Opencore ${VERSION}"
echo "==================================="
wget -nv $LINK

echo "==================================="
echo "Downloading HfsPlus.efi"
echo "==================================="
wget -nv https://github.com/acidanthera/OcBinaryData/raw/master/Drivers/HfsPlus.efi -O ./Signed/Download/HfsPlus.efi
echo "==================================="
echo "Do you use OpenLinuxBoot? (Y/N)"
read LUKA
LUKA1="Y"
LUKA2="y"
if [ "$LUKA" = "$LUKA1" ] || [ "$LUKA" = "$LUKA2" ]; then
wget -nv https://github.com/acidanthera/OcBinaryData/raw/master/Drivers/ext4_x64.efi -O ./Signed/Download/ext4_x64.efi
fi

echo "==================================="
echo "Unzipping OpenCore ${VERSION}"
echo "==================================="
unzip "OpenCore-${VERSION}-RELEASE.zip" "X64/*" -d "./Signed/Download"
rm "OpenCore-${VERSION}-RELEASE.zip"
echo "==================================="
echo "Signing OpenCore .efi files"
echo "==================================="
sbsign --key ISK.key --cert ISK.pem --output ./Signed/EFI/BOOT/BOOTx64.efi ./Signed/Download/X64/EFI/BOOT/BOOTx64.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/EFI/OC/OpenCore.efi ./Signed/Download/X64/EFI/OC/OpenCore.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/EFI/OC/Drivers/OpenRuntime.efi ./Signed/Download/X64/EFI/OC/Drivers/OpenRuntime.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/EFI/OC/Drivers/OpenCanopy.efi ./Signed/Download/X64/EFI/OC/Drivers/OpenCanopy.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/EFI/OC/Drivers/CrScreenshotDxe.efi ./Signed/Download/X64/EFI/OC/Drivers/CrScreenshotDxe.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/EFI/OC/Drivers/FirmwareSettingsEntry.efi ./Signed/Download/X64/EFI/OC/Drivers/FirmwareSettingsEntry.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/EFI/OC/Drivers/ResetNvramEntry.efi ./Signed/Download/X64/EFI/OC/Drivers/ResetNvramEntry.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/EFI/OC/Drivers/ToggleSipEntry.efi ./Signed/Download/X64/EFI/OC/Drivers/ToggleSipEntry.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/EFI/OC/Tools/OpenShell.efi ./Signed/Download/X64/EFI/OC/Tools/OpenShell.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/EFI/OC/Drivers/HfsPlus.efi ./Signed/Download/HfsPlus.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/EFI/OC/Drivers/AudioDxe.efi ./Signed/Download/X64/EFI/OC/Drivers/AudioDxe.efi


if [ "$LUKA" = "$LUKA1" ] || [ "$LUKA" = "$LUKA2" ]; then
sbsign --key ISK.key --cert ISK.pem --output ./Signed/EFI/OC/Drivers/OpenLinuxBoot.efi ./Signed/Download/X64/EFI/OC/Drivers/OpenLinuxBoot.efi
sbsign --key ISK.key --cert ISK.pem --output ./Signed/EFI/OC/Drivers/ext4_x64.efi ./Signed/Download/ext4_x64.efi
echo "Linux drivers signed"
else
rm ./Signed/Download/X64/EFI/OC/Drivers/OpenLinuxBoot.efi
fi

echo "================================================"
echo "Signed OpenCore is in oc/Signed folder"
echo "================================================"

2.- sign2.sh: contribuciones de Andres Hurtado (descargar y firmar HFSPlus.efi) y de Andrew Blits que, en una sola línea, firma recursivamente todos los archivos de OpenCore con extensión .efi y los guarda en la carpeta Uefi-SB/oc/Signed/Downloaded.

#!/bin/bash
# Copyright (c) 2015 by Roderick W. Smith
# Copyrigth (c) 2021 by profzei
# Licensed under the terms of the GPL v3
# Modified by Andrew Blitss, Andres Hurtado and perez987

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


# Block for the first boot or updating Ubuntu
# Uncommnet if desired
#sudo apt update && sudo apt upgrade

#if ! command -v unzip &> /dev/null
#then
# echo "Installing unzip..."
# sudo apt install unzip
#fi

#if ! command -v sbsign &> /dev/null
#then
# echo "Installing sbsigntool..."
# sudo apt-get install sbsigntool
#fi

#if ! command -v cert-to-efi-sig-list &> /dev/null
#then
# echo "Installing efitools..."
# sudo apt-get install efitools
#fi

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

echo "==================================="
echo "Create efikeys folder"
echo "==================================="
mkdir efikeys
cd efikeys

echo "==================================="
echo "Create PK, KEK and db keys"
echo "==================================="
openssl req -new -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes -subj "/CN=ROBLA-2024/" -keyout PK.key -out PK.pem
openssl req -new -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes -subj "/CN=ROBLA-2024/" -keyout KEK.key -out KEK.pem
openssl req -new -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes -subj "/CN=ROBLA-2024/" -keyout ISK.key -out ISK.pem
chmod 0600 *.key

echo "==================================="
echo "Download 2011 certificates"
echo "==================================="
wget --user-agent="Mozilla" https://www.microsoft.com/pkiops/certs/MicWinProPCA2011_2011-10-19.crt
wget --user-agent="Mozilla" https://www.microsoft.com/pkiops/certs/MicCorUEFCA2011_2011-06-27.crt

echo "==================================="
echo "Sign Microsoft certificates"
echo "==================================="
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

echo "==================================="
echo "Convert PEM files to ESL"
echo "==================================="
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

echo "==================================="
echo "Create allowed database"
echo "==================================="
cat ISK.esl MicWinProPCA2011_2011-10-19.esl MicCorUEFCA2011_2011-06-27.esl > db.esl


echo "==================================="
echo "Sign ESL files to auth"
echo "==================================="
sign-efi-sig-list -k PK.key -c PK.pem PK PK.esl PK.auth
sign-efi-sig-list -k PK.key -c PK.pem KEK KEK.esl KEK.auth
sign-efi-sig-list -k KEK.key -c KEK.pem db db.esl db.auth

echo "==================================="
echo "Copy files to oc folder"
echo "==================================="
cd ..
mkdir oc
cp efikeys/ISK.key oc
cp efikeys/ISK.pem oc
cp efikeys/PK.auth oc
cp efikeys/KEK.auth oc
cp efikeys/db.auth oc
cd oc

echo "==================================="
echo "Download and unzip OpenCore"
echo "==================================="
wget $LINK
unzip "OpenCore-${VERSION}-RELEASE.zip" "X64/*" -d "./Downloaded"
rm "OpenCore-${VERSION}-RELEASE.zip"

echo "==================================="
echo "Download ext4_x64 (perez987)"
echo "==================================="
wget -nv https://github.com/acidanthera/OcBinaryData/raw/master/Drivers/ext4_x64.efi -O ./Downloaded/X64/EFI/OC/Drivers/ext4_x64.efi
echo "==================================="
echo "Download HFSPlus (Daniel Hurtado)"
echo "==================================="
wget -nv https://github.com/acidanthera/OcBinaryData/raw/master/Drivers/HfsPlus.efi -O ./Downloaded/X64/EFI/OC/Drivers/HfsPlus.efi
echo "==================================="
echo "Check ISK keys"
echo "==================================="
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 "Sign OpenCore .efi files"
echo "==================================="
# Sign drivers by recursively looking for the .efi files in ./Downloaded directory
# Don't sign files that start with the dot, as this is metadata files
# Andrew Blitss's contribution0
find ./Downloaded/X64/EFI/**/* -type f -name "*.efi" ! -name '.*' | cut -c 3- | xargs -I{} bash -c 'sbsign --key ISK.key --cert ISK.pem --output $(mkdir -p $(dirname "./Signed/{}") | echo "./Signed/{}") ./{}'

echo "====================================================="
echo "Signed OpenCore is in oc/Signed/Downloaded folder"
echo "====================================================="
# Clean
#rm -rf Downloaded

Los archivos .auth de la carpeta Uefi-SB/oc son los que debes integrar en el firmware.

Incluir variables seguras en el firmware

El último paso es insertar las variables seguras en el firmware UEFI, reemplazando las variables existentes:

  • db.auth >> db (Base de datos de firmas permitidas): base de datos de firmas UEFI que puede contener (una combinación de) claves públicas, firmas y hashes simples. Funciona esencialmente como una lista blanca de claves y firmas autorizadas para arrancar ejecutables. De forma predeterminada, la variable db se cargará con un conjunto de claves públicas emitidas por varios proveedores autorizados por Microsoft.
  • kek.auth >> KEK (Key Exchange Keys): base de datos de firmas que contiene una (o más) claves públicas. Las actualizaciones de la base de datos deben estar firmadas con la clave privada de una de estas claves (la PK no se puede utilizar para esto). De forma predeterminada, la variable KEK se cargará con una clave pública emitida por Microsoft.
  • pk.auth >> PK (Platform Key): se puede usar para firmar actualizaciones en modo de usuario para PK o KEK pero no para la db (tampoco se puede usar para firmar ejecutables). De forma predeterminada, la variable PK se cargará con una clave pública emitida por el proveedor de hardware (por ejemplo, Gigabyte).

Esto se puede hacer de 2 maneras: menú BIOS o KeyTool. Utilizo el menú BIOS porque siempre está disponible y no tengo que crear una memoria USB con una partición EFI para copiar KeyTool.efi a la carpeta BOOT con el nombre BOOTx64.efi.

Máquina virtual UTM Ubuntu en macOS

Ubuntu virtual machine on macOS

Deja un comentario