Foxboron / sbctl

:computer: :lock: :key: Secure Boot key manager
MIT License
1.43k stars 80 forks source link

linux refusing the creation of PK on thinkpad T460s #102

Closed dkwo closed 10 months ago

dkwo commented 2 years ago

I'm trying to use sbctl on Void linux, but it appears I'm not mounting the efivars correctly. Could you please point out the correct way to do it, without relying on dbus, udev etc?

$ doas sbctl status
Installed:      ✔ Sbctl is installed
Owner GUID:     <some stuff>
Setup Mode:     ✔ Disabled
Secure Boot:    ✘ Disabled
$ doas sbctl enroll-keys
Enrolling keys to EFI variables...✘
couldn't sync keys: couldn't open file: open /sys/firmware/efi/efivars/<some string>: no such file or directory
$ doas mount -t efivarfs efivarfs /sys/firmware/efi/efivars
$ doas sbctl status
Installed:      ✔ Sbctl is installed
Owner GUID:     <same stuff>
Setup Mode:     ✘ Enabled
Secure Boot:    ✘ Disabled
$ doas sbctl enroll-keys
Enrolling keys to EFI variables...✘
sbtl requires root to run: couldn't sync keys: couldn't write efi variable: write /sys/firmware/efi/efivars/<some different string>: permission denied

Thanks.

dkwo commented 2 years ago

this is on a thinkpad t460s

dkwo commented 2 years ago
$ doas lsattr /sys/firmware/efi/efivars/<string>
---------------------- /sys/firmware/efi/efivars/<string>
Foxboron commented 2 years ago

Please post complete errors. I'm unable to figure out anything if you keep censoring values for no good reason.

I don't know how Void mounts efivarfs, so that is something you need to figure out on your own. As for rest of the errors you need to reset the User Mode. And give me the output of:

lsattr /sys/firmware/efi/efivars/PK-8be4df61-93ca-11d2-aa0d-00e098032b8c /sys/firmware/efi/efivars/KEK-8be4df61-93ca-11d2-aa0d-00e098032b8c /sys/firmware/efi/efivars/db-d719b2cb-3d3a-4596-a3bc-dad00e67656f
dkwo commented 2 years ago

Let me do it again: this is with efivars mounted via doas mount -t efivarfs efivarfs /sys/firmware/efi/efivars

$ doas sbctl status
Installed:      ✔ Sbctl is installed
Owner GUID:     81b996f5-236f-43ab-b5c9-282b933f006c
Setup Mode:     ✘ Enabled
Secure Boot:    ✘ Disabled
$ doas sbctl enroll-keys
Enrolling keys to EFI variables...✘
sbtl requires root to run: couldn't sync keys: couldn't write efi variable: write /sys/firmware/efi/efivars/PK-8be4df61-93ca-11d2-aa0d-00e098032b8c: permission denied
$ doas lsattr /sys/firmware/efi/efivars/PK-8be4df61-93ca-11d2-aa0d-00e098032b8c /sys/firmware/efi/efivars/KEK-8be4df61-93ca-11d2-aa0d-00
e098032b8c /sys/firmware/efi/efivars/db-d719b2cb-3d3a-4596-a3bc-dad00e67656f
---------------------- /sys/firmware/efi/efivars/PK-8be4df61-93ca-11d2-aa0d-00e098032b8c
---------------------- /sys/firmware/efi/efivars/KEK-8be4df61-93ca-11d2-aa0d-00e098032b8c
---------------------- /sys/firmware/efi/efivars/db-d719b2cb-3d3a-4596-a3bc-dad00e67656f
Foxboron commented 2 years ago

Output of ls -lah /sys/firmware/efi/efivars/PK-8be4df61-93ca-11d2-aa0d-00e098032b8c /sys/firmware/efi/efivars/KEK-8be4df61-93ca-11d2-aa0d-00e098032b8c /sys/firmware/efi/efivars/db-d719b2cb-3d3a-4596-a3bc-dad00e67656f please

dkwo commented 2 years ago
 ls -lah /sys/firmware/efi/efivars/PK-8be4df61-93ca-11d2-aa0d-00e098032b8c /sys/firmware/efi/efivars/KEK-8be4df61-93ca-11d2-aa0d-00e098
032b8c /sys/firmware/efi/efivars/db-d719b2cb-3d3a-4596-a3bc-dad00e67656f
-rw-r--r-- 1 root root 1.4K Oct 18 19:12 /sys/firmware/efi/efivars/KEK-8be4df61-93ca-11d2-aa0d-00e098032b8c
-rw-r--r-- 1 root root    0 Oct 18 19:12 /sys/firmware/efi/efivars/PK-8be4df61-93ca-11d2-aa0d-00e098032b8c
-rw-r--r-- 1 root root 1.3K Oct 18 19:12 /sys/firmware/efi/efivars/db-d719b2cb-3d3a-4596-a3bc-dad00e67656f
Foxboron commented 2 years ago

Did you select User Mode in the Secure Boot menu on your thinkpad?

dkwo commented 2 years ago

I first cleared keys and then selected setup mode.

dkwo commented 2 years ago

is user mode something different?

Foxboron commented 2 years ago

It's refusing to accept the Platform Key so I'm not quite sure what state the secure boot mode should be in for that to be a thing. To me it seems like everything should be working.

dkwo commented 2 years ago

In my bios, I have under secure boot:

secure boot: disabled
platform mode: setup mode (cannot change)
secure boot mode: custom (cannot change)
reset to setup mode: enter (did as 2)
restore factory keys: enter
clear all secure boot keys: enter (did as 1)

As for the OS, I don't think it mounts by default efivars, so I used the mount command above.

dkwo commented 2 years ago

could it be an issue with thinkpads? have you had experience with those?

Foxboron commented 2 years ago

sbctl is developed on a t480s. It should just work. Everything seems in order so this is weird. Never seen this before frankly.

dkwo commented 2 years ago

I see. And you're not questioning the way I mount efivars, right? (if I don't mount them, there's nothing there)

Foxboron commented 2 years ago

systemd mount efivarfs like this on Arch Linux

λ ~ » mount | grep efivar
efivarfs on /sys/firmware/efi/efivars type efivarfs (rw,nosuid,nodev,noexec,relatime)

I don't think anything here matters? It did manage to create KEK and db so PK is linux refusing the creation.

dkwo commented 2 years ago

I was reading on reddit that "if it only happens on the last step I’d try using PK.esl instead of PK.auth". Which format does sbctl use? is it possible to change format?

Foxboron commented 2 years ago

sbctl uses the signed EFI_SIGNATURE_LISTS, and any well behaving EFI implementation should support both. If you want to use the unsigned list you can try build sbctl yourself and remove the following lines.

https://github.com/Foxboron/sbctl/blob/master/keys.go#L107-L110

And pass sigdb into WriteEFIVariable

dkwo commented 2 years ago

Does the program use EFI_VARIABLE_APPEND_WRITE by any chance? I was reading lenovo does not support it.

Foxboron commented 2 years ago

The current Enroll code doesn't use EFI_VARIABLE_APPEND_WRITE I believe.

duffydack commented 2 years ago

Having the same issue on my T460 with Arch (proper). Reset/Cleared keys a hundred times, chattr -i the files, always fails with permission denied sbctl requires root to run: couldn't sync keys: couldn't write efi variable: write /sys/firmware/efi/efivars/PK-some-blah: permission denied :(

dkwo commented 2 years ago

I see, so perhaps the UEFI implementation of the T460(s) is faulty.

dkwo commented 2 years ago

@mrhpearson Could Lenovo BIOS devs investigate this?

mrhpearson commented 2 years ago

I've flagged it to the FW team (for my reference LO-1477). For these older platforms it can be really hard to get support for issues like this so no promises that I'll be able to get an answer....but I'll try. Mark

ghost commented 2 years ago

Same problem, but I'm on a dell precision 3510. In the last step, I get the error:

stanley in ~ λ sudo sbctl enroll-keys --microsoft     
Enrolling keys to EFI variables...
With vendor keys from Microsoft...✗ 
sbctl requires root to run: couldn't sync keys: couldn't write efi variable: write /sys/firmware/efi/efivars/db-d719b2cb-3d3a-4596-a3bc-dad00e67656f: permission denied

Output of lsattr:

stanley in ~ λ lsattr /sys/firmware/efi/efivars/PK-8be4df61-93ca-11d2-aa0d-00e098032b8c /sys/firmware/efi/efivars/KEK-8be4df61-93ca-11d2-aa0d-00e098032b8c /sys/firmware/efi/efivars/db-d719b2cb-3d3a-4596-a3bc-dad00e67656f
---------------------- /sys/firmware/efi/efivars/PK-8be4df61-93ca-11d2-aa0d-00e098032b8c
---------------------- /sys/firmware/efi/efivars/KEK-8be4df61-93ca-11d2-aa0d-00e098032b8c
---------------------- /sys/firmware/efi/efivars/db-d719b2cb-3d3a-4596-a3bc-dad00e67656f

Output of ls -lah:

stanley in ~ λ ls -lah /sys/firmware/efi/efivars/PK-8be4df61-93ca-11d2-aa0d-00e098032b8c /sys/firmware/efi/efivars/KEK-8be4df61-93ca-11d2-aa0d-00e098032b8c /sys/firmware/efi/efivars/db-d719b2cb-3d3a-4596-a3bc-dad00e67656f 
-rw-r--r-- 1 root root 3,1K 23. Dez 09:44 /sys/firmware/efi/efivars/db-d719b2cb-3d3a-4596-a3bc-dad00e67656f
-rw-r--r-- 1 root root 1,6K 23. Dez 09:44 /sys/firmware/efi/efivars/KEK-8be4df61-93ca-11d2-aa0d-00e098032b8c
-rw-r--r-- 1 root root 1,4K 23. Dez 09:44 /sys/firmware/efi/efivars/PK-8be4df61-93ca-11d2-aa0d-00e098032b8c
sbctl status output ```bash stanley in ~ λ sbctl status Installed: ✓ sbctl is installed Owner GUID: aa439dbd-ede7-466d-99d5-b0ba58c2f2a4 Setup Mode: ✓ Disabled Secure Boot: ✗ Disabled Vendor Keys: microsoft ```

Setup mode is set for "user" and I'm using Endeavour OS, with encryption, if it's relevant.

**bootctl status output** ```bash systemd-boot not installed in ESP. System: Firmware: n/a (n/a) Secure Boot: disabled Setup Mode: user TPM2 Support: no Boot into FW: supported Current Boot Loader: Product: n/a Features: ✗ Boot counting ✗ Menu timeout control ✗ One-shot menu timeout control ✗ Default entry control ✗ One-shot entry control ✗ Support for XBOOTLDR partition ✗ Support for passing random seed to OS ✗ Boot loader sets ESP information ESP: n/a File: └─n/a Random Seed: Passed to OS: no System Token: not set Exists: no Available Boot Loaders on ESP: ESP: /boot/efi (/dev/disk/by-partuuid/c0df765e-6457-4d31-b912-5e30bc0551af) File: └─/EFI/BOOT/bootx64.efi Boot Loaders Listed in EFI Variables: Title: EndeavourOS ID: 0x0003 Status: active, boot-order Partition: /dev/disk/by-partuuid/c0df765e-6457-4d31-b912-5e30bc0551af File: └─/EFI/EndeavourOS/grubx64.efi Title: Artix ID: 0x0002 Status: active, boot-order Partition: /dev/disk/by-partuuid/c0df765e-6457-4d31-b912-5e30bc0551af File: └─/EFI/Artix/grubx64.efi Title: Windows Boot Manager ID: 0x0001 Status: active, boot-order Partition: /dev/disk/by-partuuid/c0df765e-6457-4d31-b912-5e30bc0551af File: └─/EFI/Microsoft/Boot/bootmgfw.efi Title: UEFI: INTEL SSDSCKKF512H6 SATA 512GB, Partition 1 ID: 0x0010 Status: active, boot-order Partition: /dev/disk/by-partuuid/c0df765e-6457-4d31-b912-5e30bc0551af File: └─EFI/Microsoft/Boot/bootmgfw.efi Title: Windows Boot Manager ID: 0x0000 Status: active Partition: /dev/disk/by-partuuid/c0df765e-6457-4d31-b912-5e30bc0551af File: └─/EFI/Microsoft/Boot/bootmgfw.efi Boot Loader Entries: $BOOT: /boot/efi (/dev/disk/by-partuuid/c0df765e-6457-4d31-b912-5e30bc0551af) 0 entries, no entry could be determined as default. ```
Foxboron commented 2 years ago

Did you reset the keys in the BIOS menu? Do the file contain anything before you started running sbctl?

ghost commented 2 years ago

Did you reset the keys in the BIOS menu?

Yes, I checked "Clear" from BIOS for TPM 1.2.

Do the file contain anything before you started running sbctl?

Hummmm 🤔, not sure. How can I be sure of that?

Running sudo sbctl list-files doesn't yield anything.

Foxboron commented 2 years ago

Does the PK, KEK, db files exist after reseting the keys?

ghost commented 2 years ago

I don't remember, and I can't try again because "Clear" is now grayed out.

image

When trying to issue sudo sbctl reset I get the same message: "sbctl requires root to run: couldn't write efi variable"


Sorry for the late response, I'm trying your tool in my work computer. The "architecture guy" requests secure boot enabled, because of General Data Protection Law.

Foxboron commented 2 years ago

sudo sbctl reset isn't going to do anything when you can't enroll keys.

I'm also not sure why you are in the TPM 1.2 menu for Secure Boot?

dkwo commented 2 years ago

@Foxboron @mrhpearson Would it make sense to transfer this issue over to https://github.com/fwupd/firmware-lenovo (or some similar github organization tracking lenovo firmware issues) as it seems really firmware-related? Who has the authority to do so?

dkwo commented 2 years ago

Hi @mrhpearson , is there any update with this issue (LO-1477) ?

dkwo commented 2 years ago

@ChiWei-Chen Can you help with this?

dkwo commented 2 years ago

Let me add that using a different tool I get a similar error:

doas strace efi-updatevar -f /home/ti2/Projects/uefi-sb/PK/PK.auth PK
open(“/sys/firmware/efi/efivars/PK-8be4df61-93ca-11d2-aa0d-00e098032b8c”, O_RDWR|O_CREAT|O_TRUNC, 0644) = -1 EPERM (Operation not permitted)
momofor commented 2 years ago

Same issue on t460s with latest firmware version.

h3po commented 1 year ago

I have found that if I create the db/key/cert files with the mkkeys script instead of sbctl create-keys, then sbctl enroll-keys works on my t460s. At first I thought it may be because mkkeys creates 2k rsa keys and sbctl creates 4k, but even if I recompile with RSAKeySize = 2048 (https://github.com/Foxboron/sbctl/blob/master/keys.go#L26) the keys created by sbctl are 2k but cannot be uploaded anyway. So it's pretty sure to say the cause of the problem is something that mkkeys does to the files that sbctl does not.

by "mkkeys script" I mean this one: https://www.rodsbooks.com/efi-bootloaders/mkkeys.sh

Edit: creating 4k keys with mkkeys.sh also works.

dkwo commented 1 year ago

@h3po Thanks for pointing this out. What are the differences between the two key formats? @mrhpearson What are the requirements for a key to be enrolled?

mrhpearson commented 1 year ago

Will check - but @Foxboron - does this make anything jump out for you? Realistically I soubt the FW team are going to debug sbctl I'm afraid. I would have a stab at it but don't have the time right now and suspect I lack the expertise. If we're doing something in the BIOS that isn't UEFI compliant and can point at that then I'll have a lot more chance of getting this fixed.

Can we compare the certificates and steps along the way and see where they are different? Maybe hack sbctl to use the mkkeys generated certs and sign those - if that works we know it's the cert generation stage, and if it doesn't it's the signing part? Apologies if the suggestion is naive.

Minor Q - but it looks like sbctl uses 'db' and mkkeys uses 'DB' - is that important?

Mark

h3po commented 1 year ago

I'll look at the certificates and keys this weekend. I have no clue about efi things, but x509 I can maybe help with. At first glance the certificates from both tools are nothing special, but those created by openssl have some keyusage bits set that sbctl does not create. In the meantime, I have my t460s secure-booted with an arch linux unified kernel signed by sbctl. Thanks a lot for creating this tool!

Minor Q - but it looks like sbctl uses 'db' and mkkeys uses 'DB' - is that important?

I had to rename and move the mkkeys files into the sbctl folder structure for them to be recognized. Anyway the db is not the problem, it's the PK variable that enroll-keys fails at. db and KEK are written successfully

Foxboron commented 1 year ago

@mrhpearson Yo, I certainly don't expect you to debug sbctl on my behalf :) You must have a lot better things to do with your time.

I can compare the certificates with openssl asn1parse as I normally do when I get the time.

mrhpearson commented 1 year ago

This stuff is interesting - I would love to dig into it more myself but it is pretty busy right now :)

sbctl looks like an awesome tool - thanks for creating and maintaining it!

Foxboron commented 1 year ago

Thank you! And thanks for working on Linux enablement :)

Techman commented 1 year ago

Looks like I have the same issue on my T460. Glad to have found this issue. I know I am using an Arch derivative (edit: since this issue, I am now on Arch proper), but I do not think that should matter in this case.

Below is my system information (copied from KDE's info center):

Operating System: Manjaro Linux
Kernel Version: 5.15.72-1-MANJARO (64-bit)
Processors: 4 × Intel® Core™ i5-6300U CPU @ 2.40GHz
Memory: 15.5 GiB of RAM
Graphics Processor: Mesa Intel® HD Graphics 520
Manufacturer: LENOVO
Product Name: 20FN002JUS
System Version: ThinkPad T460
iLuckyW commented 1 year ago

@dkwo were you able to resolve your issue? I am heving the same problem with my t460s

dkwo commented 1 year ago

It's still there. The mkkeys script produces .auth .cer .crt .esl .key files, while in /usr/share/secureboot/keys/* there are .key .pem files. How do I compare them with openssl? Which of the former should be moved to /usr/share/secureboot/* to test?

dkwo commented 12 months ago

Maybe @FiloSottile can comment on this possible discrepancy between keys produced by openssl and by go?

FiloSottile commented 12 months ago

Maybe! Could you summarize what Go function is being used, and what’s the openssl equivalent?

dkwo commented 12 months ago

The go functions used in func CreateKey at https://github.com/Foxboron/sbctl/blob/master/keys.go#L53 are rsa.GenerateKey, x509.MarshalPKCS8PrivateKey and x509.CreateCertificate, while the openssl script at https://www.rodsbooks.com/efi-bootloaders/mkkeys.sh uses

openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME PK/" -keyout PK.key -out PK.crt -days 3650 -nodes -sha256
openssl x509 -in PK.crt -out PK.cer -outform DER
Cornelicorn commented 11 months ago

Also experiencing this when running sbctl reset on

    description: Mini Tower Computer
    product: OptiPlex 9020 (05A4)
    vendor: Dell Inc.
    version: 00
Vtec234 commented 11 months ago

I ran into this and debugged it. The issue appears to be that sbctl sets the keyUsage bitfield: https://github.com/Foxboron/sbctl/blob/21b6b3dd788ec64411dd34d32598458a30d56c76/keys.go#L62 whereas openssl x509 does not. If we instead omit this field, or set it to keyCertSign, the certificate is accepted by the firmware.

On a side note, it's really weird to set the country field (which would usually be a two-letter country code) to "Platform Key" or whatever, and openssl x509 will not even let you do that. But this turned out not be the issue. https://github.com/Foxboron/sbctl/blob/21b6b3dd788ec64411dd34d32598458a30d56c76/keys.go#L64

dkwo commented 11 months ago

Thank you! This fixes my issue.