@@ -317,6 +317,25 @@ static int _GetKeyCacheSlot(whKeyCacheContext* ctx, uint16_t keySz,
317317 }
318318 }
319319
320+ /* Last-resort fallback: every slot is occupied by an uncommitted
321+ * key (typical when many ephemeral keys are cached in succession
322+ * with no intervening commit). Reclaim the first non-erased slot
323+ * so the cache cannot saturate on transient state alone. Drops
324+ * the slot's in-flight contents; the caller's request gets the
325+ * slot fresh. */
326+ if (foundIndex == -1 ) {
327+ for (i = 0 ; i < WOLFHSM_CFG_SERVER_KEYCACHE_COUNT ; i ++ ) {
328+ if (ctx -> cache [i ].meta -> id != WH_KEYID_ERASED ) {
329+ evictRet =
330+ _EvictSlot (ctx -> cache [i ].buffer , ctx -> cache [i ].meta );
331+ if (evictRet == WH_ERROR_OK ) {
332+ foundIndex = i ;
333+ break ;
334+ }
335+ }
336+ }
337+ }
338+
320339 /* Zero slot and capture pointers */
321340 if (foundIndex >= 0 ) {
322341 memset (& ctx -> cache [foundIndex ], 0 , sizeof (whCacheSlot ));
@@ -347,6 +366,22 @@ static int _GetKeyCacheSlot(whKeyCacheContext* ctx, uint16_t keySz,
347366 }
348367 }
349368
369+ /* Last-resort fallback: reclaim any non-erased big-cache slot
370+ * when no committed slot is evictable. See the matching block in
371+ * the regular cache path above. */
372+ if (foundIndex == -1 ) {
373+ for (i = 0 ; i < WOLFHSM_CFG_SERVER_KEYCACHE_BIG_COUNT ; i ++ ) {
374+ if (ctx -> bigCache [i ].meta -> id != WH_KEYID_ERASED ) {
375+ evictRet = _EvictSlot (ctx -> bigCache [i ].buffer ,
376+ ctx -> bigCache [i ].meta );
377+ if (evictRet == WH_ERROR_OK ) {
378+ foundIndex = i ;
379+ break ;
380+ }
381+ }
382+ }
383+ }
384+
350385 /* Zero slot and capture pointers */
351386 if (foundIndex >= 0 ) {
352387 memset (& ctx -> bigCache [foundIndex ], 0 , sizeof (whBigCacheSlot ));
0 commit comments