MinnowBoard-org / bugs-and-help

Ask QUESTIONS here. MinnowBoard.org issue and get help submission. See README for use.
14 stars 2 forks source link

TPM2 on Minnowboard's bootloader #29

Closed gogo9th closed 7 years ago

gogo9th commented 7 years ago

Hi,

I need to use TPM 2.0 from the bootloader on Minnowboard in order to hash the Linux kernel's image and extend it to the PCR register. Unfortunately, TrustedGRUB2 only supports TPM 1.2, and I couldn't find any open source bootloader that supports TPM 2.0. So I think I have to implement it into the GRUB2 bootloader. However, I couldn't find any information on how to use the TPM 2.0 service by using an assembly interrupt routine for Intel x86 chips. Do you have any information on this? In particular, it would be more than great if I could find some assembly and C source code on how to use TPM2 in BIOS and/or UEFI firmware mode, with an exemplary tutorial.

zwei4 commented 7 years ago

Below white paper gives detailed information about UEFI TPM2: https://firmware.intel.com/sites/default/files/resources/A_Tour_Beyond_BIOS_Implementing_TPM2_Support_in_EDKII.pdf

zwei4 commented 7 years ago

The sample code could be downloaded from devel-Minnoboard3 branch of repository https://github.com/tianocore/edk2-platforms.git

gogo9th commented 7 years ago

Hi David,

Thanks so much for the white paper and preparing the UEFI source code. I really appreciate it.

a) What I was looking for was to implement a bootloader that supports TPM2. I think EDKII will measure the first sector of GRUB2 bootloader, but won't measure the remaining sectors of the bootloader and the kernel image. It's the bootloader's responsibility to measure the kernel image. In EDKII's source code, there is a code section for TPM2 commands. I wonder if simply copying this portion of code into GRUB2 bootloader's source code would enable GRUB2 to access and use TPM2.

b) If our goal was simply to use a UEFI that supports TPM2, would Intel's latest Minnowboard firmware also work: https://firmware.intel.com/projects/minnowboard-max It's because this article (https://prosauce.org/blog/2016/1/11/minnowboard-max-enable-and-test-the-firmware-txe-tpm-20) says Intel's firmware supports TPM2.

c) To use fTPM in Minnowboard, is it right that we go into UEFI setting, turn "PTT" to enable mode, turn "Measured Boot" to enable mode and turn "discrete TPM" to disable mode?

zwei4 commented 7 years ago

Are you booting 64bit or 32bit OS loader on MinnowBoard Max?

If you are working on 32bit, then the answers are all "yes".

But if you are working on 64bit, you need to follow below instructions in the UEFI firmware release note. https://firmware.intel.com/sites/default/files/MinnowBoard_MAX-Rel_0_94-ReleaseNotes.txt

  1. How to enable fTPM feature.
    1) Enable fTPM feature for IA32 firmware Please follow these steps as below to turn on fTPM option in setup page: i) Boot to uefi setup page ii) Run into the option "Device Manager" -> "System Setup" -> "Security Configuration" -> "PTT", setup the option from "Disable" to "Enable". iii) Save the setup option changes then reboot system.

    2) Enable fTPM feature for X64 firmware Since the default build macro of fTPM is FALSE, need to turn on the fTPM build macro then rebuild X64 firmware. i) Open MyWorkspace/Vlv2TbltDevicePkg/PlatformPkgX64.dsc ii) Modified the following macro from "FALSE" to "TRUE" then rebuild X64 firmware. DEFINE SEC_ENABLE = TRUE DEFINE SEC_DEBUG_INFO_ENABLE = TRUE DEFINE FTPM_ENABLE = TRUE After updating the new X64 firmware, still need to follow these setups as below to turn on fTPM option in setup pages. i) Boot to uefi setup page. ii) Run into the option "Device Manager" -> "System Setup" -> "Security Configuration" -> "PTT", setup the option from "Disable" to "Enable". iii) Save the setup option changes then reboot system.

flihp commented 7 years ago

@gogo9th: There have been a few interesting efforts on this front. In a past life I spent a bunch of time implementing extensions to Grub2 that used the TPM2 / TrEE UEFI protocol to extend various components into the proper PCRs. I also spent a pile of time playing around with mechanisms to persist the pre-boot event log for use by the OSS post-bootloader. My patches are pretty stale at this point since I had to drop my work to pickup a different project but they're available if you want something to read:

Matthew Garrett has done similar work but he's continued to support his patches and is currently working to upstream them into Grub2 directly.

I'd recommend pulling Matthew's patches from the Grub2 mailing list and taking them for a spin.

gogo9th commented 7 years ago

David, thanks very much for you extra note for TPM2 UEFI. This works out well. Thanks again.

Phillip, thanks for the link for the URL for your grub and Matthew's. In fact, I already tried Matthew's, but for some reason it doesn't measure PCR 10~14. I am not sure why. The error message is "error: no symbol table", but I don't know if this is the cause of the problem of not measuring the PCRs above.. Does this GRUB2 work on your computer by any chance..?

flihp commented 7 years ago

I tested Matthew's patches ~6 months ago. At the time they worked though only on 64bit UEFI firmware, not 32bit. To submit these patches upstream he's likely rebased them on the current HEAD of the Grub2 development branch. The changes involved however should be limited to structural things, not functional stuff (like PCR usage etc).

gogo9th commented 7 years ago

Hi Philip,

It's weird because my UEFI is 64 bit, and still doesn't work. Maybe I should try it on a different computer.

By the way, I have one question on using WiFi on Minnowboard. I couldn't find a good tutorial on this so far. I installed wicd-curses and plugged in a WiFi dongle, but it still doesn't work. Could you recommend me some good WiFi driver or application I can install on Ubuntu for Minnowboard, if you know any?

gogo9th commented 7 years ago

Hi Phillip,

Today I looked into the source code of Matthew's GRUB2-TPM2 and finally realized it's actually working, but extends the kernel image and initrd into PCR 9, instead of PCR 10~14. In his blog, he said these values will be extended to PCR 10~14, which is different from his actual implementation.

Here I manually created grub_printf() logs of all PCR extension events occuring upon booting.

GRUB2 TPM2 Screenshot: http://bigmail.mail.daum.net/Mail-bin/bigfile_down?uid=3CTYs-xo5EfJy9-Ui8oDlgp-zJRm9skt

[execute.c] log is for extending GRUB2's executed commands. [dl.c] log is for extending .mod module files loaded. [i386/linux.c] log is for extending Linux kernel file loaded. [linux.c] log is for extending Initrd RAM disk loaded.

For log parameters,

By the way, do you have any good idea as to how to install and run WiFi on Minnowboard...?

ghost commented 7 years ago

Hi,

To enable WifFi you need a mPCIe add-on card, such as the SilverJaw lure: http://wiki.minnowboard.org/Silverjaw_Lure

A quick search for mPCIe WiFi cards that are well supported by Linux shows the following devices. http://www.htpcbeginner.com/5-linux-compatible-wifi-cards-mini-pcie-2012/

Hope this helps :)

flihp commented 7 years ago

@gogo9th : Glad to hear you're getting results and that Matthew's patches are using the right PCRs now :)

I've never used WiFi on my MBM, but for my RaspberryPI I've used the WiPi with good results. Might be a cheaper alternative to the full Lure + mPCIe card but YMMV.

gogo9th commented 7 years ago

Oh, thanks for letting me know that there's actually GRUB-TPM2 patches.

As for WiFi, I'll try Wi-Pi first and if it doesn't work I will buy Lure + mPCIe, test and let you guys know. Thanks again!

gogo9th commented 7 years ago

WiFi dongles work out of box on Minnowboard. It was that my first WiFi dongle was defective.

But I have a problem with using TPM on Minnowboard. I closely followed the instruction at: https://firmware.intel.com/sites/default/files/MinnowBoard_MAX-Rel_0_94-ReleaseNotes.txt In PlatformPkgX64.dsc file, I set the parameters: DEFINE SEC_ENABLE = TRUE DEFINE SEC_DEBUG_INFO_ENABLE = TRUE DEFINE FTPM_ENABLE = TRUE And I flashed it on Minnowboard, installed Lubuntu, and ran "acpidump -s | grep TPM". But I don't get any TPM-related results. I don't understand why.

One possible reason is, I cloned: "git clone https://github.com/tianocore/edk2-platforms.git -b minnowboard-max-udk2015", instead of downloading devel-Minnoboard3 branch. But would this really cause a problem?

Another possibility is, "PlatformPkgGccX64.dsc" file has DEFINE SEC_ENABLE = FALSE DEFINE SEC_DEBUG_INFO_ENABLE = FALSE DEFINE FTPM_ENABLE = FALSE But the release note didn't say that we should set above values to TRUE. And doing so causes a compilation error.

zwei4 commented 7 years ago

If you are compiling with GCC, you have to change those macros in PlatformPkgGccX64.dsc .

"PlatformPkgGccX64.dsc" file has DEFINE SEC_ENABLE = TRUE DEFINE SEC_DEBUG_INFO_ENABLE = TRUE DEFINE FTPM_ENABLE = TRUE

We will check if there is any issue with the GCC compiling.

gogo9th commented 7 years ago

I fixed the compilation bug. In file PlatformPkgGccX64.dsc, we need to make the following changes:

Note that "\" has to be changed to "/".

gogo9th commented 7 years ago

I flahsed the TPM-enabled UEFI, installed Lubuntu 16.04 (Linux 4.4), and typed

$ sudo apt install acpidump -y && sudo acpidump -s | TPM ACPI: TPM2 0x0000000000000000 000034 (v03 00000000 00000000)

$ sudo acpidump -s | Tpm ACPI: SSDT 0x0000000000000000 00043A (v01 Intel_ Tpm2Tabl 00001000 INTL 20120518)

Now ACPI detects TPM. However, /dev/tpm0 is not created. I investigated dmesg, and I get the following TPM-related erronous logs:

[ 7.405216] shpchp: Standard Hot Plug PCI Controller Driver version: 0.4 [ 7.418903] ACPI Error: [TPME] Namespace lookup failure, AE_NOT_FOUND (20150930/psargs-359) [ 7.418921] ACPI Error: Method parse/execution failed [_SB.TPM._STA] (Node ffff8800770b95f0), AE_NOT_FOUND (20150930/psparse-542) [ 7.442785] ACPI Error: [TPME] Namespace lookup failure, AE_NOT_FOUND (20150930/psargs-359) [ 7.442803] ACPI Error: Method parse/execution failed [_SB.TPM._STA] (Node ffff8800770b95f0), AE_NOT_FOUND (20150930/psparse-542) [ 7.509919] dw_dmac INTL9C60:00: DesignWare DMA Controller, 8 channels [ 7.514002] dw_dmac INTL9C60:01: DesignWare DMA Controller, 8 channels [ 7.524011] tpm tpm0: invalid command count value b 0 [ 7.524023] tpm_crb MSFT0101:00: tpm_transmit: tpm_send: error -7 [ 7.524044] tpm_crb: probe of MSFT0101:00 failed with error -7

It says TPME namespace lookup failed. I am not sure what's the cause of this problem... Does yours work?

gogo9th commented 7 years ago

I erased the entire folder, re-did the patching on the newly cloned "minnowboard-max-udk2015" branch and now I get /dev/tpm0 node. I think I messed up something accidentally. So I think you only need to modify "Library\" to "Library/" in PlatformPkgGccX64.dsc file. Here's my patched stable UEFI source code with TPM enabled: http://bigmail.mail.daum.net/Mail-bin/bigfile_down?uid=8-rP1SAJQ8EU-EdAX7H8OpZss6Y2Iwwt. You only need to run:

$ cd Vlv2TbltDevicePkg && . Build_IFWI.sh MNW2 Release

I tested Tiancore UEFI + Matthew's GRUB2-TPM2 + Ken's IBM-TPM toolkit on Minnowboard, and everything works perfectly. I really appreciate you guys' kind support!

zwei4 commented 7 years ago

Congratulations! We will integrate your patch.

ghost commented 7 years ago

@gogo9th would you be interested in writing a Blog/HOWTO about the work you did?

gogo9th commented 7 years ago

That's a great idea. In fact, I'm trying to port IBM TPM's pcrread into exec() to fully track all binaries being loaded on Linux, and also port it into kmod program to track all modules being loaded.

I will hopefully try to include this part as well to make it complete.

Ronny

ghost commented 7 years ago

Sounds good! If you could send me an email, I can tell you what I had in mind how such a blog could be used most effectively :)

gogo9th commented 7 years ago

Sure, I'm happy to send it to you. But for now i'm little stuck with integrating Matthew's GRUB2' UEFI-TPM service functions into Linux kernel's source code. While running my kernel, EFI system table structure seems to contain invalid entries. One reason might be that I installed a 32-bit kernel on a 64-bit machine (but maybe not). I hope to get this done soon and wrap things up.

ghost commented 7 years ago

No worries. There is no rush :)

gogo9th commented 7 years ago

I'm finally trying to add TPM's PCR extension routine inside exec() and modprobe() calls, to fully monitor and verify every binary being run on our machine/device. IBM-TPM depends on several user-space libraries, so I tried to port Matthew's GRUB2's source code snippet performing TPM register measurement. But I've been stuck for 40 hours straight, because I'm not familiar with UEFI programming inside the kernel source code.

Linux source code says that we must access UEFI services via elf_system_table structure defined in "efi.h" file. This table should be automatically filled out by the kernel during initialization inside "efi.c" file's efi_systab_init() function. However, I debugged and realized that the some of the second-level table entries are invalid and makes the kernel panick. For example, to make a TPM measurement request like Matthew's GRUB2 does, I need to access efi->system_table->boottime->locate_handle() function pointer. But boottime points at an invalid memory address and thus the kernel crashes when I try to access locate_handle().

Am I totally on a wrong track for using UEFI services? Does anybody know how we should implement using UEFI services within the kernel's source code?

ghost commented 7 years ago

@flihp do you have an idea? Thanks.

gogo9th commented 7 years ago

Last night I just figured out the problem. The reason was that the bootloader didn't fully pass the "boottime" member variable within the EFI system table structure to the kernel for some reason (null pointer), which should contain TPM service handlers.

Instead of using UEFI's EFI table directly for TPM services, I realized it is actually more convenient to use Linux kernel's TPM driver (drivers/char/tpm/tpm.h). But for some reason, TPM driver didn't work until a certain point in time after the system booted. After debugging, I realized The TPM driver got started working after "crb_acpi_driver" got loaded, which turns out to be the TPM driver. This driver was compiled as dynamic module instead of an embedded source code into the Kernel image. So I statically embedded this driver into Linux image, by doing:

make menuconfig -> Device Drivers-> Character Device -> TPM Hardware Support -> TPM 2.0 CRB Interface <> # M means modulize the code, means hard-code the code into the kernel image. make -j4

Now the TPM works okay for every launched binary. Acutally, it would be recommended to set all TPM drivers under "Device Drivers-> Character Device -> TPM Hardware Support" to <*>, just in case.

Now I'm debugging reading in binary files within the kernel mode, which is to be TPM-measured. I'll keep you posted.

ghost commented 7 years ago

Sounds good 👍

13pools commented 7 years ago

I'm finally trying to add TPM's PCR extension routine inside exec() and modprobe() calls, to fully monitor and verify every binary being run on our machine/device.

@gogo9th Have you looked into the integrity subsystem at all? Sounds pretty similar to what you're describing.

ghost commented 7 years ago

Hi @gogo9th, how is it going with your secure boot enabling efforts? Just checking :)

gogo9th commented 7 years ago

Hi @13pools

I'm sorry, your reply message didn't get to my email 2 weeks ago and I just checked it as @uhofemei wrote me a new message.

Yes, you are absolutely right. I fully implemented the integrity checking system manually and after that I found out about IMA you linked to. Basically, in order to turn on IMA's integrity measurement for all binaries & modules & dynamic libraries & shell scripts, we only need to do the following:

  1. Boot the computer
  2. In the GRUB menu, move the cursor to the kernel image you'll load
  3. Press 'e'
  4. Move the cursor at the end of the line starting with "linux" (or "kernel") keyword
  5. Add the string [ima_tcb] at the end of this line as an extra argument to Linux kernel image.
  6. Press F10 to load the kernel.

But I found one security hole in IMA. It re-measures all binaries whenever they are modified or re-compiled and launched. But it doesn't do the same for shell script files. This can be exploited by an attacker.

Yesterday I finished implementing server-client TPM remote attestation. But apparently, about 2 weeks ago this part has been also released by IBM: https://sourceforge.net/projects/ibmtpm20acs/

I was to start writing a brief summary tutorial this week, but suddenly I got engaged into SOSP conference paper writing work and its deadline is this Friday night. Sorry for the delay, but right after submitting the paper I'll get back to this.

Meanwhile, as the next project I think of running XEN on Minnowboard. It seems that there isn't an official success on this yet:

https://lists.xen.org/archives/html/xen-users/2015-10/msg00181.html

Has anyone have an idea? It'll be nice if we can use UEFI's fTPM with XEN on Minnowboard.

ghost commented 7 years ago

Hi @gogo9th could you please send me an email? Thanks :)

gogo9th commented 7 years ago

Hi guys, I have a problem of Minnowboard... My two Minnoboards' USB ports permanently died. One happened when I was unplugging and replugging in a small USB 2.0 Hub, while I was running iperf3 network bandwidth program. The other happened when I was unplugging and replugging in a keyboard USB cable to one port, while I was installing Ubuntu kernel. I was powering Minnowboard with 2V, 5A USB charger by using a DC cable. Both happened on the same day, and I don't have anymore Minnowboard.. Does anyone know why this happened?

BrianOttaway commented 7 years ago

@gogo9th : It has been a while. Is this issue still active? Your power supply info can't be correct (2V 5A)...yet, even if you had those numbers reversed (5V 2A) the 2A amperage is quite low and upderpowering the board. With that kind of power supply I wouldn't be surprised with any type of crazy behavior from an under load board. As the amps spike upward and demand more from the limited power supply you could be seeing voltage drops and really the whole boards power delivery could be in question. @gogo9th: are you sure you didn't fry the board with overvoltage?

gogo9th commented 7 years ago

Hi, yes I agree that your guess could be correct. I finally ended up replacing my board with a new version of Minnowboard (square one instead of rectangular) and this problem does not happen anymore, even if I have been using the same 5V 2A power supply. I suppose the old version of the board is somehow problematic...

BrianOttaway commented 7 years ago

Good to hear you are up and running on the dual-e. Do note, however, that a 2 amp power supply is way under-powered and brings with it a life of pain and mystery. :) Seriously, a workload could work one time, but not when the heat is on in winter, or boot sometimes and other times reset loop. I can boot a Turbot with a USB wall adapter and USB-to-barrel cable, but I wouldn't trust it to handle any real application without serious testing.

Best wishes. closing this thread for now. Have a good day.