Problems and features of UEFI implementation on various platforms

About nineteen years have passed since the release of the first EFI specification in the year 2000. It took the interface ten years to enter the user market and gain a foothold on it. At the moment, rarely can you see a modern computer without UEFI in the firmware of the motherboard. The interface standard has increased the "meat" and several thousand pages in the official documentation. For the average user, nothing has changed, except for occasional collisions with Secure Boot enabled. But if the plane of work shifts to development, everything becomes more interesting.



The very concept of the modular architecture of UEFI implies that these modules can not only be used in the standard configuration, but also download something of their own. A file system driver (not limited to native efi-shy FAT?), Peripheral drivers, applications, bootloaders - you can load everything by hand, it would be nice to load a bit of Shell. You can take a step "deeper" and look at the contents of the firmware, saving yourself from dancing with SecureBoot and the need to write a layer of scripts (there are enough articles on the pages of the hub).

On this basis, the idea was born of creating functional modules that perform various security functions before loading the OS, which can further unite and become a kind of integrated trusted boot environment affecting both services of the boot and runtime interface so that between the modules in the firmware and the modules on the disk nothing could be "pushed" without low-level intervention, and after them - only with the permission of the security administrator.

The implementation of this idea introduced us to a huge number of nuances and subtleties of UEFI - starting with many undocumented or poorly documented features, bugs, and ending with the undefined behavior so beloved by all developers. Let's start in order.

Platform Dependence




The first thing you need to find out when integrating into the platform is whether we can work with it? The version of the UEFI specification is important, and on most devices it is presented in the range between 2.1 and 2.7. The newer has not yet hit the research stand. The older one is found, and its performance may be limited due to the lack of the necessary protocols or crookedly written drivers for their implementation. For example, UnicodeCollation is often not enough, when accessing smbios there are undocumented errors, the language change functions through SetVariable () do not work. Anything can happen, depending on the vendor and freshness, because sometimes you have to put your protocols even on relatively new boards.

Even in our practice, I was lucky enough to stumble upon two mini-computers with Intel Bay Trail D and 32-bit firmware on board. The case is rare, but at one time it made it necessary to urgently recompile the modules. Actually, like the question: will we meet with a more modern platform of the same capacity in the future? And if we meet, then where?

The next step is to determine how to integrate. The modules are built into the firmware, the firmware is located in the SPI chip on the board, and PCH with Intel ME is located nearby. And here the most interesting question arises - how to get there? Good old programmer with a "crocodile" - this is good, it is reliable. Even if you don’t catch on to the end, you can always look at the burning LEDs on the board, they have enough power from the programmer. It works almost flawlessly, with the exception of some older HP models, where mikruha SOIC-16 with firmware is so accessible that it’s easier to contrive and solder the adapter to her legs than to squeeze the clip.



I know that there are people on Habré who have contributed to the writing of flashrom, thanks to them separately.

But, despite the reliability and reliability of dump removal by the programmer, this method is not suitable if you need to install something in UEFI on several machines, or if the target platform for installation is not on your desk. Fortunately for us, manufacturers left behind native firmware utilities: FPT (Flash programming tool) from Intel (CS) ME System Tools, and AFU (AMI Firmware Update) for Aptio from American Megatrends. These utilities are launched both from the EFI environment and from the Windows, Linux, and DOS operating systems. The utilities are somewhat interchangeable, both allow you to consider the image, if not the whole, then certain regions for sure. And sometimes they even let you write back.



He writes and does not write

This is where the first serious stumbling block on the path of integration appears. Not all motherboards allow you to read the entire firmware, banning access to the ME region (ME is almost sacred, Intel will not allow it to be read in a good way, but in a bad way we don’t always want to). Even less - pour something even into the BIOS region, unless it is a signed capsule. The likelihood of success varies greatly depending on the manufacturer and the freshness of the chipset. On some models of motherboards, you can observe a funny picture: that which was not recorded on the old vendor boards, flies at new times.

Sometimes IFR parser helps fight write protection, which opens the curtain on hidden settings and variables. And sometimes only a hardcore jumper helps, allowing access to the recording or "turning off" ME (if one is provided, of course).

The complex nature of systems


The Acer, Asus, AsRock, and Gigabyte boards in most cases are written without unnecessary difficulties. Intel, HP and server hardware stand apart. HP not only does not allow writing in itself programmatically, it also swears at any attempt to modify the firmware (inCodeRush there are articles on finding and disabling integrity checking). Intel more or less recorded up to the 87th chipset, then it became deaf to requests to open the gates of the BIOS region.

With Intel, the first time was funny. The modules were imported into the firmware using the UEFITool utility, and we came across an interesting bug: if you insert ffs modules at the end of the DXE volume, after all freeforms, then the assembled image “bricked” the board. The solution was to add modules after any native DXE driver. We did not immediately get to this, and at first it looked like Intel was monitoring the integrity of the firmware, like HP. Later it became clear that one could not do without an automatic utility for importing modules, and the problem came to naught after writing it.

Server-side hardware is simpler and more complex at the same time. On the one hand, there are always additional ways to update and modify BIOSes on servers, on the other hand, the volume of customization in these same BIOSes is overwhelming, since they don’t skimp on servers and install quite capacious flash memory chips, often also backing them up.

When installing on a server, it is always nice to be able to remotely update the BIOS via IPMI. True, for this in a good way you need a license, of course paid. If it does not appear at the right time, it is quite possible to get into a funny situation similar to the one we got by introducing modules into the Supermicro server BIOS.

After the introduction of the modules, the load freezes tightly due to blocking by one of the security modules (they did not take into account the waywardness of the server BIOSs, with whom it does not happen!). In the absence of the ability to force the BIOS to be rolled back through IPMI, the hand itself reached for the programmer, but it was a bad luck - the standard SOIC-8 clip was not enough for a SOIC-16 chip! Well, okay, because in theory the server board has the ability to backup from the connected media, picking up the SUPER.ROM image in the root. But this mechanism does not start, because according to the system everything is OK, everything works, therefore, the BIOS rollback is not needed! What to do?! .. The story ended up running around the city in search of the right clip, an emergency re-soldering of wires, smeared by the Chinese in an incomprehensible order for us, and finally - a flashing.

Lenovo came out even more interesting. On the switches received from the vendor, under the cover of the case, a control board was found with two “mikruhs” for firmware, with an SSD for OSes and with a fixed battery. The BIOS turned out to be a tough nut, I didn’t want to eat a modified image in any way, succumbing only to the programmer. In one of the attempts to write something down, they inserted a flash drive with console ubuntu into the switch (the terminal did not give out graphics) and booted quite safely. Having done what was required, they turned off the system using the halt -p command from the old memory. The switch, by its nature not adapted for any shutdown, except for the lack of power, was not ready for this and did not want to start anymore. The link on the face burned through once, the fans rustled quietly, and all the ports gave out nothing. Re-flashing did not help,the battery sat like a glove - we were afraid to break the mount. As a result, a thin dielectric plate crawled under the force of perseverance and verbal inspiration under the contacts, the volatile memory was erased, the switch came to life.

The study of dumps taken from two chips showed a lot of interesting things. In particular, a huge number of "Invalid" entries in the NVRAM of the main firmware and several similar ones in the backup. Well, and not a previously encountered data hash in the volume with DXE drivers. One could only guess about the exact cause of the problem of starting the switch.

In general, the software part is rarely deprived of its unexpected nuances. Many motherboards that came to us before the 87th chipset (from different manufacturers) have an unpleasant feature to produce an endless stream of errors when entering the “dh -v” command in the shell console. With manual entry, this is not critical, but when collecting data into a file, it ends in an unfortunate hang. In both cases, you have to restart the machine. I am glad that at the same time the data file does not swell to immense sizes.



Kraftway BIOS with ASRock H81M-DGS board proved to be very wayward. So, it responds to Ctrl Alt Del Del by hanging, from which only Reset can output it. There were problems with skipping the startup script <startup.nsh> in Shell'e - a split second to choose from instead of five default ones. Perhaps these problems are caused by the modification by the KSS proprietary modules, perhaps the matter is inaccurately “unscrewed” ME.

On the Asus H97-PLUS board, the firmware has the following feature - BootOrder overflows over time. Most likely, the reason lies in the errors in the code. Although, perhaps, the manufacturer wanted to keep all the boot devices that were ever connected in the board, but did not calculate that there could be more than a dozen in one day. So, when BootOrder overflows, the system hangs during the boot process. To clean it, you must turn off all boot devices and turn on the system. The firmware clears itself and the system boots directly into the BIOS Setup shell. Performance remains until the next overflow.

Summarizing the experience of working with boards of various vendors, you come to the conclusion that it is almost impossible to find out what surprises at the EFI level you will deal with on the next board, even if it already has a well-known model. This is a kind of lottery, because sometimes difficulties may arise at the stage of collecting information about the system. Perhaps this has a share of unquenchable research idealism and faith in the manufacturer, because how else could some of the freshest motherboards with ME v11 and v12 hang when running FPT or MEInfo of older versions on them?

Problems of work with hardware protocols




Some problems pop up when we start working with USB devices - drives and tokens. This happens often because the BIOS code for working with peripherals is a dangerous cocktail of drivers and applications from Independent Hardware Vendor (IHV) for a specific peripheral, code from the chipset manufacturer (in our case, from Intel), code from the BIOS manufacturer and code from the manufacturer of the motherboard.

The following “interesting” situations

arose : Token “not detected”. At the same time, an LED is lit on it. Most likely, the host controller does not go through the initial reset procedure of the USB device, that is, the power is supplied, but the reset through changing the D + and D- lines does not work correctly, and without it, any further manipulations with the token are meaningless.

The computer freezes before loading the shell (again, with a token connected). In this case, without a token, the PC starts normally. Live, it looks like this: the computer seems to crash right after the start, while the token sticks out in the connector. You take it out - loading suddenly continues. Connect - hanging again. The obvious problem is in UEFI, and one can only speculate about the reasons.

The situation when it is not possible to open the USB_IO interface. Perhaps it is connected only with the interface for working with smart cards - USB CCID. Some AMI driver has already opened USB_IO with the EFI_OPEN_PROTOCOL_BY_DRIVER parameter. The driver has a protocol with a GUID:

#define EFI_AMI_USB_CCID_PROTOCOL_GUID	 { 0x5FDEE00D, 0xDA40, 0x405A, { 0xB9, 0x2E, 0xCF, 0x4A, 0x80, 0xEA, 0x8F, 0x76} }
 // Workaround.      EFI_OPEN_PROTOCOL_BY_DRIVER,  ,     EFI_OPEN_PROTOCOL_GET_PROTOCOL.
 //
 // Open USB I/O Protocol
 //
 Status = gBS->OpenProtocol (
 ControllerHandle,
 &gEfiUsbIoProtocolGuid,
 (VOID **) &UsbIo,
 This->DriverBindingHandle,
 ControllerHandle,
 EFI_OPEN_PROTOCOL_BY_DRIVER
 );

 if (EFI_ACCESS_DENIED == Status)
 {		// AMI BIOS workaround (BindingStop will not be invoked)
	 Status = gBS->OpenProtocol(
		 ControllerHandle,
		 &gEfiUsbIoProtocolGuid,
		 (VOID **)&UsbIo,
		 This->DriverBindingHandle,
		 ControllerHandle,
		 EFI_OPEN_PROTOCOL_GET_PROTOCOL
	 );
 }

However, BindingStop () will not be called, i.e. the device extraction event is not monitored, and the driver will try to use invalid handle. This was observed with the HP Compaq Elite 8300 SFF PC and some others. This is either a kind of vendor protection from unwanted drivers, or a regular development bug. Perhaps AMI is constantly doing something in the direction of USB CCID, but the interfering driver cannot be unloaded, since it is located in the same AMI UHCI module along with USB HID, USB MassStorage. With UninstallInterface (), things are similar.

Or another interesting feature. In one of the UEFI BIOS, where the token was not detected, USB_IO allowed to read the device descriptors, but EFI_INVALID_PARAMETER returned to the next UsbBulkTransfer (). Moreover, this happened only with some types of tokens, with absolutely the same parameters, others worked perfectly.

In general, the protocol UsbBulkTransfer () is interestingly implemented in the EFI_USB_IO_PROTOCOL protocol. It is intended for guaranteed package delivery for an unlimited time, or for the time specified in the Timeout parameter. But an experiment was conducted with a MassStorage device: when copying a large file to a USB flash drive, it was removed. PC hangs tight. When connecting the USB flash drive, the PC sagged and continued to write the file as if nothing had happened. The same situation was with tokens, but with its own specifics. This is an architectural problem, in EFI there are no interrupts except a timer, and the devices operate according to a poll. That is, the system crashed somewhere in the USB poll, but did not reach the timeout, when the device reappeared, it simply continued and completed the operation.

Virtualization


We should also say about virtual environments. Currently there are two main platforms on the market that support emulation of the EFI environment: VMware and VirtualBox. Both have their advantages and disadvantages when interacting with them as with “real” systems. The VMware environment adequately provides work with NVRAM variables, but stumbles when displaying messages visually during the initialization of DXE modules: in the best case, preference will be given to native messages about finding bootable media, leaving behind what we need. VirtualBox, on the contrary, perfectly renders everything required, but does not want to remember long variables.

Another small stone in the VMware garden - the FAT32 driver built into it supports the creation and editing of files only in 8.3 notation. It is not clear why this was done, but this is a limitation that clearly requires attention. It is likely that a similar implementation of the driver can be observed on real platforms, but so far we have not come across those.

On the other hand, in virtual machines there are no dances with firmware utilities, programmers, jumpers, uncomfortable chips. A separate ROM file, UEFITool and a line in the config file. Almost an idyll.

In the end



A slice of the request from CHIPSEC. Where do they teach such sacraments?

As already mentioned, the development and implementation in the UEFI shell is a fascinating and creative process. You can always come across something new even on a famous field. On the one hand, it is encouraging that the standard is developing, on the other, it is saddening that concrete implementations of it by the producers are too “creative”.

The main problems were and remain:

  1. Departure of vendors from the UEFI specification when developing firmware.
  2. Errors in the code during implementation.
  3. NDV in code, pop-up during integration.

And last, but not least, the absence of many things in the official (read, open) documentation, such as, for example, descriptions of the protocol for communicating with ME via PCI devices like MEI, HECI. You can find a description of the registers, but not the commands. Find a GUID, but not its purpose. Which once again returns the work to a long analysis, collecting data and statistics on platforms and using the disassembler.

It should be noted that the situation is slowly but surely correcting, and I want to believe that the moment is not far off when the development of the standard will become a fairly predictable and very pleasant process.

Vladimir Onipchuk,
Head of the group of hardware and software protection products of
Gazinformservice LLC

All Articles