shim est une application EFI triviale qui, une fois lancée, tente d’ouvrir et d’exécuter une autre application. Cela tentera initialement de le faire via les appels standard EFI
LoadImage()
etStartImage()
. Si cela échoue (parce que le démarrage sécurisé est activé et que le binaire n'est pas signé avec une clé appropriée, par exemple), il validera alors le binaire par rapport à un certificat intégré. Si cela réussit et si le binaire ou la clé de signature ne sont pas sur la liste noire, alors Shim sera déplacé et exécutera le binaire.
J'ai lu pour comprendre comment se déroule la procédure de vérification lorsque l'option d'amorçage sécurisé est activée:
Différence entre vmlinuz * -generic et * -generic.efi.signed
Comment fonctionne le démarrage sécurisé?
Gestion des chargeurs de démarrage EFI pour Linux: Contrôle du démarrage sécurisé
Je pourrais dire maintenant que la procédure est la suivante:
Shim est d'abord exécuté par le micrologiciel de la machine. Shim doit maintenant lancer le chargeur de démarrage. Ce que je ne comprends pas, c'est comment Shim vérifie les fichiers binaires? Par exemple, le paragraphe cité ci-dessus indique que shim tente de démarrer l'autre application via les appels standard EFI LoadImage()
et StartImage()
. Si cela échoue, shim tente de vérifier le fichier binaire à partir d'un certificat intégré. Ce certificat intégré appartient alors à shim? Essentailly est-ce pourquoi Shim s'appelle MOK (Machine Owner Key Manager)? Parce qu'il a sa propre base de données de clés pour vérifier les fichiers binaires.
En termes simples, le micrologiciel de la machine a sa propre base de données de clés dans la NVRAM pour vérifier les fichiers binaires, et Shim a-t-il sa propre base de données de clés pour vérifier les fichiers binaires?
Une fois que le chargeur de démarrage a été vérifié et exécuté, où cherche-t-il à localiser les clés du noyau signé qu'il doit démarrer, à partir de la base de données de clés du microprogramme par exemple?
Comme vous en avez déduit correctement, SHIM tentera de charger à partir de LoadImage()
et StartImage()
en premier. L'EFI validera ensuite que la signature correspond (via le mécanisme interne SecureBoot). Si LoadImage()
renvoie un EFI_SECURITY_VIOLATION
, le système essaiera de remplacer l'étape de chargement 2 (dans ce cas, GRUB2) à partir d'un certificat interne.
Ce certificat est intégré au système lors de la compilation, ce qui a été fait par Canonical dans ce cas. Ce certificat peut être extrait de SHIM en utilisant binwalk
ou un utilitaire similaire.
En pratique, cela permet à SecureBoot d'avoir une signature validée de shim
stockée dans le cache, ce qui permet ensuite à shim
de vérifier que GRUB a été signé avec le certificat susmentionné. Si c'était le cas, GRUB démarre correctement.
SHIM utilisera les clés système chaque fois que possible - c'est pourquoi LoadImage()
et StartImage()
sont utilisés en premier. Si cela ne fonctionne pas, SHIM tentera de charger stage2 avec son propre certificat interne. Vous pouvez voir ce code ici (une partie de verify_buffer
), appelé en partie dans la chaîne handle_image
.
La chaîne de vérification complète ressemble à ceci:
Il est également important que le gestionnaire MOK ne soit pas la base de données MOK elle-même. Ce dernier est géré par le micrologiciel EFI, qui commande les éléments à ajouter/supprimer du fabricant pendant le clignotement ainsi que le système d’exploitation (ou, dans ce cas, shim
). shim
ne stocke qu'une très courte liste des clés compilées susmentionnées pour permettre un démarrage - tout le reste doit être géré par le microprogramme EFI.
La réponse de Kaz Wolfe est plutôt bonne, mais je tiens à souligner et à développer quelques points ...
La dernière fois que j'ai vérifié, Shim a essentiellement fourni une sorte de fonctionnalité de vérification parallèle de Secure Boot. Il est destiné à être utilisé par GRUB, qui est conçu pour lancer des noyaux Linux qui ne sont pas des programmes EFI. Ainsi, Shim s'enregistre auprès de l'EFI de manière à ce que les programmes qui suivent puissent appeler Shim pour vérifier que les fichiers binaires sont signés. Shim le fait de deux manières:
Dans la plupart des cas, les MOK ne sont pas utilisés. si vous voulez double-amorcer Windows et Ubuntu, vous vous en sortirez probablement avec les clés intégrées du micrologiciel et la clé intégrée dans le binaire Shim d'Ubuntu. Vous utiliseriez des MOK si vous souhaitez ajouter une autre distribution Linux, compiler vos propres noyaux, utiliser un chargeur de démarrage autre que GRUB, utiliser des modules de noyau tiers, etc.
En plus de ces deux sources, il existe également les clés de démarrage sécurisé intégrées au microprogramme. Je ne me souviens pas si Shim utilise ces clés. Il les utiliserait implicitement s'il utilisait les appels LoadImage()
et StartImage()
d'EFI (ce qui est le cas, mais je n'ai pas examiné le contexte de cette réponse. ). Mon souvenir est que son propre code de vérification n'utilise pas les clés de démarrage sécurisé du microprogramme lorsque GRUB rappelle pour vérifier si un noyau est signé, mais je ne m'en souviens peut-être pas correctement.
Quant à la manière dont Shim s'intègre dans le système Secure Boot, la dernière fois que j'ai vérifié, cela n'a pas été le cas. Pour lancer son programme ultérieur (GRUB), l’IIRC implémente son propre code de chargement binaire, qui ressemble à une version simplifiée du code figurant dans l’implémentation exemple UEFI de Tianocore. Ce code appelle le propre code de vérification Secure Boot de Shim, qui compare un binaire à sa clé intégrée et à la liste MOK locale, pour lancer un binaire. (Il peut également utiliser les propres clés de démarrage sécurisées du microprogramme, mais je n'en suis pas certain.) Une fois que GRUB est chargé, il appelle la fonction de vérification binaire de Shim pour vérifier le noyau Linux, lequel GRUB se lance à sa manière (pas comme l'EFI lance ses programmes). Ainsi, Shim ne s’intègre pas vraiment dans le firmware; il ne met qu'une ou deux de ses fonctions à la disposition des programmes suivants, en laissant les fonctions LoadImage()
et StartImage()
EFI inchangées.
Cela dit, EFI fournit des moyens de remplacer ou de compléter les appels système EFI normaux, et certains outils utilisent ces méthodes. Par exemple, le programme PreLoader, qui était un outil permettant de faire quelque chose de similaire à ce que fait Shim, s’intégrait plus profondément dans le firmware; il utilisait des appels système EFI conçus pour corriger des fonctions endommagées ou obsolètes afin de modifier StartImage()
afin qu'il vérifie both les clés de démarrage UEFI Secure Boot habituelles et le MOK. PreLoader a bien failli perdre la route; ses développeurs et les développeurs de Shim ont coopéré pour se concentrer sur Shim plutôt que sur PreLoader en tant qu'outil Linux Secure Boot standard. D’après nos souvenirs, Shim n’a pas adopté l’intégration UEFI plus poussée de PreLoader; Cependant, cela fait un moment que j'ai examiné le code de très près, il se peut donc que je sois dépassé. Cela dit....
Mon propre gestionnaire de démarrage rEFInd utilise le code que j'ai extrait du programme PreLoader afin de "coller" le code de vérification binaire de Shim dans le sous-système de vérification normal de l'UEFI. Ainsi, avec rEFInd dans l'image, toute tentative de lancement d'un programme EFI à l'aide de LoadImage()
et StartImage()
appelle d'abord le code d'authentification Shim et, en cas d'échec, appelle ensuite l'authentification standard UEFI Secure Boot. Le gestionnaire de démarrage gummiboot/systemd-boot fait quelque chose de similaire. Les deux programmes le font parce qu’ils lancent le noyau Linux au moyen de son chargeur de stub EFI, ce qui signifie qu’ils reposent sur les appels EFI LoadImage()
et StartImage()
. Cela contraste avec GRUB, qui est un chargeur de démarrage complet qui lance le noyau Linux à sa manière. GRUB n'a donc pas besoin de ces appels système EFI pour reconnaître la clé de Shim ou la liste MOK locale.
J'espère que cela aide à clarifier les choses, mais je ne suis pas sûr que ce sera le cas. Les détails de la façon dont tout ce travail est confus, et cela fait un moment que je ne les ai pas traités en détail, alors mes propres pensées ne sont pas aussi organisées qu'elles pourraient l'être.