F-8628 - Scrub failed persistence key derivation

pull/577/head
Aidan Garske 2026-08-21 01:16:35 -07:00
parent d951cc6b63
commit 091a254c98
2 changed files with 51 additions and 0 deletions

View File

@ -209,6 +209,8 @@ static WC_INLINE int wmqb_read_header(const byte* buf, word32 buf_len,
}
#ifdef WOLFMQTT_BROKER_PERSIST_ENCRYPT
static void wmqb_force_zero(void* mem, word32 len);
/* Lazy-init key cache. Single-threaded broker - no lock needed. The
* application-provided derive_key hook fills 32 bytes on first request.
* The cache lives on the MqttBroker (broker->persist_key_cache /
@ -230,6 +232,8 @@ static int wmqb_get_key(MqttBroker* broker)
}
if (h->derive_key(h->ctx, broker->persist_key_cache,
(word32)sizeof(broker->persist_key_cache)) != 0) {
wmqb_force_zero(broker->persist_key_cache,
(word32)sizeof(broker->persist_key_cache));
return MQTT_CODE_ERROR_SYSTEM;
}
broker->persist_key_loaded = 1;

View File

@ -5968,6 +5968,50 @@ typedef struct PersistIterCapture {
int calls;
} PersistIterCapture;
#ifdef WOLFMQTT_BROKER_PERSIST_ENCRYPT
static int persist_test_put_noop(void* ctx, byte ns, const byte* key,
word16 key_len, const byte* blob, word32 blob_len)
{
(void)ctx;
(void)ns;
(void)key;
(void)key_len;
(void)blob;
(void)blob_len;
return MQTT_CODE_SUCCESS;
}
static int persist_test_derive_partial_failure(void* ctx, byte* out_key,
word32 key_len)
{
(void)ctx;
XMEMSET(out_key, 0xA5, key_len / 2);
return MQTT_CODE_ERROR_SYSTEM;
}
TEST(persist_failed_key_derivation_scrubs_cache)
{
MqttBroker broker;
MqttBrokerPersistHooks hooks;
int rc;
word32 i;
XMEMSET(&broker, 0, sizeof(broker));
XMEMSET(&hooks, 0, sizeof(hooks));
hooks.kv_put = persist_test_put_noop;
hooks.derive_key = persist_test_derive_partial_failure;
ASSERT_EQ(MQTT_CODE_SUCCESS, MqttBroker_SetPersistHooks(&broker, &hooks));
rc = BrokerPersist_PutOrphanSession(&broker, "client", 4, 60,
(WOLFMQTT_BROKER_TIME_T)1);
ASSERT_EQ(MQTT_CODE_ERROR_SYSTEM, rc);
ASSERT_EQ(0, broker.persist_key_loaded);
for (i = 0; i < (word32)sizeof(broker.persist_key_cache); i++) {
ASSERT_EQ(0, broker.persist_key_cache[i]);
}
}
#endif /* WOLFMQTT_BROKER_PERSIST_ENCRYPT */
static int persist_test_iter_cb(const byte* key, word16 key_len,
const byte* blob, word32 blob_len, void* ctx)
{
@ -6447,6 +6491,9 @@ int main(int argc, char** argv)
RUN_TEST(persist_root_readable_permissions_accepted);
RUN_TEST(persist_root_writable_permissions_rejected);
RUN_TEST(persist_put_rejects_existing_temp_symlink);
#ifdef WOLFMQTT_BROKER_PERSIST_ENCRYPT
RUN_TEST(persist_failed_key_derivation_scrubs_cache);
#endif
#endif
TEST_SUITE_END();