Repository navigation
Conversation
hal_flash_write() never read the FLASH_SR error flags and returned 0 whatever happened. With TrustZone it also returned 0 for an address out of range, and without TrustZone it did not check the address at all. hal_flash_erase() failed only for a zero length or an address below the flash, and returned 0 for pages past the top of the flash. Check OPERR, PROGERR, WRPERR, PGAERR, SIZERR and PGSERR after each quad-word program and each page erase. On an error, clear PG or PER and the flags, and return -1. The status is read once before EOP is cleared, because clearing EOP writes the error flags back as well, which clears them. Both functions now return -1 for a negative length or a span that is not all inside the flash, before touching it. The STM32U5 write test now extracts hal_flash_erase() as well. Its flash is two 8 KB pages, and the mock hal_flash_wait_complete() erases the page selected in FLASH_CR on STRT. It can also fail one program or erase with chosen FLASH_SR flags, leaving the flash unchanged. The host register file cannot clear write-1-to-clear flags, so the mock sets FLASH_NS_SR to the result of each operation. New tests check that each error flag stops a write on the unit that set it and an erase on the page that set it, with PG or PER cleared, that other flags do not fail a write, and that ranges outside the flash are refused before anything changes. The error and range tests fail on the HAL without the checks.
The keyvault ignored the return values of hal_flash_erase() and hal_flash_write(), and wolfPKCS11_Store_Close() returns void, so a record that did not reach flash looked committed. wolfPKCS11 then had no reason to write it again. Count erase and program failures in cache_commit_entry(), restore_backup() and check_vault(). A store window records the count at wolfPKCS11_Store_Open(), and the new wolfPKCS11_Store_CloseCommit() returns BUFFER_E when it changed during the window. wolfPKCS11_Store_Remove() does the same. The sector cache is shared, so every window open during a failure reports it; a window that lost nothing only makes wolfPKCS11 write all records again. The commit sequence itself is unchanged. user_settings.h defines WOLFPKCS11_CUSTOM_STORE_CLOSE_COMMIT, so a wolfPKCS11 that supports it closes written records with wolfPKCS11_Store_CloseCommit() and marks the token for a full store when it fails. The pinned wolfPKCS11 ignores the define and keeps calling wolfPKCS11_Store_Close(). docs/HAL.md now says that hal_flash_erase() returns non-zero on failure, and why the keyvault needs both functions to check the flash error flags.
The mock flash gains hal_flash_erase_fail, a one-shot erase failure like hal_flash_write_fail. New tests check that a failed write or erase while a window commits fails its close and not the next window's, that a failure is reported by every window open at the time but not by one opened later, that wolfPKCS11_Store_Remove() reports a failure and returns NOT_AVAILABLE_E only for a missing object, and that failures while Store_Open formats a blank vault or restores the header from the backup sector belong to that window. They fail on the store without failure tracking.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A flash erase or program that fails while the PKCS#11 keyvault (
src/pkcs11_store.c) commits a record went unnoticed. The store ignored the return values ofhal_flash_erase()andhal_flash_write(), wolfPKCS11'swolfPKCS11_Store_Close()returnsvoid, and on STM32U5 the HAL returned 0 anyway. wolfPKCS11 therefore treated the record as stored and did not write it again (since wolfSSL/wolfPKCS11#257 it only rewrites everything after a store that failed).pkcs11_store: erase and program failures in
cache_commit_entry(),restore_backup()andcheck_vault()are counted. A store window records the count atwolfPKCS11_Store_Open(), and the newwolfPKCS11_Store_CloseCommit()returnsBUFFER_Ewhen it changed during the window.wolfPKCS11_Store_Remove()does the same. The sector cache is shared, so every window open during a failure reports it; a window that lost nothing only makes wolfPKCS11 write all records again. The commit sequence itself (backup sector, then destination) is unchanged.user_settings.hdefinesWOLFPKCS11_CUSTOM_STORE_CLOSE_COMMIT, which wolfSSL/wolfPKCS11#265 adds: a wolfPKCS11 with it closes written records throughwolfPKCS11_Store_CloseCommit()and writes the token again after a failure. The pinned wolfPKCS11 ignores the define and keeps callingwolfPKCS11_Store_Close(), so this can merge before or after it.stm32u5:
hal_flash_write()andhal_flash_erase()now check OPERR, PROGERR, WRPERR, PGAERR, SIZERR and PGSERR after each quad-word and each page, clear PG or PER and the flags, and return -1. The status is read before EOP is cleared, since clearing EOP writes the error flags back and clears them too. Both return -1 for a negative length or a span not inside the flash, wherehal_flash_write()used to return 0 (TrustZone) or not check at all, andhal_flash_erase()returned 0 for pages past the top.docs/HAL.mdnotes thathal_flash_erase()returns non-zero on failure and that the keyvault depends on both functions checking the error flags.Testing:
unit-stm32u5-writealso extractshal_flash_erase(). Its mock wait erases pages and can fail one operation with chosen flags. New tests cover each error flag for write and erase, flags that are not errors, and out-of-range spans. The error and range tests fail on the HAL without the checks.unit-pkcs11_store(and-stalecache): new tests cover a failed write or erase in a window's close, a failure seen by every open window but not by a later one,wolfPKCS11_Store_Remove(), and failures while formatting the vault or restoring the header from the backup sector. They fail on the store without the tracking. The mock flash gains a one-shothal_flash_erase_fail.wolfboot-ci-sim:v1.0, gives the same results on master and on this branch (223 pass; the same 7 tests fail on both for lack of tools or SDKs in that image).wolfboot-ci-m33mu:v1.25, thestm32h5-tzPKCS11_TESTAPP=1run passes andstm32u5-wolfcrypt-tz.configbuilds, with the pinned wolfPKCS11 and with Let custom stores report records that did not commit wolfPKCS11#265 (which then callswolfPKCS11_Store_CloseCommit()).ZD 21908