Skip to content

Commit 5498633

Browse files
committed
Implement timeout capability. Apply timeout to crypto response
1 parent 7eaba42 commit 5498633

File tree

11 files changed

+467
-179
lines changed

11 files changed

+467
-179
lines changed

src/wh_client.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ int wh_Client_Init(whClientContext* c, const whClientConfig* config)
8181
c->cancelCb = config->cancelCb;
8282
#endif
8383

84+
#ifdef WOLFHSM_CFG_ENABLE_TIMEOUT
85+
if (config->respTimeout != NULL) {
86+
rc = wh_Timeout_Init(c->respTimeout, config->respTimeout);
87+
if (rc != 0) {
88+
return rc;
89+
}
90+
}
91+
#endif
92+
8493
rc = wh_CommClient_Init(c->comm, config->comm);
8594

8695
#ifndef WOLFHSM_CFG_NO_CRYPTO
@@ -199,6 +208,31 @@ int wh_Client_RecvResponse(whClientContext *c,
199208
return rc;
200209
}
201210

211+
int wh_Client_RecvResponseTimeout(whClientContext *c,
212+
uint16_t *out_group, uint16_t *out_action,
213+
uint16_t *out_size, void* data, whTimeoutCtx *timeout)
214+
{
215+
int ret;
216+
217+
if ((c == NULL) || (timeout == NULL)) {
218+
return WH_ERROR_BADARGS;
219+
}
220+
221+
ret = wh_Timeout_Start(timeout);
222+
if (ret != WH_ERROR_OK) {
223+
return ret;
224+
}
225+
226+
do {
227+
ret = wh_Client_RecvResponse(c, out_group, out_action, out_size, data);
228+
if ((ret == WH_ERROR_NOTREADY) && wh_Timeout_Expired(timeout)) {
229+
return WH_ERROR_TIMEOUT;
230+
}
231+
} while (ret == WH_ERROR_NOTREADY);
232+
233+
return ret;
234+
}
235+
202236
int wh_Client_CommInitRequest(whClientContext* c)
203237
{
204238
whMessageCommInitRequest msg = {0};

src/wh_client_crypto.c

Lines changed: 100 additions & 179 deletions
Large diffs are not rendered by default.

src/wh_timeout.c

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright (C) 2025 wolfSSL Inc.
3+
*
4+
* This file is part of wolfHSM.
5+
*
6+
* wolfHSM is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation; either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* wolfHSM is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with wolfHSM. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
/*
20+
* src/wh_timeout.c
21+
*/
22+
23+
/* Pick up compile-time configuration */
24+
#include "wolfhsm/wh_settings.h"
25+
26+
#include "wolfhsm/wh_timeout.h"
27+
#include "wolfhsm/wh_error.h"
28+
29+
int wh_Timeout_Init(whTimeoutCtx* timeout, const whTimeoutConfig* config)
30+
{
31+
if ((timeout == NULL) || (config == NULL)) {
32+
return WH_ERROR_BADARGS;
33+
}
34+
35+
timeout->startUs = 0;
36+
timeout->timeoutUs = config->timeoutUs;
37+
timeout->expiredCb = config->expiredCb;
38+
timeout->cbCtx = config->cbCtx;
39+
40+
return WH_ERROR_OK;
41+
}
42+
43+
int wh_Timeout_Set(whTimeoutCtx* timeout, uint64_t timeoutUs)
44+
{
45+
if (timeout == NULL) {
46+
return WH_ERROR_BADARGS;
47+
}
48+
49+
timeout->timeoutUs = timeoutUs;
50+
51+
return WH_ERROR_OK;
52+
}
53+
54+
int wh_Timeout_Start(whTimeoutCtx* timeout)
55+
{
56+
if (timeout == NULL) {
57+
return WH_ERROR_BADARGS;
58+
}
59+
60+
if (timeout->timeoutUs == 0) {
61+
timeout->startUs = 0;
62+
return WH_ERROR_BADARGS;
63+
}
64+
65+
timeout->startUs = WH_GETTIME_US();
66+
67+
return WH_ERROR_OK;
68+
}
69+
70+
int wh_Timeout_Stop(whTimeoutCtx* timeout)
71+
{
72+
if (timeout == NULL) {
73+
return WH_ERROR_BADARGS;
74+
}
75+
76+
timeout->startUs = 0;
77+
timeout->timeoutUs = 0;
78+
79+
return WH_ERROR_OK;
80+
}
81+
82+
int wh_Timeout_Expired(const whTimeoutCtx* timeout)
83+
{
84+
uint64_t nowUs = 0;
85+
int expired = 0;
86+
87+
if (timeout == NULL) {
88+
return 0;
89+
}
90+
91+
if (timeout->timeoutUs == 0) {
92+
return 0;
93+
}
94+
95+
nowUs = WH_GETTIME_US();
96+
expired = (nowUs - timeout->startUs) >= timeout->timeoutUs;
97+
if (expired && (timeout->expiredCb != NULL)) {
98+
timeout->expiredCb(timeout->cbCtx);
99+
}
100+
return expired;
101+
}

test/config/wolfhsm_cfg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,6 @@
7171
/* Allow persistent NVM artifacts in tests */
7272
#define WOLFHSM_CFG_TEST_ALLOW_PERSISTENT_NVM_ARTIFACTS
7373

74+
#define WOLFHSM_CFG_ENABLE_TIMEOUT
75+
7476
#endif /* WOLFHSM_CFG_H_ */

test/wh_test.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "wh_test_keywrap.h"
4141
#include "wh_test_multiclient.h"
4242
#include "wh_test_log.h"
43+
#include "wh_test_timeout.h"
4344

4445
#if defined(WOLFHSM_CFG_CERTIFICATE_MANAGER)
4546
#include "wh_test_cert.h"
@@ -71,6 +72,9 @@ int whTest_Unit(void)
7172
/* Component Tests */
7273
WH_TEST_ASSERT(0 == whTest_Flash_RamSim());
7374
WH_TEST_ASSERT(0 == whTest_NvmFlash());
75+
#ifdef WOLFHSM_CFG_ENABLE_TIMEOUT
76+
WH_TEST_ASSERT(0 == whTest_Timeout());
77+
#endif
7478
#ifdef WOLFHSM_CFG_LOGGING
7579
WH_TEST_ASSERT(0 == whTest_Log());
7680
#endif

test/wh_test_timeout.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright (C) 2024 wolfSSL Inc.
3+
*
4+
* This file is part of wolfHSM.
5+
*
6+
* wolfHSM is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation; either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* wolfHSM is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with wolfHSM. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
/*
20+
* test/wh_test_timeout.c
21+
*
22+
*/
23+
24+
#include <stdint.h>
25+
26+
#include "wolfhsm/wh_settings.h"
27+
#include "wolfhsm/wh_timeout.h"
28+
#include "wolfhsm/wh_error.h"
29+
30+
#include "wh_test_common.h"
31+
#include "wh_test_timeout.h"
32+
33+
static void whTest_TimeoutCb(void* ctx)
34+
{
35+
int* counter = (int*)ctx;
36+
if (counter != NULL) {
37+
(*counter)++;
38+
}
39+
}
40+
41+
int whTest_Timeout(void)
42+
{
43+
int cb_count = 0;
44+
whTimeoutConfig cfg;
45+
whTimeoutCtx timeout[1];
46+
47+
cfg.timeoutUs = 1;
48+
cfg.expiredCb = whTest_TimeoutCb;
49+
cfg.cbCtx = &cb_count;
50+
51+
wh_Timeout_Init(timeout, &cfg);
52+
WH_TEST_ASSERT_RETURN(timeout->startUs == 0);
53+
WH_TEST_ASSERT_RETURN(timeout->timeoutUs == cfg.timeoutUs);
54+
WH_TEST_ASSERT_RETURN(timeout->expiredCb == cfg.expiredCb);
55+
WH_TEST_ASSERT_RETURN(timeout->cbCtx == cfg.cbCtx);
56+
57+
wh_Timeout_Start(timeout);
58+
WH_TEST_ASSERT_RETURN(timeout->timeoutUs > 0);
59+
60+
wh_Timeout_Stop(timeout);
61+
WH_TEST_ASSERT_RETURN(timeout->startUs == 0);
62+
WH_TEST_ASSERT_RETURN(timeout->timeoutUs == 0);
63+
64+
/* No expiration when disabled */
65+
WH_TEST_ASSERT_RETURN(wh_Timeout_Expired(timeout) == 0);
66+
67+
WH_TEST_ASSERT_RETURN(wh_Timeout_Init(0, 0) == WH_ERROR_BADARGS);
68+
WH_TEST_ASSERT_RETURN(wh_Timeout_Set(0, 0) == WH_ERROR_BADARGS);
69+
WH_TEST_ASSERT_RETURN(wh_Timeout_Start(0) == WH_ERROR_BADARGS);
70+
WH_TEST_ASSERT_RETURN(wh_Timeout_Stop(0) == WH_ERROR_BADARGS);
71+
WH_TEST_ASSERT_RETURN(wh_Timeout_Expired(0) == 0);
72+
73+
return 0;
74+
}

test/wh_test_timeout.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (C) 2024 wolfSSL Inc.
3+
*
4+
* This file is part of wolfHSM.
5+
*
6+
* wolfHSM is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation; either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* wolfHSM is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with wolfHSM. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
/*
20+
* test/wh_test_timeout.h
21+
*
22+
*/
23+
24+
#ifndef TEST_WH_TEST_TIMEOUT_H_
25+
#define TEST_WH_TEST_TIMEOUT_H_
26+
27+
/**
28+
* Runs timeout module tests.
29+
*
30+
* @return 0 on success and a non-zero error code on failure.
31+
*/
32+
int whTest_Timeout(void);
33+
34+
#endif /* TEST_WH_TEST_TIMEOUT_H_ */

wolfhsm/wh_client.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848

4949
/* Component includes */
5050
#include "wolfhsm/wh_comm.h"
51+
#include "wolfhsm/wh_timeout.h"
5152
#include "wolfhsm/wh_message_customcb.h"
5253
#ifdef WOLFHSM_CFG_DMA
5354
#include "wolfhsm/wh_dma.h"
@@ -121,6 +122,9 @@ struct whClientContext_t {
121122
uint8_t cancelable;
122123
whClientCancelCb cancelCb;
123124
#endif
125+
#ifdef WOLFHSM_CFG_ENABLE_TIMEOUT
126+
whTimeoutCtx respTimeout[1];
127+
#endif
124128
#ifdef WOLFHSM_CFG_DMA
125129
whClientDmaContext dma;
126130
#endif /* WOLFHSM_CFG_DMA */
@@ -135,6 +139,9 @@ struct whClientConfig_t {
135139
#ifdef WOLFHSM_CFG_DMA
136140
whClientDmaConfig* dmaConfig;
137141
#endif /* WOLFHSM_CFG_DMA */
142+
#ifdef WOLFHSM_CFG_ENABLE_TIMEOUT
143+
whTimeoutConfig* respTimeout;
144+
#endif /* WOLFHSM_CFG_ENABLE_TIMEOUT*/
138145
};
139146
typedef struct whClientConfig_t whClientConfig;
140147

@@ -193,6 +200,23 @@ int wh_Client_SendRequest(whClientContext* c, uint16_t group, uint16_t action,
193200
int wh_Client_RecvResponse(whClientContext* c, uint16_t* out_group,
194201
uint16_t* out_action, uint16_t* out_size,
195202
void* data);
203+
#ifdef WOLFHSM_CFG_ENABLE_TIMEOUT
204+
/**
205+
* Receives a response from the server with a timeout window.
206+
*
207+
* @param c The client context.
208+
* @param out_group Pointer to store the received group value.
209+
* @param out_action Pointer to store the received action value.
210+
* @param out_size Pointer to store the received size value.
211+
* @param data Pointer to store the received data.
212+
* @param timeout The timeout context to use.
213+
* @return 0 if successful, WH_ERROR_TIMEOUT on expiration, or a negative value
214+
* if an error occurred.
215+
*/
216+
int wh_Client_RecvResponseTimeout(whClientContext* c, uint16_t* out_group,
217+
uint16_t* out_action, uint16_t* out_size,
218+
void* data, whTimeoutCtx* timeout);
219+
#endif /* WOLFHSM_CFG_ENABLE_TIMEOUT */
196220

197221

198222
/** Comm component functions */

wolfhsm/wh_error.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ enum WH_ERROR_ENUM {
4545
compile-time configuration */
4646
WH_ERROR_USAGE =
4747
-2009, /* Operation not permitted based on object/key usage flags */
48+
WH_ERROR_TIMEOUT = -2010, /* Timeout occurred. */
4849

4950
/* NVM and keystore specific status returns */
5051
WH_ERROR_LOCKED = -2100, /* Unlock and retry if necessary */

wolfhsm/wh_settings.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@
5757
* WOLFHSM_CFG_ENABLE_SERVER - If defined, include server-specific
5858
* functionality
5959
*
60+
* WOLFHSM_CFG_ENABLE_TIMEOUT - If defined, include timeout helpers and
61+
* client response timeout support.
62+
*
6063
* WOLFHSM_CFG_NVM_OBJECT_COUNT - Number of objects in ram and disk directories
6164
* Default: 32
6265
*

0 commit comments

Comments
 (0)