Foxboron / sbctl

:computer: :lock: :key: Secure Boot key manager
MIT License
1.52k stars 87 forks source link

Feature request: MOK & Shim support #85

Open Jaakkonen opened 3 years ago

Jaakkonen commented 3 years ago

On some machines enabling UEFI secure boot setup mode is a no-can-do due to company policies or horrible UEFI UIs. Support for using a Microsoft CA signed Shim with a MOK key would enable using secure boot on these machines.

Foxboron commented 3 years ago

I don't personally have any use for MOK+shim. mokutils seems fairly usable and I don't see what is missing from a usability standpoint?

The Microsoft CA stuff is going to be unconditionally added unless opted out in the future.

EvilBit commented 3 years ago

The Microsoft CA stuff is going to be unconditionally added unless opted out in the future.

You mean sbctl enroll-keys will automatically add Microsoft's keys in the future?

Please make it opt-in rather than opt-out.

Adding back Microsoft's keys is most likely not the majority use case, and making a SB setup less secure by signing 3rd party keys should be a user's active decision, i.e. opt-in. After all, why add back Microsoft's keys when going through the trouble of rolling your own SB PK setup? Kind of defeats the primary purpose of having full control over your chain of trust. ;)

Foxboron commented 3 years ago

Please make it opt-in rather than opt-out.

Can't do that. We don't know if there is any signed oprom in the boot process and if we enroll custom signing keys without having this in the clear the computer simply wont POST. This is just going to brick peoples laptops for no good reasons.

Adding back Microsoft's keys is most likely not the majority use case, and making a SB setup less secure by signing 3rd party keys should be a user's active decision, i.e. opt-in.

It is, which is the issue. UEFI Class 3+ which is what Intel is targeting from 2021 and onwards, along with Windows 11 demanding TPM+SecureBoot support we'll most likely see more signed oprom we can't discover in boot process. Especially outside of the laptop market.

The goal here is to be user-friendly, so the only sane thing here is to make it opt-out with a warning for people that know what they are doing. Anything else is going to have people come to us (read "me") and complain about broken computers. Don't want to deal with that.

Kind of defeats the primary purpose of having full control over your chain of trust. ;)

I have ranted to UEFI WG people. There is nothing we can do here.

Foxboron commented 3 years ago

You mean sbctl enroll-keys will automatically add Microsoft's keys in the future?

I'm probably going to abstract away create-keys and enroll-keys into a setup command which is going to be a bit more user-friendly for the initial setup. I don't think the low-level plumbing commands is going to change in this regard.

Foxboron commented 3 years ago

You mean sbctl enroll-keys will automatically add Microsoft's keys in the future?

I'm probably going to abstract away create-keys and enroll-keys into a setup command which is going to be a bit more user-friendly for the initial setup. I don't think the low-level plumbing commands is going to change in this regard.

EvilBit commented 3 years ago

It is, which is the issue. UEFI Class 3+ which is what Intel is targeting from 2021 and onwards, along with Windows 11 demanding TPM+SecureBoot support we'll most likely see more signed oprom we can't discover in boot process. Especially outside of the laptop market.

Damn, didn't think about OPROMs - those pesky things keep coming back to haunt us. Already a source of severe exploits in the past (see e.g. Thunderstrike). AFAIK they are also only necessary if you rely on devices which need OPROMs during BDS stage in UEFI and afterwards unnecessary for booting an OS with sane device driver initialization, à la linux. Actually, I'm trying to get rid of all the DXE stage onwards UEFI madness right now with LinuxBoot / NERF firmware - I'm curious how that will work together with secure boot and sbctl.

The goal here is to be user-friendly, so the only sane thing here is to make it opt-out with a warning for people that know what they are doing. Anything else is going to have people come to us (read "me") and complain about broken computers. Don't want to deal with that.

Yeah, I understand that concern of course. I propose to make it not only a warning, but a mandatory flag, e.g. --include-microsoft-keys or --include-vendor-keys, without which enrolling errors out with an explanation. Additionally an --expert flag which silences those kinds of safety checks.

WhyNotHugo commented 3 years ago

Isn't signing the oproms with the new keys also a possibility?

Adding MS's keys kinda defeats the purpose of using SecureBoot completely: the system will only run code signed with a private key, but they key is in the hand of a completely untrustworthy third party that's signed software for uncountable others too.

There's also the possibility of no default, and prompting the user to pick. But adding a third party's key is a huge security issue that really shouldn't be the default. I'd kinda akin to setting the root password a pre-defined default value; even if it's not public, it's very far from being safe.

Foxboron commented 3 years ago

Isn't signing the oproms with the new keys also a possibility?

Then you need to start hardware hacking. Oprom extraction, modify it and write it back. It's not something that can be done from userspace.

https://github.com/osresearch/safeboot/issues/84#issuecomment-815402662

There's also the possibility of no default, and prompting the user to pick. But adding a third party's key is a huge security issue that really shouldn't be the default.

There isn't really any good way around this. I wish it would be easier to detect signed oprom from userspace but I don't think it's possible.

WhyNotHugo commented 3 years ago

Oh, shit. Sounds like UEFI SecureBoot wasn't really though out 100%, and they shipped it quickly without really considering it being actually used.

EvilBit commented 3 years ago

Well, to be fair, I've yet to personally stumble over a (signed) Option ROM that's actually necessary for booting modern hardware (even in server hardware space). That doesn't mean they don't exist and might change with UEFI Class 3+. I believe Trammell Hudson (@osresearch) did more in-depth research on disabling as many untrusted Option ROMs as possible and came to a similar conclusion (?).

In practice, one should probably strive to replace the whole DXE & Option ROM phase with something like LinuxBoot, NERF, coreboot (if lucky enough with hardware), etc.


To reiterate, I believe forcing the user to make an active choice via two mutually exclusive command line flags would be best, à la --include-microsoft-keys vs. --no-include-microsoft-keys (maybe vendor instead of microsoft). Without any of the two present, the programm would error out with an explanatory message.

That way, we wouldn't establish in an insecure default, protecting users from both:

osresearch commented 3 years ago

I haven't encountered any laptops that require option roms (most of my research is on Thinkpads and NUCs), although servers and desktops definitely use them, especially if the system has an external GPU for primary video or RAID card for booting. One of the safeboot contributors hit this with their desktop and had to track down a VGA monitor to be able to use the on-board video to reset the UEFI PK.

Re-signing the option rom as described in https://github.com/osresearch/safeboot/issues/84#issuecomment-815402662 is probably unnecessary (and fraught with peril if things go wrong or if the firmware is reset to factory keys) -- the hash of the existing ROM can be added to the db, right? This would also eliminate a roll-back attacks where an adversary installs an older vulnerable version of an option ROM.

The option ROMs should show up in the tpm event log, so it should be possible to parse that to find any that were loaded during boot and perhaps offer to sign them with the user provided PK or KEK so they can be enrolled in the db.

Foxboron commented 3 years ago

the hash of the existing ROM can be added to the db, right? This would also eliminate a roll-back attacks where an adversary installs an older vulnerable version of an option ROM.

The issue I see is that we need the Authenticode checksum of the OpROM. I don't how we can realistically retrieve this file from Linux userspace? The comment from safeboot implies it can be extracted but this is out-of-scope for any user friendly tooling.

The TPM eventlog is also going to record the checksum of the file itself, so if we can find the checksum in the eventlog we still can't enroll it into the db.

The option ROMs should show up in the tpm event log, so it should be possible to parse that to find any that were loaded during boot and perhaps offer to sign them with the user provided PK or KEK so they can be enrolled in the db.

I'm not clear how we can sign this file from Linux userspace though.

Foxboron commented 3 years ago

Wait, I forget if we need the authenticode checksum or a standard sha256sum of the file for the db and dbx variable?

Foxboron commented 3 years ago

Ah, it's the checksum of the oprom itself!

UEFI spec 2.8 errata A, February 2020. Page 1727, Table 227. "Authorization process flow", 2 A.

But then I need to figure out how we can properly parse the eventlog for loaded oprom. I wonder how easy it would be to obtain an example log with that? @orangecms do you have an idea :)?

osresearch commented 3 years ago

It's a little odd that they don't use the authenticode, but my guess is that this allows easier compatibility with legacy unsigned ROMs that need to be added to the allow-list. For things that are signed, the eventlog contains the authenticode hash, such as EV_EFI_BOOT_SERVICES_APPLICATION when loading shimx64.efi:

- EventNum: 24
  PCRIndex: 4
  EventType: EV_EFI_BOOT_SERVICES_APPLICATION
  DigestCount: 2
  Digests:
  - AlgorithmId: sha1
    Digest: "21e79438580ec89df674dfe12653d77d132c3936"
  - AlgorithmId: sha256
    Digest: "2ea4cb6a1f1eb1d3dce82d54fde26ded243ba3e18de7c6d211902a594fe56788"
  EventSize: 170
  Event:
    ImageLocationInMemory: 0x75943018
    ImageLengthInMemory: 1341560
    ImageLinkTimeAddress: 0x0
    LengthOfDevicePath: 138
    DevicePath: '02010c00d041030a0000000001010600001d01010600000003171000010000000025385b0142db5204012a000100000000080000000000000000100000000000904af79b23573d4abc468a6548cbb75e0202040434005c004500460049005c007500620075006e00740075005c007300680069006d007800360034002e0065006600690000007fff0400'

verified with:

# sbsign.safeboot --hash-only /boot/efi/EFI/ubuntu/shimx64.efi
warning: data remaining[1177936 vs 1341560]: gaps between PE/COFF sections?
2ea4cb6a1f1eb1d3dce82d54fde26ded243ba3e18de7c6d211902a594fe56788

I'll see if I can track down an eventlog with an option rom in it since most of my systems don't have them.

Foxboron commented 3 years ago

If we can get by with just reading the eventlog for oprom and stuffing the checksum into db it would make things a lot simpler.

It would be interesting if i could try boot a qemu instance some placeholder oprom with an emulated tpm? Not sure how possible that would be.

osresearch commented 3 years ago

qemu with ovmf and ipxe has these entries in the eventlog. The BOOT_SERVICES_APPLICATION is my kernel, although the EV_EFI_BOOT_SERVICES_DRIVER should be the ipxe, but doesn't match any of the files in /usr/lib/ipxe/qemu/*.rom so I'm trying to figure out where that hash comes from.

- EventNum: 1
  PCRIndex: 0
  EventType: EV_S_CRTM_VERSION
  DigestCount: 2
  Digests:
  - AlgorithmId: sha1
    Digest: "1489f923c4dca729178b3e3233458550d8dddf29"
  - AlgorithmId: sha256
    Digest: "96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7"
  EventSize: 2
  Event: "0000"
- EventNum: 2
  PCRIndex: 0
  EventType: EV_EFI_PLATFORM_FIRMWARE_BLOB
  DigestCount: 2
  Digests:
  - AlgorithmId: sha1
    Digest: "3f32b9a5c407bccf010934da6b80dda4cd160bb5"
  - AlgorithmId: sha256
    Digest: "a6dfbab05de8afdef2eb5e075b56f277fff9cd752d40f1a2360ea0e082159666"
  EventSize: 16
  Event:
    BlobBase: 0x820000
    BlobLength: 0xe0000
- EventNum: 3
  PCRIndex: 0
  EventType: EV_EFI_PLATFORM_FIRMWARE_BLOB
  DigestCount: 2
  Digests:
  - AlgorithmId: sha1
    Digest: "5178d24da0e0124f8100089f24725eb0ca865cca"
  - AlgorithmId: sha256
    Digest: "362cc6af7cc330ab3c10696edec503fc4341524711c31a509f2c9c2204365436"
  EventSize: 16
  Event:
    BlobBase: 0x900000
    BlobLength: 0xb00000
....
- EventNum: 10
  PCRIndex: 2
  EventType: EV_EFI_BOOT_SERVICES_DRIVER
  DigestCount: 2
  Digests:
  - AlgorithmId: sha1
    Digest: "3cab2aa673fc6a7f6e1765a82c04be90b110507f"
  - AlgorithmId: sha256
    Digest: "58c91e43a3a34c0784008712501dbfa44841ff67e6ec0db178d929bd40d3958f"
  EventSize: 78
  Event:
    ImageLocationInMemory: 0x3f207018
    ImageLengthInMemory: 216520
    ImageLinkTimeAddress: 0x0
    LengthOfDevicePath: 46
    DevicePath: '02010c00d041030a0000000001010600000204081800000000000064010000000000ffb10400000000007fff0400'
...
- EventNum: 27
  PCRIndex: 4
  EventType: EV_EFI_BOOT_SERVICES_APPLICATION
  DigestCount: 2
  Digests:
  - AlgorithmId: sha1
    Digest: "42ee27c5f05ba7b377905f1d54611f214b4b8185"
  - AlgorithmId: sha256
    Digest: "ec1899aefaad2092e8f736ebd1964f23089fb1ca73f0f873e9304dc071843c91"
  EventSize: 118
  Event:
    ImageLocationInMemory: 0x3d11e018
    ImageLengthInMemory: 19242912
    ImageLinkTimeAddress: 0x0
    LengthOfDevicePath: 86
    DevicePath: '02010c00d041030a00000000010106000002030b2500525400123456000000000000000000000000000000000000000000000000000001030c1b0000000000000000000000000000000000000000000000007fff0400'
Foxboron commented 3 years ago

Right, it measures the OpROM with Microsoft Authenticode. Hmm. I need to check if we can use the authenticode checksum in db + dbx.

See 2.3.3.1, Measuring PE/COFF Image Files (page 23). and Table 9 Events (page 93) in "TCG PC Client Platform Firmware Profile Specification, revision 1.04"

orangecms commented 3 years ago

Chiming in here a little as the curious web developer who loves iterating over array-like data structures - if you can collect some more sample logs, I'd love to render them visually and present some features in whatever way I see fit; will have to dig into it a bit, but I have a sense that it can enrich the understandability of the log.

For a start, I will just grab the sample from above and just render the respective messages with some metadata and maybe icons. In another step, I'd add something aware of the history, like "warning: this shouldn't happen because xyz was the previous state" or "error: your system is now compromised because...".

osresearch commented 3 years ago

Using strace I determined it is loading /usr/lib/ipxe/qemu/efi-e1000.rom. The hash of that doesn't match and it is a 307KB file, despite the driver hash claiming to be 216520 bytes (and it isn't zero padded or anything, it appears to be fully that size). Trying to dump the ROM via sysfs also fails: Extracting the ROM from the proper sysfs locaton results in the same file as the one on disk:

# lspci -v
...
00:02.0 Class 0200: Device 8086:100e (rev 03)
    Subsystem: Device 1af4:1100
    Flags: bus master, fast devsel, latency 0, IRQ 22
    Memory at c1080000 (32-bit, non-prefetchable) [size=128K]
    I/O ports at 6040 [size=64]
    Expansion ROM at 40000000 [disabled] [size=512K]
    Kernel driver in use: e1000
...
# echo 1 > /sys/bus/pci/devices/0000:00:02.0/rom
# xxd -g1 /sys/bus/pci/devices/0000:00:02.0/rom | head -8
00000000: 55 aa b2 e9 a2 00 22 00 00 00 00 00 00 00 00 00  U.....".........
00000010: 9c 00 00 00 00 00 84 00 1c 00 40 00 50 43 49 52  ..........@.PCIR
00000020: 86 80 0e 10 bf 04 1c 00 03 02 00 00 b2 00 01 00  ................
00000030: 00 00 07 00 00 00 00 00 8d b4 00 00 8d b4 00 00  ................
00000040: 24 50 6e 50 01 02 00 00 00 7d 00 00 00 00 60 00  $PnP.....}....`.
00000050: 70 00 02 00 00 f4 00 00 00 00 85 03 00 00 00 00  p...............
00000060: 68 74 74 70 3a 2f 2f 69 70 78 65 2e 6f 72 67 00  http://ipxe.org.
00000070: 69 50 58 45 00 28 50 43 49 20 78 78 3a 78 78 2e  iPXE.(PCI xx:xx.
# sha256sum rom
e79be70adf1bd94f485be3998d5e15fe287fa4fd46708123beb448df8d841dee  rom

Figuring out where that hash is coming from will take some more debugging it seems.

osresearch commented 3 years ago

Right, it measures the OpROM with Microsoft Authenticode. Hmm. I need to check if we can use the authenticode checksum in db + dbx.

See 2.3.3.1, Measuring PE/COFF Image Files (page 23). and Table 9 Events (page 93) in "TCG PC Client Platform Firmware Profile Specification, revision 1.04"

And looking at the source code for SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c:

  The image verification policy is:
    If the image is signed,
      At least one valid signature or at least one hash value of the image must match a record
      in the security database "db", and no valid signature nor any hash value of the image may
      be reflected in the security database "dbx".
    Otherwise, the image is not signed,
      The SHA256 hash value of the image must match a record in the security database "db", and
      not be reflected in the security data base "dbx".

And I've found the hash for the option ROM in the eventlog. There are two option ROMs in the file; my guess is one legacy and one PE. The EFI one appears second and the size matches:

# xxd -g1 efi-e1000.rom | grep MZ
00016430: 03 80 00 00 4b 00 00 00 4d 5a 00 00 00 00 00 00  ....K...MZ......
# dd if=efi-e1000.rom bs=1 skip=$[0x16438] > /tmp/efi.pe
# wc -c /tmp/efi.pe
216520 /tmp/efi.pe
# sbsign.safeboot --hash-only /tmp/efi.pe 
58c91e43a3a34c0784008712501dbfa44841ff67e6ec0db178d929bd40d3958f

So it is likely possible to enroll just the authenticode hash based on the eventlog since that is what the code is eventually looking for (first checked for a signature by a trusted key, and then based on the authenticode computed by HashPeImage())

Foxboron commented 3 years ago

It's funny because I was discussing the same code on IRC just now :)

I intend to try mess a little bit with enrolling some authenticode checksums into my laptops db and dbx variables and see what happens. I hope this isn't going to be all firmware dependant.

You also see fwupd use authenticode signatures when validating firmware files. https://github.com/fwupd/fwupd/blob/master/plugins/uefi-dbx/fu-uefi-dbx-common.c#L63

Foxboron commented 3 years ago

However, I think this issue has strayed a bit from the original request of MOK/shim support. I'll make a new issue detailing potential approaches for dealing with the Microsoft CA and, by extension, OpROM.

Foxboron commented 3 years ago

@osresearch Trivia: How many different ways do you need to have for properly checksuming PE/COFF binaries under UEFI/Secure Boot?

2!

It turns out that when embedding the PE/COFF checksum into signatures pesign and sbsigntools align the file buffer up to 8 bytes. However, this should not be done for checksums that enter db and dbx.

λ go-uefi master» go run ./cmd/gochecksum/main.go tests/shared/HelloWorld.efi
d2ae1f36ec9b40b55f60920a3f58ec902ebdc7c323e443412c751cdb3c42d3f3 (correct checksum accepted in db)                                                                  

λ go-uefi master» pesign --hash --in ./tests/shared/HelloWorld.efi
./tests/shared/HelloWorld.efi 765600a03f44d9f954376dd5f4e5b5e86b2ca1a3d6308a005f95922b0ebe7c94

λ go-uefi master» /home/fox/Git/prosjekter/C/sbsigntools/src/sbsign --hash-only ./tests/shared/HelloWorld.efi
warning: data remaining[44032 vs 53174]: gaps between PE/COFF sections?
warning: data remaining[44032 vs 53176]: gaps between PE/COFF sections?
765600a03f44d9f954376dd5f4e5b5e86b2ca1a3d6308a005f95922b0ebe7c94

So this is confusing and needs more work I reckon. I need to figure out where in edk2 they add the alignment....

EDIT:

sbsigntools commit: https://github.com/osresearch/sbsigntools/commit/592ec2188f7b9cf003fe7cb0835e93559f19156f

Foxboron commented 3 years ago

I wonder if this makes the measurements in the TPM eventlog useless actually. If they are aligned we can't use them in the db variable.....

Foxboron commented 3 years ago

If you add signatures to the file then sbsigntools gives you the correct checksum, while pesign still fails.

# Add two signatures to the example file
λ go-uefi master» go run cmd/gosign/main.go -key ./tests/ovmf/keys/db/db.key -cert ./tests/ovmf/keys/db/db.pem ./HelloWorld.efi ./HelloWorld.efi
λ go-uefi master» go run cmd/gosign/main.go -key ./tests/ovmf/keys/KEK/KEK.key -cert ./tests/ovmf/keys/KEK/KEK.pem ./HelloWorld.efi ./HelloWorld.efi

λ go-uefi master» go run ./cmd/gochecksum/main.go ./HelloWorld.efi
d2ae1f36ec9b40b55f60920a3f58ec902ebdc7c323e443412c751cdb3c42d3f3%

λ go-uefi master» pesign --hash --in ./HelloWorld.efi
./HelloWorld.efi 765600a03f44d9f954376dd5f4e5b5e86b2ca1a3d6308a005f95922b0ebe7c94                                                                                                                                                                                                                 

λ go-uefi master» /home/fox/Git/prosjekter/C/sbsigntools/src/sbsign --hash-only ./HelloWorld.efi
warning: data remaining[48264 vs 57406]: gaps between PE/COFF sections?
d2ae1f36ec9b40b55f60920a3f58ec902ebdc7c323e443412c751cdb3c42d3f3
Foxboron commented 3 years ago

I have gotten eventlogs from the Lenovo T14 and T14s :) They load 7 and 11 OpROMs during boot respectively.

https://pub.linderud.dev/secureboot/eventlogs/

orangecms commented 3 years ago

Here is my log from a T14, parsed by tpmtool with a little hack to get it to "work" with TPM 2.0: https://github.com/orangecms/utk-web/blob/wasm-tpm/src/TPM/t14-tpm20.json

it has 7 EV_EFI_BOOT_SERVICES_DRIVER entries :+1:

savchenko commented 3 years ago

I have gotten eventlogs from the Lenovo T14 and T14s :)

I have T14g2 (Tiger Lake) if that is of any use for the project.

Foxboron commented 3 years ago

Seems like someone on reddit got this to work using the TPM eventlog.

https://www.reddit.com/r/linuxquestions/comments/pi1daj/secure_boot_how_to_extract_nvidia_uefi_boot/hbq49ft/?context=3

ansemjo commented 3 years ago

I've been reading up on FDE and SecureBoot again in the last couple days and hit this thread. I am currently running a Lenovo ThinkPad P14s Gen 2 (AMD) with enabled SecureBoot using my own keys to sign my kernel bundle. However, I just checked and I have not removed any of the Microsoft or Lenovo keys. This was partly because I've read notices in the Arch wiki and multiple reddit threads with warnings for similar (earlier) models and was cautious because I really didn't want to brick my device. So .. was I just lucky?

Dump of my current PK, KEK and db ``` ~ $ efi-readvar -v PK Variable PK, length 911 PK: List 0, type X509 Signature 0, size 883, owner 3190042b-7bf6-40c2-b502-c0b57fd9301b Subject: O=Anton Semjonov, OU=Secureboot Keys, CN=anrz.de PlatformKey Issuer: O=Anton Semjonov, OU=Secureboot Keys, CN=anrz.de PlatformKey ~ $ efi-readvar -v KEK Variable KEK, length 3595 KEK: List 0, type X509 Signature 0, size 1043, owner 7facc7b6-127f-4e9c-9c5d-080f98994345 Subject: C=CN, ST=Beijing, L=Beijing, O=Lenovo(Beijing)Ltd, OU=CCD, CN=swqagent, emailAddress=swqagent@lenovo.com Issuer: C=CN, ST=Beijing, L=Beijing, O=Lenovo(Beijing) Ltd, OU=CCD, CN=swqagent, emailAddress=swqagent@lenovo.com KEK: List 1, type X509 Signature 0, size 1532, owner 77fa9abd-0359-4d32-bd60-28f4e78f784b Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft Corporation KEK CA 2011 Issuer: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft Corporation Third Party Marketplace Root KEK: List 2, type X509 Signature 0, size 936, owner 3190042b-7bf6-40c2-b502-c0b57fd9301b Subject: O=Anton Semjonov, OU=Secureboot Keys, CN=anrz.de KeyExchangeKey Issuer: O=Anton Semjonov, OU=Secureboot Keys, CN=anrz.de PlatformKey ~ $ efi-readvar -v db Variable db, length 7116 db: List 0, type X509 Signature 0, size 962, owner 7facc7b6-127f-4e9c-9c5d-080f98994345 Subject: C=JP, ST=Kanagawa, L=Yokohama, O=Lenovo Ltd., CN=ThinkPad Product CA 2012 Issuer: C=JP, ST=Kanagawa, L=Yokohama, O=Lenovo Ltd., CN=Lenovo Ltd. Root CA 2012 db: List 1, type X509 Signature 0, size 1043, owner 7facc7b6-127f-4e9c-9c5d-080f98994345 Subject: C=CN, ST=Beijing, L=Beijing, O=Lenovo(Beijing)Ltd, OU=CCD, CN=swqagent, emailAddress=swqagent@lenovo.com Issuer: C=CN, ST=Beijing, L=Beijing, O=Lenovo(Beijing) Ltd, OU=CCD, CN=swqagent, emailAddress=swqagent@lenovo.com db: List 2, type X509 Signature 0, size 919, owner 7facc7b6-127f-4e9c-9c5d-080f98994345 Subject: C=US, ST=North Carolina, O=Lenovo, CN=Lenovo UEFI CA 2014 Issuer: C=US, ST=North Carolina, O=Lenovo, CN=Lenovo UEFI CA 2014 db: List 3, type X509 Signature 0, size 1572, owner 77fa9abd-0359-4d32-bd60-28f4e78f784b Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft Corporation UEFI CA 2011 Issuer: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft Corporation Third Party Marketplace Root db: List 4, type X509 Signature 0, size 1515, owner 77fa9abd-0359-4d32-bd60-28f4e78f784b Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft Windows Production PCA 2011 Issuer: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft Root Certificate Authority 2010 db: List 5, type X509 Signature 0, size 937, owner 3190042b-7bf6-40c2-b502-c0b57fd9301b Subject: O=Anton Semjonov, OU=Secureboot Keys, CN=anrz.de DatabaseKey Issuer: O=Anton Semjonov, OU=Secureboot Keys, CN=anrz.de KeyExchangeKey ```

I don't have a discrete graphics card in my laptop and thanks to this thread I found how I can extract and look at the eventlog.

1) Now, how could one make sure that they don't brick their device if they were to remove the aforementioned keys from KEK and db?
2) Alternatively, which of these digests absolutely need to be resigned and added to db?
3) What about firmware updates? Would one need to disable secureboot, apply the update and recheck for new digests each time?

The reddit thread you just linked only deals with EV_EFI_BOOT_SERVICES_DRIVER logs – but I have none of those. Does that mean I am in the clear? (Attached my eventlog_lenovo_p14s_g2_amd_ansemjo.gz)

List of EventTypes in my eventlog ``` EV_EFI_ACTION EV_EFI_BOOT_SERVICES_APPLICATION EV_EFI_GPT_EVENT EV_EFI_HANDOFF_TABLES EV_EFI_PLATFORM_FIRMWARE_BLOB EV_EFI_VARIABLE_AUTHORITY EV_EFI_VARIABLE_BOOT EV_EFI_VARIABLE_DRIVER_CONFIG EV_IPL EV_NO_ACTION EV_POST_CODE EV_S_CRTM_VERSION EV_SEPARATOR ```

I don't mean to burden anyone here and I understand that this discussion has moved a bit from the initial issue. But I am hoping that this concrete situation might help me and others to understand how to check for possible bricking "traps" and safely move forward in the future?

Foxboron commented 3 years ago

The reddit thread you just linked only deals with EV_EFI_BOOT_SERVICES_DRIVER logs – but I have none of those. Does that mean I am in the clear?

Yes, it means you do not have oprom in your boot chain.

klausenbusk commented 3 years ago

AuditMode==1 and EFI_IMAGE_EXECUTION_INFO_TABLE is also worth mentioning as a way to avoid bricking systems:

When AuditMode==1, an EFI_IMAGE_EXECUTION_INFO element is created in the EFI_IMAGE_EXECUTION_INFO_TABLE for every certificate found in the certificate table of every image that is validated.

Additionally for every image, an element will be created in the table for every EFI_CERT_SHAXXX that is supported by the platform. The contents of Action for each element are determined by comparing that specific element’s Signature (which will contain exactly 1 EFI_SIGNATURE_DATA) to the currently- configured image security databases and policies, and shall be either EFI_IMAGE_EXECUTION_AUTH_SIG_PASSED, EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED, or EFI_IMAGE_EXECUTION_POLICY_FAILED.

Finally, because the system is in Audit Mode, all modules are initialized even if they fail to authenticate, and the EFI_IMAGE_EXECUTION_INITIALIZED bit shall be set in Action for all elements.

UEFI Specification Version 2.9 (March 2021) - page 1706

BxOxSxS commented 3 years ago

Most are talking about laptops but on my custom build pc I have successful added hashes from tpm log to db using instructions from reddit link above and secure boot is working on fully custom key. I have ASUS TUF B450-PLUS GAMING II motherboard, AMD Radeon RX 6600 XT and samsung NVMe 980 drive (Im not sure if secure boot is validing nvme drive). I had to add 3 hashes.

I have done it successful at the first time using sbkeysync and then I wanted to "migrate" to sbctl but I did something wrong with db hashes (btw I still cannot figure out how sbctl is managing custom db enteries) and motherboard's POST failed.

I almost had hearth attack but thanks to my motherboard that it let me enable csm and boot pc. I enrolled old db and everything is working fine.

My dump of PK, KEK and DB ``` [boss@BxOxSxS ~]$ efi-readvar -v PK Variable PK, length 1359 PK: List 0, type X509 Signature 0, size 1331, owner f6a690a8-cd1e-4a00-84d0-11a124abc1d3 Subject: CN=B.O.S.S Platform Key Issuer: CN=B.O.S.S Platform Key [boss@BxOxSxS ~]$ efi-readvar -v KEK Variable KEK, length 1367 KEK: List 0, type X509 Signature 0, size 1339, owner f6a690a8-cd1e-4a00-84d0-11a124abc1d3 Subject: CN=B.O.S.S Key Exchange Key Issuer: CN=B.O.S.S Key Exchange Key [boss@BxOxSxS ~]$ efi-readvar -v db Variable db, length 1607 db: List 0, type X509 Signature 0, size 1351, owner f6a690a8-cd1e-4a00-84d0-11a124abc1d3 Subject: CN=B.O.S.S Signature Database key Issuer: CN=B.O.S.S Signature Database key db: List 1, type SHA256 Signature 0, size 48, owner 00000000-0000-0000-0000-000000000000 Hash:abe4ae8c658c5630b575bd7db08605112a74ca486271dc4ba36a7f3b2771a9fa db: List 2, type SHA256 Signature 0, size 48, owner 00000000-0000-0000-0000-000000000000 Hash:4da9ca68f5b4ce8154b34a229bfd071e67deb81532c855795515cf41be366aaa db: List 3, type SHA256 Signature 0, size 48, owner 00000000-0000-0000-0000-000000000000 Hash:804c5b158e3f5edf15df4c72bdfe9afedb68a7753eec5b035fd32cca6a201769 ```
Output of bootctl status ``` System: Firmware: UEFI 2.70 (American Megatrends 5.17) Secure Boot: enabled Setup Mode: user TPM2 Support: yes 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 Stub: systemd-stub 249.4-1-arch ESP: /dev/disk/by-partuuid/40b40e3d-680d-4cb8-9275-7cb102b9e5a3 File: └─/EFI/Arch/linux-signed.efi Random Seed: Passed to OS: no System Token: not set Exists: no Available Boot Loaders on ESP: ESP: /boot/efi (/dev/disk/by-partuuid/40b40e3d-680d-4cb8-9275-7cb102b9e5a3) Boot Loaders Listed in EFI Variables: Title: rEFInd Boot Manager ID: 0x0002 Status: active, boot-order Partition: /dev/disk/by-partuuid/40b40e3d-680d-4cb8-9275-7cb102b9e5a3 File: └─/EFI/REFIND/REFIND_X64.EFI Title: Windows Boot Manager ID: 0x0000 Status: active, boot-order Partition: /dev/disk/by-partuuid/40b40e3d-680d-4cb8-9275-7cb102b9e5a3 File: └─/EFI/MICROSOFT/BOOT/BOOTMGFW.EFI Boot Loader Entries: $BOOT: /boot/efi (/dev/disk/by-partuuid/40b40e3d-680d-4cb8-9275-7cb102b9e5a3) 0 entries, no entry could be determined as default. ```
Foxboron commented 3 years ago

btw I still cannot figure out how sbctl is managing custom db enteries

It doesn't, currently.

Ferdi265 commented 9 months ago

Just to add a small point to the discussion:

(Disclaimer: I have not read much into secure boot, the following might be a terrible idea)

I noticed that after running sbctl create-keys, one can use the generated db.pem, convert it to DER format with openssl, and enroll it in MokManager / mokutil as a MOK key and after that sbctl works completely fine on a system with shim.

Granted, sbctl status and sbctl verify won't be all green, but the system will be able to boot off of shim, and any later stages can be easily signed with sbctl sign or registered for automatic signing with sbctl sign-all.

If what I propose here is cryptographically sound, then integrating that more nicely in sbctl wouldn't even be that complex, and the added convenience that sbctl brings over doing it manually is definitely worth a shot.

If this project is not interested in doing that I will potentially set up and maintain a fork that does add it, since I don't think it will be very hard to do.

Foxboron commented 9 months ago

Personally I would probably make a new MOK key and enroll this. It's not hard to implement but sbctl figuring out when you are using MOK and not is the probably the harder part of the problem.

If you want to implement this feel free to take a stab at it. I'd be happy to review the code.

Foxboron commented 9 months ago

Thinking it through, there are several MOK variables that should be present when shim is in the bootloader so figuring out when to use the given mode is probably not very hard. So all that is needed to be done is to enroll a new key into MOKList (which is 1:1 with db enrollment), and then either implement the kernel module signing by shelling out to the binary, or better, implement the support in sbctl.