Category Archives: Linux

Disabling Secure Boot on Intel Quark “secure SKU” silicon

Secure Boot is a bit like SELinux: people who use it really like it, and tell all their friends to use it. For everyone else, apart from those who don’t know about or even notice Secure Boot, it’s an annoyance that they almost immediately disable.

We’ve looked at the Intel DK200 from a hardware perspective before. Now it’s time to look at it from a software perspective. “Internet of Things Gateway” is pretty generic, so what can it actually do?

Following the instructions, I tried to register the system on Intel’s website so I could download the Wind River Intelligent Device Platform XT 2.0 SDK. I didn’t get very far:

No WindRiver SDK for you

Stormtrooper #1: This is not the product you’re looking for

Yeah… I guess this is what Mouser meant when they said the DK200 was End of Life.

Since this ships with the Linux Kernel, which is GPLv2 licensed, I believe Intel may be violating the GPL. Specifically:

Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange

But I am not a lawyer, and I am not really that interested in starting a legal battle over the source code for an ancient version of Wind River Linux I am not interested in using anyway.

So let’s go try to build Yocto. The Intel rep did say there was a Yocto BSP coming “soon” but “soon” in Intel time seems kind of variable.

After some hiccups (Yocto needs python2 and GCC <6) I had built a Yocto image and put it on an SD card. Does it boot?

...no

…no

So we can’t boot Yocto because this is a “secure SKU” which means Secure Boot is enabled. Is there some way we can disable Secure Boot? What about updating the BSP to a newer version with Secure Boot disabled?

Back to hardware
If I’ve learned anything from messing around with electronics, you want to make a backup before you start modifying things. This is doubly so if the data in question is related to the booting process. It sucks to end up with a brick, so make a backup!

Taking a backup of flash

Taking a backup of flash

The Intel Quark guide mentions using a Dediprog SF100 to flash EDKII. I don’t have a Dediprog, but I do have an SPI programmer. Unfortunately, none of the Intel documentation I could find mentions the Dediprog header on the DK200, so I had to go hunting.

I traced the pins from the Winbond flash to header J23. J23 is only 8 pins, so trial and error with a multimeter to find the pin mapping wasn’t terrible:

J23 pinout

J23 pinout

Here’s the pinout of J23 in text form:

J23 pin 25Q64 pin Pin description
1 8 VCC
2 4 GND
3 1 /CS
4 6 CLK
5 2 DO
6 5 DI
7 Not connected
8 Not connected

/WP and HOLD pins on the 25Q64FV are not routed to J23, but they aren’t required for flashing.

With the pinout known, I could attach the SPI programmer to the header instead of using the chip clip:

J23 to ch341a SPI programmer

J23 to ch341a SPI programmer

I took a dump of the Winbond 25Q64FV and then for good measure desoldered the chip and read it again to confirm the images were exactly the same. It was strange because the image from the chip clip wasn’t identical. But, the image from the desoldered chip was identical to the image taken from J23, so we’re done here. I wrote the image to a new 25Q64FV and soldered that back onto the board.

Firmware disassembly
Disassembling the firmware which shipped on my DK200, we see that a Secure Boot certificate was created by WindRiver.

I assume that had I been able to download the WindRiver SDK, I would have been able to build and sign Secure Boot with my own certificates. Given that industrial customers spend a lot of time and money worrying about security, I was surprised to see that the Secure Boot certificate in the firmware was created by WindRiver China.

I did try to load up the image in IDA, but not being a power user of IDA, I couldn’t figure out how to get it to analyze the SPI dump, and gave up to try and compile the firmware from source.

Building the BSP

Being Intel, there are hundreds of pages you can read about developing for EDK2 and other really fun things, probably. I didn’t read them.

A document which I did end up reading religiously was the Intel ® QuarkTM SoC X1000 Board Support Package (BSP) Build and Software User Guide [PDF] which describes how to build all the firmware components needed to bring up the X1000 SoC. I found out there is actually a newer version of this document (1.2.1 instead of 1.1) and there are some important differences between the documents I want to get to later.

By building the firmware, we’re hoping for one of two outcomes:

  1. A firmware with our own Secure Boot certificates, or
  2. A firmware which has Secure Boot disabled

Version 1.1 of the BSP Build and Software User Guide includes a section on pages 29 and 30 on how to bundle your own db, kek, and pk certificates:

Page 29 and 30 condensed

Unfortunately if you follow the instructions and try to use a layout.conf which specifies these files, you’ll get an error because there’s no address specified for this data in the image:

I do have a reference file from WindRiver with Secure Boot certificates, so if I was really interested in making Secure Boot work as intended, I could have reverse engineered the address to store the certificates.

The certificates section of layout.conf was removed from the 1.2.1 revision of the BSP Build and Software User Guide. I guess since it no longer works, Intel decided to remove it from the documentation.

So, we can’t install our own Secure Boot certificates in the firmware. What happens if we just leave out the certificates section entirely and build it?

Error 37: Quark signature file not found

Right, so even though there’s now no certificate in the firmware bundle, we still can’t boot.

Interestingly, if you don’t partition the uSD or USB stick correctly, you end up with this pretty screen:

I never saw that in the stock firmware.

Hacking GRUB
So it seems that we can’t include our own Secure Boot certificate in the firmware, due to the sample layout.conf file missing the certificates section, and not knowing the appropriate address to store the certificates.

What if we dig into Error 37: Quark signature file not found a bit more?

If you look in the grub source code included in the BSP, you can see a giant ~1000KB patch that Intel has made to the original upstream code to support the Quark platform.

If you grep for “Quark signature file not found” you’ll find it was added in stage2/common.c:
diff --git a/stage2/common.c b/stage2/common.c
index e96bec2..e122745 100644
--- a/stage2/common.c
+++ b/stage2/common.c
@@ -88,6 +88,8 @@ char *err_list[] =
[ERR_UNRECOGNIZED] = "Unrecognized command",
[ERR_WONT_FIT] = "Selected item cannot fit into memory",
[ERR_WRITE] = "Disk write error",
+ [ERR_QUARK_VERIFICATION] = "Quark signature verification failed",
+ [ERR_SGN_FILE_NOT_FOUND] = "Quark signature file not found",
};

If you grep for ERR_SGN_FILE_NOT_FOUND you’ll find it’s in the following files:
./work/efi/ia32/loader/linux.c:410: errnum = ERR_SGN_FILE_NOT_FOUND;
./work/efi/ia32/loader/linux.c:732: errnum = ERR_SGN_FILE_NOT_FOUND;
./work/efi/quark/boot_settings.c:190: errnum = ERR_SGN_FILE_NOT_FOUND;

Going back to Intel’s modifications to grub, we can see what they added:

It takes a bit of searching, but if you strip out all of the grub_quark_secure logic from linux.c and boot_settings.c, you end up with…

Ta-da! I can boot Yocto Linux

No more Secure Boot!

At the end of the day, the Quark X1000 is an x86: “secure SKU” is nothing but a fuse setting.

The comment should read:

Determine whether or not grub should enforce Secure Boot.

In our case, this is not a mandatory option 😉

Special offer for DK200 owners
As shown above, it is possible to modify the Intel sources to disable Secure Boot. If there are other people have a DK200 from Intel and are interested in running a firmware without Secure Boot, leave a comment with your contact details. Upon request, I can provide a firmware image* with generic Ethernet MAC addresses for you to flash. Note that this firmware is specific to the DK200 (Clanton Hill) hardware.

* No warranty, express or implied, provided for said firmware image. You flash at your own risk!

Allwinner H2+/H3 Ethernet with Linux 4.9-rc8

The Orange Pi PC is not a new single board computer. It’s been released for over a year now, but has mostly been stuck on a heavily patched 3.4 release kernel.

There have been ongoing efforts since the release to have support for the Allwinner H3 in the mainline kernel. In the past weeks there have been new patches released which enable support for the Ethernet MAC on the H3 (and H2+).

Unfortunately this support is not in mainline yet, and won’t make it in the upcoming 4.9 release. However, that doesn’t stop you from taking the patches and applying them against 4.9 yourself.

I wrote a script to compile the kernel from source, applying the necessary patches to the kernel and using a minimal .config file which compiles the sun8i_emac support as a module. You can download the build script from GitHub.

It does try to be somewhat smart: verifying the integrity of the downloaded files, and will bail out if there are errors in patching the source code. But, it doesn’t do toolchain dependency checking because that’s just too complicated. Since the emac support will end up in mainline soon, I doubt it’s worth the time to improve the build script. However if anyone is interested in improving it, the script is released as GPLv2.

The result? If you are patient enough to wait for the kernel to compile, you get a uImage and modules for Linux 4.9-rc8 with Ethernet support:

Allwinner H3 emac performance:

orangepi@OrangePI:~$ iperf -n 1024M -c 192.168.1.150
————————————————————
Client connecting to 192.168.1.150, TCP port 5001
TCP window size: 43.8 KByte (default)
————————————————————
[ 3] local 192.168.1.206 port 42572 connected with 192.168.1.150 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-100.6 sec 1.00 GBytes 85.4 Mbits/sec

Orange Pi Zero (Allwinner H2+):

I’ve also just received my Orange Pi Zero and confirmed that the same kernel works on the Orange Pi Zero, so you can run Linux 4.9 on the Orange Pi PC (Allwinner H3) or Orange Pi Zero (Allwinner H2+) with Ethernet support.

Allwinner H2+ emac performance:

orangepi@OrangePI:~$ iperf -n 1024M -c 192.168.1.150
————————————————————
Client connecting to 192.168.1.150, TCP port 5001
TCP window size: 43.8 KByte (default)
————————————————————
[ 3] local 172.16.4.206 port 54762 connected with 192.168.1.150 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-95.9 sec 1.00 GBytes 89.5 Mbits/sec

Download:
If you want to skip compiling the kernel yourself, I’m providing the kernel uImage and modules here.

I am using u-boot v2016.11 from denx.

Note: HDMI isn’t working on my Orange Pi PC, and since I run it headless I’m not interested in investigating why. If you’re using your Orange Pi PC with HDMI output, you may need to modify the kernel .config file to fix HDMI.

Linux 4.5 on a Bay Trail tablet

This post is a short update to my original article on booting Arch Linux on a Bay Trail tablet.

I originally wrote this for 4.4.5, but I wasn’t fast enough, and 4.5 was released before the post was completed, so might as well continue with a 4.5 kernel.

To simplify the build process I took the PKGBUILD for linux-mainline in AUR and modified it to build a mainline kernel with patches for SDIO WiFi on BayTrail.

If you’d like to build the kernel yourself (and you happen to run Arch Linux) you can download the PKGBUILD.

The firmware for the rtl8723bs card is in its own package, in keeping with the Arch Linux best practices for separating firmware from the kernel package. Download the firmware PKGBUILD.

Or, if you’d rather just have a newer kernel on your tablet which is already running Arch Linux, you can download the pre-built kernel package, and the firmware package.

I will be submitting both of these packages to AUR shortly.

Turns out you can actually get GRUB working with a menu if you build a standalone version of grub. However, the issue is that even though the grub menu works, there’s some issue with modesetting and you’ll never see any console after grub hands off to the kernel. You can download the standalone version of grub if you want to try, I wasn’t able to get any usable installer environment out of it. You can download standalone grub for ia32 (i686), you will also need grub.cfg.

$ tar -Jxf bootia32.tar.xz
$ cp bootia32.efi /mnt/archiso/EFI/boot/bootia32.efi
$ cp grub.cfg /mnt/archiso/EFI/boot/grub.cfg

Since grub video handoff isn’t working well, the only way I was able to successfully boot was to drop to command line by pressing c at the menu, and typing the following:

set root=hd0,msdos1
linux /arch/boot/x86_64/vmlinuz archisobasedir=arch archisolabel=ARCH_201603 video=VGA-1:800x1280@75e
initrd /arch/boot/x86_64/archiso.img
boot

There is a small issue with kernel oops, which has been present since at least 4.4.5:

[  164.281827] NMI watchdog: Watchdog detected hard LOCKUP on cpu 2
[  164.281913] Modules linked in:
[  164.281962]  intel_rapl intel_soc_dts_thermal intel_powerclamp coretemp kvm_intel kvm irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel aesni_intel aes_x86_64 lrw iTCO_wdt snd_soc_sst_bytcr_rt5640 iTCO_vendor_support hid_multitouch gf128mul glue_helper dcdbas ablk_helper cryptd pcspkr hci_uart snd_intel_sst_acpi mei_txe joydev input_leds snd_intel_sst_core btbcm snd_soc_rt5640 evdev snd_soc_sst_mfld_platform mousedev btintel mei lpc_ich mac_hid snd_soc_rl6231 thermal snd_soc_sst_match dw_dmac dw_dmac_core tpm_crb snd_soc_core bluetooth processor_thermal_device int3400_thermal int3403_thermal acpi_thermal_rel int3402_thermal i2c_hid int340x_thermal_zone snd_compress intel_soc_dts_iosf tpm_tis rfkill_gpio snd_pcm_dmaengine battery ac97_bus ac spi_pxa2xx_platform crc16 tpm snd_pcm i2c_designware_platform
[  164.283185]  acpi_pad i2c_designware_core 8250_dw snd_timer snd processor soundcore sch_fq_codel nfs lockd grace sunrpc fscache ip_tables x_tables overlay squashfs loop nls_iso8859_1 nls_cp437 vfat fat sd_mod uas usb_storage scsi_mod hid_generic usbhid hid i915 mmc_block button i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops crc32c_intel xhci_pci drm xhci_hcd intel_gtt wmi serio video sdhci_acpi sdhci led_class r8723bs(O) cfg80211 rfkill mmc_core
[  164.283978] CPU: 2 PID: 0 Comm: swapper/2 Tainted: G           O    4.5.0-byt #1
[  164.284073] Hardware name: Dell Inc. Venue 8 Pro 3845/XXXXXX, BIOS A02 12/29/2014
[  164.284169]  0000000000000086 9ad5a4512f59852f ffff880039d05b50 ffffffff812d25d1
[  164.284284]  0000000000000000 0000000000000000 ffff880039d05b68 ffffffff81116550
[  164.284399]  ffff880038ca8000 ffff880039d05ba0 ffffffff81156b4c 0000000000000001
[  164.284513] Call Trace:
[  164.284552]    [] dump_stack+0x63/0x82
[  164.284645]  [] watchdog_overflow_callback+0xe0/0xf0
[  164.284733]  [] __perf_event_overflow+0x8c/0x1d0
[  164.284815]  [] perf_event_overflow+0x14/0x20
[  164.284894]  [] intel_pmu_handle_irq+0x1e1/0x460
[  164.284980]  [] perf_event_nmi_handler+0x28/0x50
[  164.285062]  [] nmi_handle+0x5e/0x130
[  164.285133]  [] default_do_nmi+0x48/0x120
[  164.285207]  [] do_nmi+0xe2/0x130
[  164.285274]  [] end_repeat_nmi+0x1a/0x1e
[  164.285349]  [] ? poll_idle+0x39/0x80
[  164.285420]  [] ? poll_idle+0x39/0x80
[  164.285490]  [] ? poll_idle+0x39/0x80
[  164.285558]  <>  [] cpuidle_enter_state+0xf3/0x2f0
[  164.285655]  [] cpuidle_enter+0x17/0x20
[  164.285728]  [] call_cpuidle+0x2a/0x40
[  164.285800]  [] cpu_startup_entry+0x2c5/0x3a0
[  164.285878]  [] start_secondary+0x165/0x1a0
[  164.285964] INFO: NMI handler (perf_event_nmi_handler) took too long to run: 4.144 msecs
[  164.286069] perf interrupt took too long (32852 > 2495), lowering kernel.perf_event_max_sample_rate to 50100
[  172.707012] perf interrupt took too long (32619 > 4960), lowering kernel.perf_event_max_sample_rate to 25200

You’ll see a lot of these, however WiFi still continues to work, and the tablet didn’t kernel panic for me in the installer environment.

Hopefully someone finds this useful. I’ll have a write up on installing and using Arch Linux on the tablet in the coming weeks.