Relationship between AllowUnverifiedRo and software write protect

I did some messing around today. Restored the stock firmware on a roric and reset the ccd to default. The result was that the device would not boot due to AllowUnverifiedRo. Got it resolved, so no issues here, but I think I discovered something that wasn’t obvious to me from this: Disabling Firmware Write Protection | MrChromebox.tech

AllowUnverifiedRo:always will fail to boot if software write protect is disabled. Why I think this: After recovering from the not booting device, all I changed was enabling sofware write protect (wp-enable and wp-region) and now the device boots even with AllowUnverifiedRo:never.

EDIT: AllowUnverifiedRo:never will fail to boot if software write protect is disabled. Why I think this: After recovering from the not booting device, all I changed was enabling sofware write protect (wp-enable and wp-region) and now the device boots with AllowUnverifiedRo:never.

Not sure if this behavior is known. I think this should be added to the website.

Well, it must be something else going on. Just tried to verify this again. Disabled software write protect and it still boots with AllowUnverifiedRo:always set…

But there must be something wrong with the recovery flow. After I flashed the stock firmware using the script, enabling AllowUnverifiedRo:always led to a “bricked” device that I had to recover with this:

1. Press and hold the Power button.
2. Press [F2] twice.
3. Release the Power button.
4. Repeat the above steps a second time.

Now that I think back I did one more thing. I performed a recovery using Wifi after temporarily disabling RO verification with the above method. Does that rewrite the firmware?

Adding one more thing: It couldn’t have been fixed by the wifi recovery. Because that took a while (I guess longer than the 15 minutes) and after it finished the device was bricked again due to RO verification and I had to repeat the key combination.

I should have done a read of the entire SPI flash via the Suzyqable in the bricked state. But I didn’t, so now I can’t compare if anything in the RO section is actually different now that it works again.

Exact steps I took to best of my memory:

  1. use mrchromebox’s script to reflash the stock firmware (this was from the backup created by the script upon flashing the uefi firmware)
  2. script complained that it failed to re-enable software write protect (saying I might have to remove battery to make recovery work), but otherwise succeeded
  3. on first boot I got the the “scary” developer mode screen
  4. I inserted a recovery USB drive created from cros.tech
  5. reboot
  6. first recovery attempt failed at the very end
  7. I retried, this time it worked
  8. It booted into the normal (non-developer mode) setup.
  9. re-enabled developer mode
  10. issued ccd reset via Suzyqable
  11. tried to reboot but got nothing
  12. booted using the power button and f2 dance
  13. went into recovery mode and performed a WiFi recovery
  14. reboot didn’t work
  15. rebooted using power button and f2 dance
  16. it booted into non-developer mode
  17. reentered developer mode
  18. gsctool -a -o and pp button dance
  19. issued ccd reset factory via Suzyqable

next steps are troubleshooting:
20. flashrom --wp-region WP_RO --fmap
21. flashrom --wp-enable
22. successful reboot
23. set AllowUnverifiedRo:never
24. made sure to wait 15 minutes
25. successful boot
26. made the first post in this thread
27. flashrom --wp-disable
28. successful reboot
29. confusion
30. flashrom --wp-range 0,0
31. successful reboot
32. even more confusion
20. flashrom --wp-region WP_RO --fmap
21. flashrom --wp-enable

current flashrom --wp-status:

# flashrom --wp-status
flashrom v1.6.0-devel on Linux 6.6.88-08649-g7f9948e28f9a (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using default programmer "internal" with arguments "".
coreboot table found at 0x76845000.
Found chipset "Intel Alder Lake-N".
Enabling flash write... Warning: Setting BIOS Control at 0xdc from 0x8b to 0x89 failed.
New value is 0x8b.
SPI Configuration is locked down.
FREG0: Flash Descriptor region (0x00000000-0x00000fff) is read-only.
FREG1: BIOS region (0x003a0000-0x00ffffff) is read-write.
FREG2: Management Engine region (0x00001000-0x0039ffff) is read-only.
Not all flash regions are freely accessible by flashrom. This is most likely
due to an active ME. Please see https://flashrom.org/ME for details.
GPR0: Warning: 0x00001000-0x0014ffff is read-only.
At least some flash regions are write protected. For write operations,
you should use a flash layout and include only writable regions. See
manpage for more details.
OK.
Found GigaDevice flash chip "GD25Q128E/GD25B128E/GD25R128E/GD25Q127C" (16384 kB, Programmer-specific) on internal.
Protection range: start=0x00c00000 length=0x00400000 (upper 1/4)
Protection mode: hardware
SUCCESS

current ccd state:

ccd
State: Opened
Password: none
Flags: 0x00400004
Capabilities: 0x0000015555555555
  UartGscRxAPTx    Y 1=Always
  UartGscTxAPRx    Y 1=Always
  UartGscRxECTx    Y 1=Always
  UartGscTxECRx    Y 1=Always
  UartGscRxFpmcuTx Y 1=Always
  UartGscTxFpmcuRx Y 1=Always
  FlashAP          Y 1=Always
  FlashEC          Y 1=Always
  OverrideWP       Y 1=Always
  RebootECAP       Y 1=Always
  GscFullConsole   Y 1=Always
  UnlockNoReboot   Y 1=Always
  UnlockNoShortPP  Y 1=Always
  OpenNoTPMWipe    Y 1=Always
  OpenNoLongPP     Y 1=Always
  BatteryBypassPP  Y 1=Always
  I2C              Y 1=Always
  FlashRead        Y 1=Always
  OpenNoDevMode    Y 1=Always
  OpenFromUSB      Y 1=Always
  OverrideBatt     Y 1=Always
  AllowUnverifiedRo - 0=Default (Never)
Capabilities are modified.
TPM: dev_mode

Going back through my terminals scrollback buffer I do have some Ti50 console logs from the boot failures due to AllowUnverifiedRo:

*** Ti50 RESET ***
[       0.042] RBOX: assert EC_RST_L
[       0.042] cryptolib v0 at 0x80c00
[       0.046] 
[       0.051] RBOX: assert EC_RST_L
[       0.052] AP SPI WP register SR-1 is not correct! Got 00, expected to match 94 & fc
[       0.060] AP RO: NOT OK
[       0.062] AP RO verifications took 11 ms.
[       0.074] 21 files found across 5 pages.
[       0.075] 7086 bytes of data.
[       0.078] 0 invalid and 5 free pages.
[       0.082] 0 erases since boot.
[       0.086] Partition 

The log appears to complain specifically about the WP register…

I’m attaching the entire history of ccd logs I have. Unfortunately this does not go back far enough to show the first ccd reset. It starts with some boot failures due to AllowUnverifiedRo. It also shows one of the instances were RO verification got turned off for 15 minutes. I wasn’t running the Ti50 console the whole time unfortunately.

Here’s all the my scrollback buffer has to offer: OverrideBatt - 0=Default (IfOpened) AllowUnverifiedRo - 0=Default (Neve - Pastebin.com

Ok, so I think RO verification does cover WP registers but the RO verification just isn’t triggered on every boot/reboot. My thinking is that the boots in 28 and 31 it just didn’t run RO verification. There is no message indicating successful RO verification in my logs (though I’m not sure if I had the Ti50 console running for 28 or 31).

Here’s what a successful RO verification looks like on the Ti50 console:

*** Ti50 RESET ***
[       0.042] cryptolib v0 at 0x80c00
[       0.042] 
[       0.047] Restoring AP RO verify status
[       0.049] AP RO: OK
[       0.051] AP RO verifications took 4 ms.
[       0.063] 21 files found across 6 pages.
[       0.064] 7094 bytes of data.
[       0.067] 0 invalid and 4 free pages.
[       0.071] 0 erases since boot.
[       0.074] Partition |   File ID   | Bank | Page | Size
[       0.079]      0x03    0x81000000      1    238    314
[       0.085]      0x03    

Here is a sequence of me powering the device off and then restarting it:

[    1585.370] RBOX: power button pressed
[    1587.636] RBOX: power button released
[    1589.613] Idle erase.
[    1589.712] PLT_RST_L ASSERTED
[    1590.617] Idle erase.
[    1598.012] RBOX: power button pressed
[    1598.169] RBOX: power button released
[    1598.357] PLT_RST_L DEASSERTED
[    1598.403] Deferring NV write.
[    1598.407] PinWeaver init
[    1598.639] PCR0 updated
[    1598.656] Deferring NV write.
[    1598.663] Deferring NV write.
[    1617.387] Kernel booted.

In this case no RO verification was done. This seems to confirm my suspicion that RO verification is not done on every boot of the AP. Maybe only on reboot of the Ti50 or if the previous RO verification failed.

There is a ap_ro_verify command on the Ti50 console:

> ap_ro_verify
ap_ro_verify
Addressing mode: 3byte
WPSR: expected values: 1: 94 & fc, 2: 00 & 41
System reset enforcement: Enabled (Latched: Yes)
APRV status: OK (0xfffff000)
Reboot pending at next AP power event: No
Pre MP validation supported: No

It talks about expected WPSR values.

this is 100% not true, if it were you wouldn’t be able to boot your device to flash it in the first place

Net every boot appears to invoke RO verification though. So far I have only seen RO verification performed after the Ti50 rebooted.

RO verification is exclusively a Ti50 function; CR50 does not support it

Well my device has Ti50.

What I mean is that simply rebooting the AP does not invoke RO verification. So far I have only seen RO verification performed when the Ti50 rebooted.

So I think the only reason boots 28 and 31 worked with software write protect registers altered is because RO verification was not performed. But if RO verification is perfomed it will check that software write protect registers are in the “correct” state.

@MrChromebox Do you have another explanation why a device that was failling RO verification was successfully completing RO verification after re-enabling software write protection without any flashing of the SPI flash?

and right before the failed AP RO there is a line in the logs specifically complaining about write protect registers:

[       0.052] AP SPI WP register SR-1 is not correct! Got 00, expected to match 94 & fc
[       0.060] AP RO: NOT OK
[       0.062] AP RO verifications took 11 ms.

Also the ap_ro_verify command on the Ti50 talks about expected WPSR values.

you’re saying two completely opposite things here, only one is correct.

this is obviously wrong.

AP RO verification requires the SW WP registers (range and enable) to be set properly.

Setting the AllowUnverifiedRo flag to always disables AP RO verification.

resetting the AllowUnverifiedRo flag requires SW WP to be properly set.

Ok, now I understand. My bad. When I wrote “AllowUnverifiedRo:always will fail to boot if software write protect is disabled”. What I meant was the opposite: “AllowUnverifiedRo:never will fail to boot if software write protect is disabled”

I’m sorry if that confused things. :face_with_peeking_eye:

AP RO verification requires the SW WP registers (range and enable) to be set properly.

Setting the AllowUnverifiedRo flag to always disables AP RO verification.

resetting the AllowUnverifiedRo flag requires SW WP to be properly set.

This is exactly what I was trying and unfortunately failing to say. It is unclear from the website that AP RO checks the state of the SW WP. I’m saying this should be added somewhere.