mirror of https://github.com/wolfSSL/wolfBoot.git
pkcs11 store: tighten power-fail assert, rebase F4 footprint limits
vault_obj_read() now separates "object absent" from a failed read, so the power-fail test rejects a corrupted vault instead of accepting any negative. hal_cache_invalidate() shrank 120 -> 44 bytes; the 48 it still costs every STM32F407 build is folded into the test-size-all limits.pull/873/head
parent
9b06b907f8
commit
3d5bebeefe
|
|
@ -196,26 +196,28 @@ void RAMFUNCTION hal_flash_unlock(void)
|
|||
FLASH_KEYR = FLASH_KEY2;
|
||||
}
|
||||
|
||||
#if ((FLASH_ACR_ENABLE_INST_CACHE << 2) != FLASH_ACR_RESET_INST_CACHE) || \
|
||||
((FLASH_ACR_ENABLE_DATA_CACHE << 2) != FLASH_ACR_RESET_DATA_CACHE)
|
||||
#error "STM32F4: flash cache reset bits are not two positions above the enables"
|
||||
#endif
|
||||
/* RM0090 3.5.1: the instruction and data caches keep lines fetched before an
|
||||
* erase/program, so a read-back through the flash memory map can return
|
||||
* pre-erase bytes. The reset bits are only writable while the corresponding
|
||||
* cache is disabled, hence the disable/reset/re-enable dance. */
|
||||
* pre-erase bytes. A cache reset bit is only writable while its cache is
|
||||
* disabled, and the reset bits sit two positions above the enable bits
|
||||
* (ICEN 9 -> ICRST 11, DCEN 10 -> DCRST 12), so one shift covers both. */
|
||||
void RAMFUNCTION hal_cache_invalidate(void)
|
||||
{
|
||||
uint32_t acr = FLASH_ACR;
|
||||
uint32_t en = acr & (FLASH_ACR_ENABLE_INST_CACHE |
|
||||
FLASH_ACR_ENABLE_DATA_CACHE);
|
||||
uint32_t off = acr & ~en;
|
||||
|
||||
if (acr & FLASH_ACR_ENABLE_INST_CACHE) {
|
||||
FLASH_ACR &= ~FLASH_ACR_ENABLE_INST_CACHE;
|
||||
FLASH_ACR |= FLASH_ACR_RESET_INST_CACHE;
|
||||
FLASH_ACR &= ~FLASH_ACR_RESET_INST_CACHE;
|
||||
FLASH_ACR |= FLASH_ACR_ENABLE_INST_CACHE;
|
||||
}
|
||||
if (acr & FLASH_ACR_ENABLE_DATA_CACHE) {
|
||||
FLASH_ACR &= ~FLASH_ACR_ENABLE_DATA_CACHE;
|
||||
FLASH_ACR |= FLASH_ACR_RESET_DATA_CACHE;
|
||||
FLASH_ACR &= ~FLASH_ACR_RESET_DATA_CACHE;
|
||||
FLASH_ACR |= FLASH_ACR_ENABLE_DATA_CACHE;
|
||||
}
|
||||
if (en == 0)
|
||||
return;
|
||||
FLASH_ACR = off; /* disable the caches that were on */
|
||||
FLASH_ACR = off | (en << 2); /* set their reset bits */
|
||||
FLASH_ACR = off; /* release reset */
|
||||
FLASH_ACR = acr; /* restore the original enables */
|
||||
}
|
||||
|
||||
void RAMFUNCTION hal_flash_lock(void)
|
||||
|
|
|
|||
|
|
@ -98,26 +98,27 @@ void RAMFUNCTION hal_flash_unlock(void)
|
|||
}
|
||||
}
|
||||
|
||||
#if ((FLASH_ACR_ICEN << 2) != FLASH_ACR_ICRST) || \
|
||||
((FLASH_ACR_DCEN << 2) != FLASH_ACR_DCRST)
|
||||
#error "STM32G4: flash cache reset bits are not two positions above the enables"
|
||||
#endif
|
||||
/* RM0440 3.3.3: the instruction and data caches keep lines fetched before an
|
||||
* erase/program, so a read-back through the flash memory map can return
|
||||
* pre-erase bytes. The reset bits are only writable while the corresponding
|
||||
* cache is disabled, hence the disable/reset/re-enable dance. */
|
||||
* pre-erase bytes. A cache reset bit is only writable while its cache is
|
||||
* disabled, and the reset bits sit two positions above the enable bits
|
||||
* (ICEN 9 -> ICRST 11, DCEN 10 -> DCRST 12), so one shift covers both. */
|
||||
void RAMFUNCTION hal_cache_invalidate(void)
|
||||
{
|
||||
uint32_t acr = FLASH_ACR;
|
||||
uint32_t en = acr & (FLASH_ACR_ICEN | FLASH_ACR_DCEN);
|
||||
uint32_t off = acr & ~en;
|
||||
|
||||
if (acr & FLASH_ACR_ICEN) {
|
||||
FLASH_ACR &= ~FLASH_ACR_ICEN;
|
||||
FLASH_ACR |= FLASH_ACR_ICRST;
|
||||
FLASH_ACR &= ~FLASH_ACR_ICRST;
|
||||
FLASH_ACR |= FLASH_ACR_ICEN;
|
||||
}
|
||||
if (acr & FLASH_ACR_DCEN) {
|
||||
FLASH_ACR &= ~FLASH_ACR_DCEN;
|
||||
FLASH_ACR |= FLASH_ACR_DCRST;
|
||||
FLASH_ACR &= ~FLASH_ACR_DCRST;
|
||||
FLASH_ACR |= FLASH_ACR_DCEN;
|
||||
}
|
||||
if (en == 0)
|
||||
return;
|
||||
FLASH_ACR = off; /* disable the caches that were on */
|
||||
FLASH_ACR = off | (en << 2); /* set their reset bits */
|
||||
FLASH_ACR = off; /* release reset */
|
||||
FLASH_ACR = acr; /* restore the original enables */
|
||||
}
|
||||
|
||||
void RAMFUNCTION hal_flash_lock(void)
|
||||
|
|
|
|||
|
|
@ -1231,55 +1231,57 @@ test-size-all:
|
|||
# Several limits below are raised relative to upstream. This branch bumps
|
||||
# lib/wolfssl to the ti_c25 merge for CHAR_BIT!=8 wide-byte support, which
|
||||
# costs 4-48 bytes depending on configuration (most of it in the no-ASM
|
||||
# SP-math and ML-DSA paths). No wolfBoot code changed in these builds, and
|
||||
# each new value is the measured size, matching upstream's convention.
|
||||
# SP-math and ML-DSA paths). On top of that, every entry here is an
|
||||
# STM32F407 build, so each one also carries the flat 48 bytes of
|
||||
# hal_cache_invalidate() and its call from hal_flash_lock(). Each value
|
||||
# is the measured size, matching upstream's convention.
|
||||
# Measured with the CI container (ghcr.io/wolfssl/wolfboot-ci-arm).
|
||||
make test-size SIGN=NONE LIMIT=5116 NO_ARM_ASM=1
|
||||
make test-size SIGN=NONE LIMIT=5164 NO_ARM_ASM=1
|
||||
make keysclean
|
||||
make test-size SIGN=ED25519 LIMIT=12228 NO_ARM_ASM=1
|
||||
make test-size SIGN=ED25519 LIMIT=12276 NO_ARM_ASM=1
|
||||
make keysclean
|
||||
make test-size SIGN=ECC256 LIMIT=18924 NO_ARM_ASM=1
|
||||
make test-size SIGN=ECC256 LIMIT=18972 NO_ARM_ASM=1
|
||||
make clean
|
||||
make test-size SIGN=ECC256 NO_ASM=1 LIMIT=13968 NO_ARM_ASM=1
|
||||
make test-size SIGN=ECC256 NO_ASM=1 LIMIT=14016 NO_ARM_ASM=1
|
||||
make keysclean
|
||||
make test-size SIGN=RSA2048 LIMIT=11816 NO_ARM_ASM=1
|
||||
make test-size SIGN=RSA2048 LIMIT=11864 NO_ARM_ASM=1
|
||||
make clean
|
||||
make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=12372 NO_ARM_ASM=1
|
||||
make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=12412 NO_ARM_ASM=1
|
||||
make keysclean
|
||||
make test-size SIGN=RSA4096 LIMIT=12116 NO_ARM_ASM=1
|
||||
make test-size SIGN=RSA4096 LIMIT=12164 NO_ARM_ASM=1
|
||||
make clean
|
||||
make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=12660 NO_ARM_ASM=1
|
||||
make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=12708 NO_ARM_ASM=1
|
||||
make keysclean
|
||||
make test-size SIGN=ECC384 LIMIT=19608 NO_ARM_ASM=1
|
||||
make test-size SIGN=ECC384 LIMIT=19656 NO_ARM_ASM=1
|
||||
make clean
|
||||
make test-size SIGN=ECC384 NO_ASM=1 LIMIT=15328 NO_ARM_ASM=1
|
||||
make test-size SIGN=ECC384 NO_ASM=1 LIMIT=15376 NO_ARM_ASM=1
|
||||
make keysclean
|
||||
make test-size SIGN=ED448 LIMIT=14256 NO_ARM_ASM=1
|
||||
make test-size SIGN=ED448 LIMIT=14288 NO_ARM_ASM=1
|
||||
make keysclean
|
||||
make test-size SIGN=RSA3072 LIMIT=11956 NO_ARM_ASM=1
|
||||
make test-size SIGN=RSA3072 LIMIT=12004 NO_ARM_ASM=1
|
||||
make clean
|
||||
make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=12480 NO_ARM_ASM=1
|
||||
make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=12528 NO_ARM_ASM=1
|
||||
make keysclean
|
||||
make test-size SIGN=RSAPSS2048 LIMIT=13748 NO_ARM_ASM=1
|
||||
make test-size SIGN=RSAPSS2048 LIMIT=13796 NO_ARM_ASM=1
|
||||
make clean
|
||||
make test-size SIGN=RSAPSS2048 NO_ASM=1 LIMIT=14304 NO_ARM_ASM=1
|
||||
make test-size SIGN=RSAPSS2048 NO_ASM=1 LIMIT=14344 NO_ARM_ASM=1
|
||||
make keysclean
|
||||
make test-size SIGN=RSAPSS3072 LIMIT=13916 NO_ARM_ASM=1
|
||||
make test-size SIGN=RSAPSS3072 LIMIT=13964 NO_ARM_ASM=1
|
||||
make clean
|
||||
make test-size SIGN=RSAPSS3072 NO_ASM=1 LIMIT=14436 NO_ARM_ASM=1
|
||||
make test-size SIGN=RSAPSS3072 NO_ASM=1 LIMIT=14484 NO_ARM_ASM=1
|
||||
make keysclean
|
||||
make test-size SIGN=RSAPSS4096 LIMIT=14088 NO_ARM_ASM=1
|
||||
make test-size SIGN=RSAPSS4096 LIMIT=14136 NO_ARM_ASM=1
|
||||
make clean
|
||||
make test-size SIGN=RSAPSS4096 NO_ASM=1 LIMIT=14628 NO_ARM_ASM=1
|
||||
make test-size SIGN=RSAPSS4096 NO_ASM=1 LIMIT=14676 NO_ARM_ASM=1
|
||||
make keysclean
|
||||
make test-size SIGN=LMS LMS_LEVELS=2 LMS_HEIGHT=5 LMS_WINTERNITZ=8 \
|
||||
WOLFBOOT_SMALL_STACK=0 IMAGE_SIGNATURE_SIZE=2644 \
|
||||
IMAGE_HEADER_SIZE?=5288 LIMIT=8120 NO_ARM_ASM=1
|
||||
IMAGE_HEADER_SIZE?=5288 LIMIT=8168 NO_ARM_ASM=1
|
||||
make keysclean
|
||||
make test-size SIGN=XMSS XMSS_PARAMS='XMSS-SHA2_10_256' \
|
||||
IMAGE_SIGNATURE_SIZE=2500 IMAGE_HEADER_SIZE?=4096 \
|
||||
LIMIT=8772 NO_ARM_ASM=1
|
||||
LIMIT=8820 NO_ARM_ASM=1
|
||||
make keysclean
|
||||
make clean
|
||||
make test-size SIGN=ML_DSA ML_DSA_LEVEL=2 LIMIT=19630 \
|
||||
make test-size SIGN=ML_DSA ML_DSA_LEVEL=2 LIMIT=19678 \
|
||||
IMAGE_SIGNATURE_SIZE=2420 IMAGE_HEADER_SIZE?=8192
|
||||
|
|
|
|||
|
|
@ -766,14 +766,22 @@ static int vault_obj_write(int type, CK_ULONG tok, CK_ULONG obj,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* "The object is not in the vault" is a legitimate state after a power cut,
|
||||
* but any other open/read failure means the vault or its metadata is
|
||||
* damaged. Report the two distinctly so the power-fail test can insist on
|
||||
* the former and fail on the latter. */
|
||||
#define VAULT_OBJ_ABSENT (-1000)
|
||||
|
||||
static int vault_obj_read(int type, CK_ULONG tok, CK_ULONG obj,
|
||||
uint8_t *out, int max)
|
||||
{
|
||||
void *store = NULL;
|
||||
int ret = wolfPKCS11_Store_Open(type, tok, obj, 1, &store);
|
||||
|
||||
if (ret == NOT_AVAILABLE_E)
|
||||
return VAULT_OBJ_ABSENT;
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
return ret;
|
||||
ret = wolfPKCS11_Store_Read(store, out, max);
|
||||
wolfPKCS11_Store_Close(store);
|
||||
return ret;
|
||||
|
|
@ -846,9 +854,14 @@ START_TEST (test_power_fail_during_rewrite_never_mixes_generations) {
|
|||
"payload", crash);
|
||||
}
|
||||
else {
|
||||
ck_assert_msg(ret <= 0,
|
||||
"power fail at op %d: object read back %d bytes, neither "
|
||||
"generation nor empty", crash, ret);
|
||||
/* Only two other outcomes are crash-safe: the object was never
|
||||
* published, or it is present but truncated to empty by the
|
||||
* Open-time durability commit. Every other return (a negative
|
||||
* read error, or a partial payload length) means the vault came
|
||||
* back damaged. */
|
||||
ck_assert_msg(ret == VAULT_OBJ_ABSENT || ret == 0,
|
||||
"power fail at op %d: object read back %d, neither old "
|
||||
"payload, new payload, empty, nor absent", crash, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue