SuperThunder/HP_Z420_Z620_Z820_BootBlock_Upgrade

AMI BIOS Investigation (Overclocking? SRIOV?)

Opened this issue · 5 comments

From issue#3:

Dare I ask if anyone with a programmer could try to unlock the following bios options and see what happens?
-overclocking
-sr-iov
I've reviewed a bios dump and the menu options definitely already exist in the AMI bios; they're just hidden. Flashing a modified bios apparently doesn't work since hp signs the bios and rejects the modified file. I'd be willing to do the work on my own machine if somebody would throw themselves on the sword to test it first.

For Zx20 and above, I think there are boot guard protections in place that will reject a BIOS with an invalid signature on a protected region. Flashing the boot block works because HP signs portions of the BIOS, not the whole thing. However boot protections often have flaws (especially when almost a decade old) so that may not be the end.

@zack4485, what software did you use to look through the BIOS?

I have a Z400 that I am fond of but willing to risk for science (I have already taken a soldering iron to it...it eventually started working again), so if that has a hidden menu as well it may provide some insight. I believe Zx00 was the last generation without boot protections, but a lot of the code stays the same between generations.

It's been a while but these are the tools that should work:

  • UEFITool
  • Universal IFR Extractor
  • IFRExtractor

I was thinking it could also be possible to overclock (and access other settings) using the EFI shell, relying on the IFR dump as a roadmap to the various settings. Changes made via EFI shell do seem to persist after reboots but they don't seem to have any impact either...

Here are some settings I find in the IFR from my own z420:

0x94BC8 		One Of: Package C State limit, VarStoreInfo (VarOffset/VarName): 0x34, VarStore: 0x1, QuestionId: 0x40, Size: 1, Min: 0x0, Max 0x0, Step: 0x0 {05 A6 5C 02 5D 02 40 00 01 00 34 00 10 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00}
0x94BEE 			One Of Option: , Value (8 bit): 0x0 {09 0E 5E 02 00 00 00 00 00 00 00 00 00 00}
0x94BFC 			One Of Option: C2, Value (8 bit): 0x1 {09 0E 5F 02 00 00 01 00 00 00 00 00 00 00}
0x94C0A 			One Of Option: C6, Value (8 bit): 0x6 {09 0E 60 02 00 00 06 00 00 00 00 00 00 00}
0x94C18 			One Of Option: C7, Value (8 bit): 0x7 {09 0E 61 02 00 00 07 00 00 00 00 00 00 00}
0x94C26 			One Of Option: No Limit, Value (8 bit): 0xFF (default) {09 0E 62 02 30 00 FF 00 00 00 00 00 00 00}
0x94C34 		End One Of {29 02}
0x94C36 		Numeric: Long duration power limit, VarStoreInfo (VarOffset/VarName): 0x47, VarStore: 0x1, QuestionId: 0x41, Size: 1, Min: 0x0, Max 0xFF, Step: 0x0 {07 A6 1E 02 1F 02 41 00 01 00 47 00 10 10 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00}
0x94C5C 			Default: DefaultId: 0x0, Value (8 bit): 0x0 {5B 0D 00 00 00 00 00 00 00 00 00 00 00}
0x94C69 		End {29 02}
0x94C6B 		Numeric: Long duration maintained, VarStoreInfo (VarOffset/VarName): 0xB5, VarStore: 0x1, QuestionId: 0x42, Size: 2, Min: 0x0, Max 0xFF, Step: 0x0 {07 A6 23 02 24 02 42 00 01 00 B5 00 10 11 00 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00}
0x94C91 			Default: DefaultId: 0x0, Value (16 bit): 0x0 {5B 0D 00 00 01 00 00 00 00 00 00 00 00}
0x94C9E 		End {29 02}
0x94CA0 		Numeric: Short duration power limit, VarStoreInfo (VarOffset/VarName): 0x48, VarStore: 0x1, QuestionId: 0x43, Size: 1, Min: 0x0, Max 0xFF, Step: 0x0 {07 A6 28 02 29 02 43 00 01 00 48 00 10 10 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00}
0x94CC6 			Default: DefaultId: 0x0, Value (8 bit): 0x0 {5B 0D 00 00 00 00 00 00 00 00 00 00 00}
0x94CD3 		End {29 02}
0x94E48 		Numeric: 8-Core Ratio Limit, VarStoreInfo (VarOffset/VarName): 0x2D, VarStore: 0x1, QuestionId: 0x4B, Size: 1, Min: 0x0, Max 0xFF, Step: 0x0 {07 A6 3B 02 3C 02 4B 00 01 00 2D 00 10 10 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00}
0x94E6E 			Default: DefaultId: 0x0, Value (8 bit): 0x0 {5B 0D 00 00 00 00 00 00 00 00 00 00 00}
0x94E7B 		End {29 02}
0x94E7D 		Numeric: VID Override for Max Turbo Ratio, VarStoreInfo (VarOffset/VarName): 0x2E, VarStore: 0x1, QuestionId: 0x4C, Size: 1, Min: 0x0, Max 0xFF, Step: 0x0 {07 A6 40 02 41 02 4C 00 01 00 2E 00 10 10 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00}
0x94EA3 			Default: DefaultId: 0x0, Value (8 bit): 0x0 {5B 0D 00 00 00 00 00 00 00 00 00 00 00}
0x94EB0 		End {29 02}

Unless I'm a moron it looks like HP actually didn't bother to strip out the default AMI forms for advanced and security settings; it seems to have simply disabled them and added their own copies. My hope was that it would be possible to simply enable those forms. They seem to be conditionally disabled based on the value of certain settings and hence superficially I would think it possible to use the EFI shell to edit those settings and thereby enable the other forms. I'm just not familiar enough with EUFI to know what I'm doing :-)

                                   Form Sets
--------------------------------------------------------------------------------
Offset:		Title:
--------------------------------------------------------------------------------
0x92E04		Main (0xA from string package 0x0)
0x96203		Advanced (0x20 from string package 0x0)
0x9988D		Chipset (0x22 from string package 0x0)
0x9A974		Boot (0x24 from string package 0x0)
0x9B9CF		Security (0x3F from string package 0x0)
0x9C740		Save & Exit (0x53 from string package 0x0)
0x9CF7B		File (0x6F from string package 0x0)
0x9D7C1		Storage (0x85 from string package 0x0)
0x9F231		Security (0x3F from string package 0x0)
0xA2141		Power (0xAE from string package 0x0)
0xA2B70		Advanced (0x20 from string package 0x0)

My lazy brain thinks this is the relevant section in terms of how they've disabled the forms and how one may be able to re-enable them:

0x96099 		Disable If {1E 82}
0x9609B 			True {46 02}
0x9609D 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x0, VarStore: 0x4, QuestionId: 0x83 {06 8E 00 00 00 00 83 00 04 00 00 00 00 00}
0x960AB 			End {29 02}
0x960AD 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x0, VarStore: 0x3, QuestionId: 0x84 {06 8E 00 00 00 00 84 00 03 00 00 00 00 00}
0x960BB 			End {29 02}
0x960BD 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x13, VarStore: 0xE, QuestionId: 0x85 {06 8E 00 00 00 00 85 00 0E 00 13 00 00 00}
0x960CB 			End {29 02}
0x960CD 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x12, VarStore: 0xE, QuestionId: 0x86 {06 8E 00 00 00 00 86 00 0E 00 12 00 00 00}
0x960DB 			End {29 02}
0x960DD 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x11, VarStore: 0xE, QuestionId: 0x87 {06 8E 00 00 00 00 87 00 0E 00 11 00 00 00}
0x960EB 			End {29 02}
0x960ED 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x10, VarStore: 0xE, QuestionId: 0x88 {06 8E 00 00 00 00 88 00 0E 00 10 00 00 00}
0x960FB 			End {29 02}
0x960FD 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0xF, VarStore: 0xE, QuestionId: 0x89 {06 8E 00 00 00 00 89 00 0E 00 0F 00 00 00}
0x9610B 			End {29 02}
0x9610D 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0xE, VarStore: 0xE, QuestionId: 0x8A {06 8E 00 00 00 00 8A 00 0E 00 0E 00 00 00}
0x9611B 			End {29 02}
0x9611D 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0xD, VarStore: 0xE, QuestionId: 0x8B {06 8E 00 00 00 00 8B 00 0E 00 0D 00 00 00}
0x9612B 			End {29 02}
0x9612D 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0xC, VarStore: 0xE, QuestionId: 0x8C {06 8E 00 00 00 00 8C 00 0E 00 0C 00 00 00}
0x9613B 			End {29 02}
0x9613D 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0xB, VarStore: 0xE, QuestionId: 0x8D {06 8E 00 00 00 00 8D 00 0E 00 0B 00 00 00}
0x9614B 			End {29 02}
0x9614D 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0xA, VarStore: 0xE, QuestionId: 0x8E {06 8E 00 00 00 00 8E 00 0E 00 0A 00 00 00}
0x9615B 			End {29 02}
0x9615D 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x9, VarStore: 0xE, QuestionId: 0x8F {06 8E 00 00 00 00 8F 00 0E 00 09 00 00 00}
0x9616B 			End {29 02}
0x9616D 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x8, VarStore: 0xE, QuestionId: 0x90 {06 8E 00 00 00 00 90 00 0E 00 08 00 00 00}
0x9617B 			End {29 02}
0x9617D 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x7, VarStore: 0xE, QuestionId: 0x91 {06 8E 00 00 00 00 91 00 0E 00 07 00 00 00}
0x9618B 			End {29 02}
0x9618D 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x6, VarStore: 0xE, QuestionId: 0x92 {06 8E 00 00 00 00 92 00 0E 00 06 00 00 00}
0x9619B 			End {29 02}
0x9619D 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x5, VarStore: 0xE, QuestionId: 0x93 {06 8E 00 00 00 00 93 00 0E 00 05 00 00 00}
0x961AB 			End {29 02}
0x961AD 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x4, VarStore: 0xE, QuestionId: 0x94 {06 8E 00 00 00 00 94 00 0E 00 04 00 00 00}
0x961BB 			End {29 02}
0x961BD 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x3, VarStore: 0xE, QuestionId: 0x95 {06 8E 00 00 00 00 95 00 0E 00 03 00 00 00}
0x961CB 			End {29 02}
0x961CD 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x2, VarStore: 0xE, QuestionId: 0x96 {06 8E 00 00 00 00 96 00 0E 00 02 00 00 00}
0x961DB 			End {29 02}
0x961DD 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x1, VarStore: 0xE, QuestionId: 0x97 {06 8E 00 00 00 00 97 00 0E 00 01 00 00 00}
0x961EB 			End {29 02}
0x961ED 			Checkbox: , VarStoreInfo (VarOffset/VarName): 0x0, VarStore: 0xE, QuestionId: 0x98 {06 8E 00 00 00 00 98 00 0E 00 00 00 00 00}
0x961FB 			End {29 02}
0x961FD 		End If {29 02}

I also expect that this would be the set of steps likely necessary to do the actual BIOS editing the "right" way:

https://www.bios-mods.com/forum/Thread-GUIDE-How-to-modify-AMI-MSI-BIOS-to-unlock-full-features-UEFI-Aptio4

The out-of-box amibcp util doesn't like the HP .bin image but I'm guessing that's because it's concatenating the BIOS with the boot block and Lord knows what else; in order to run the out-of-box AMI utilities I expect one would need to split the BIOS out into its own file first.

Random idea: what about flashing the bios from a dl380 gen8 onto the z620? Superficially the hardware is pretty similar...

Or at least extracting modules from it that don't exist on the z620 bios (like SR-IOV). I know it's possible to retrofit in the nvme module so maybe the same could be done with any other missing module?

I also would guess if the z400 and z420 are as similar as you say then a side-by-side comparison of the bios regions may help identify where the verification component lives (which was newly added in the z420 so should be outright missing in the z400).

Alas I just don't know much about the subject of bios editing so don't know what this would even look like... similar to saying I know what I'm looking for but not when it's written in Swahili.

This is very interesting, when I have some time I will take a look at my Z400 and see if it has similar options

For Z620 it does appear that secure boot can be disabled (related discussion: https://h30434.www3.hp.com/t5/Business-PCs-Workstations-and-Point-of-Sale-Systems/LoJax-can-a-HPZ-series-workstation-be-configured-to-be/td-p/7046218), but at the very minimum the checksums for each BIOS region will need to be valid (assuming the BIOS does check the checksums, and not just the BIOS updater. Not actually checking checksums has been a flaw in some BIOSes/firmwares).

Is your secure boot disabled?

I'm not sure if disabling secure boot will disable the checking of cryptographic signatures (I never looked into it, but I think an RSA public key is included with the BIOS and certain regions have a signed checksum). I guess the easiest way to test that is to do the modifications and see what happens at boot.

I found a paper from MITRE about defeating signed BIOS enforcement (https://www.mitre.org/sites/default/files/publications/defeating-signed-bios-enforcement.pdf), so that may be useful later. It appears there are quite a number of flaws in the protection mechanisms, especially in older systems like the Z620.

If the checksums can be recalculated and signature verification avoided, I don't see why enabling those menus by editing the BIOS file and flashing it with a programmer shouldn't work. Ideally the edit could be done with one of the AMI software tools, but a manual hex edit could probably work too.

I don't know too much about EFI modules, it seems fairly common to add NVMe boot drive support with them. One way seems to be making a special USB boot drive with the new EFI modules you want on them, so that could be an easy way to test the DL380 g8 modules on a Z620.

The Zx00 and Zx20 are different in that EFI and Secure Boot was added with Zx20, but I think the actual BIOS menu is pretty much the same old code (supposedly going back all the way to DEC Alpha). I found 'Clove-EFI' which includes a way to emulate UEFI on legacy systems, so that's pretty cool (https://wiki.archlinux.org/index.php/Clover). One person used this to have an NVMe boot drive on Z800 with CloverEFI (https://steemit.com/hp/@fobio/load-win10-on-nvme-pci-e-on-hp-z800).

@SuperThunder @zack4485

To add to your 4 y.o. conversation, here is a way to write any BIOS to the flash chip through software, including the modded one:
#12

One person on techpowerup did write a modded BIOS through an external programmer. Just added an NVME module, nothing else, no signature changes - and it worked OK. I do have his working copy, and compared it extensively to stock. On my side, I daisy chained a few updates, and they bricked - some moved things around a lot. So careful mods should work, extensive ones - may not.

So I think there is BIOS verification when writing through the official tools, but it does not kick in during boot since a modded BIOS did work, at least in 1 case.