Skip to content

Commit 398de7f

Browse files
authored
Merge pull request #228 from bigbrett/cmac-kdf
Add support for wolfCrypt CMAC KDF
2 parents 35a983e + 6498766 commit 398de7f

19 files changed

+1035
-18
lines changed

benchmark/bench_modules/wh_bench_mod_all.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,12 @@ int wh_Bench_Mod_HmacSha3256Dma(whClientContext* client, whBenchOpContext* ctx,
165165
int wh_Bench_Mod_HkdfSha256(whClientContext* client, whBenchOpContext* ctx,
166166
int id, void* params);
167167

168+
/*
169+
* CMAC KDF benchmark module prototypes (wh_bench_mod_cmac_kdf.c)
170+
*/
171+
int wh_Bench_Mod_CmacKdf(whClientContext* client, whBenchOpContext* ctx, int id,
172+
void* params);
173+
168174
/*
169175
* ECC benchmark module prototypes (wh_bench_mod_ecc.c)
170176
*/
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
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+
#include "wh_bench_mod.h"
21+
#include "wolfhsm/wh_error.h"
22+
#include "wolfhsm/wh_client.h"
23+
#include "wolfhsm/wh_client_crypto.h"
24+
25+
#include "wolfssl/wolfcrypt/cmac.h"
26+
#include "wolfssl/wolfcrypt/kdf.h"
27+
28+
#if defined(WOLFHSM_CFG_BENCH_ENABLE)
29+
30+
#if defined(HAVE_CMAC_KDF) && defined(WOLFSSL_CMAC)
31+
32+
#define WH_BENCH_CMAC_KDF_OUT_SIZE 40
33+
34+
static int _benchCmacKdf(whClientContext* client, whBenchOpContext* ctx, int id,
35+
int devId)
36+
{
37+
/* Derivation inputs mirror the unit test vectors to provide realistic
38+
* message sizes while keeping the benchmark deterministic. */
39+
static const uint8_t cmacKdfSalt[] = {
40+
0x20, 0x51, 0xaf, 0x34, 0x76, 0x2e, 0xbe, 0x55, 0x6f, 0x72, 0xa5, 0xc6,
41+
0xed, 0xc7, 0x77, 0x1e, 0xb9, 0x24, 0x5f, 0xad, 0x76, 0xf0, 0x34, 0xbe};
42+
static const uint8_t cmacKdfZ[] = {
43+
0xae, 0x8e, 0x93, 0xc9, 0xc9, 0x91, 0xcf, 0x89, 0x6a, 0x49, 0x1a,
44+
0x89, 0x07, 0xdf, 0x4e, 0x4b, 0xe5, 0x18, 0x6a, 0xe4, 0x96, 0xcd,
45+
0x34, 0x0d, 0xc1, 0x9b, 0x23, 0x78, 0x21, 0xdb, 0x7b, 0x60};
46+
static const uint8_t cmacKdfFixedInfo[] = {
47+
0xa2, 0x59, 0xca, 0xe2, 0xc4, 0xa3, 0x6b, 0x89, 0x56, 0x3c, 0xb1, 0x48,
48+
0xc7, 0x82, 0x51, 0x34, 0x3b, 0xbf, 0xab, 0xdc, 0x13, 0xca, 0x7a, 0xc2,
49+
0x17, 0x1c, 0x2e, 0xb6, 0x02, 0x1f, 0x44, 0x77, 0xfe, 0xa3, 0x3b, 0x28,
50+
0x72, 0x4d, 0xa7, 0x21, 0xee, 0x08, 0x7b, 0xff, 0xd7, 0x94, 0xa1, 0x56,
51+
0x37, 0x54, 0xb4, 0x25, 0xa8, 0xd0, 0x9b, 0x3e, 0x0d, 0xa5, 0xff, 0xed};
52+
static const uint8_t label[] = "cmac-kdf-bench";
53+
54+
int ret = 0;
55+
whKeyId keyId;
56+
int i;
57+
58+
(void)devId;
59+
60+
for (i = 0; i < WOLFHSM_CFG_BENCH_KG_ITERS && ret == 0; i++) {
61+
int benchStartRet;
62+
int benchStopRet;
63+
64+
keyId = WH_KEYID_ERASED;
65+
66+
benchStartRet = wh_Bench_StartOp(ctx, id);
67+
ret = wh_Client_CmacKdfMakeCacheKey(
68+
client, WH_KEYID_ERASED, cmacKdfSalt, (uint32_t)sizeof(cmacKdfSalt),
69+
WH_KEYID_ERASED, cmacKdfZ, (uint32_t)sizeof(cmacKdfZ),
70+
cmacKdfFixedInfo, (uint32_t)sizeof(cmacKdfFixedInfo), &keyId,
71+
WH_NVM_FLAGS_NONE, label, (uint32_t)sizeof(label),
72+
WH_BENCH_CMAC_KDF_OUT_SIZE);
73+
benchStopRet = wh_Bench_StopOp(ctx, id);
74+
75+
if (benchStartRet != 0) {
76+
WH_BENCH_PRINTF("Failed to wh_Bench_StartOp %d\n", benchStartRet);
77+
ret = benchStartRet;
78+
break;
79+
}
80+
if (ret != 0) {
81+
WH_BENCH_PRINTF("Failed to wh_Client_CmacKdfMakeCacheKey %d\n",
82+
ret);
83+
break;
84+
}
85+
if (benchStopRet != 0) {
86+
WH_BENCH_PRINTF("Failed to wh_Bench_StopOp %d\n", benchStopRet);
87+
ret = benchStopRet;
88+
break;
89+
}
90+
91+
/* Evict the cached key to free resources for next iteration */
92+
ret = wh_Client_KeyEvict(client, keyId);
93+
if (ret != 0) {
94+
WH_BENCH_PRINTF("Failed to wh_Client_KeyEvict %d\n", ret);
95+
break;
96+
}
97+
}
98+
99+
return ret;
100+
}
101+
102+
int wh_Bench_Mod_CmacKdf(whClientContext* client, whBenchOpContext* ctx, int id,
103+
void* params)
104+
{
105+
(void)params;
106+
return _benchCmacKdf(client, ctx, id, WH_DEV_ID);
107+
}
108+
109+
#endif /* HAVE_CMAC_KDF && WOLFSSL_CMAC */
110+
111+
#endif /* WOLFHSM_CFG_BENCH_ENABLE */

benchmark/bench_modules/wh_bench_mod_hkdf.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#include "wh_bench_mod.h"
2121
#include "wolfhsm/wh_error.h"
22+
#include "wolfhsm/wh_client.h"
23+
#include "wolfhsm/wh_client_crypto.h"
2224

2325
#if !defined(WOLFHSM_CFG_NO_CRYPTO) && defined(WOLFHSM_CFG_BENCH_ENABLE)
2426
#include "wolfssl/wolfcrypt/hmac.h"
@@ -44,24 +46,26 @@ static int _benchHkdf(whClientContext* client, whBenchOpContext* ctx, int id,
4446
0x0a, 0x0b, 0x0c};
4547
static const uint8_t hkdf_info[] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4,
4648
0xf5, 0xf6, 0xf7, 0xf8, 0xf9};
47-
49+
static const uint8_t label[] = "hkdf-bench";
4850

4951
int ret = 0;
50-
uint8_t okm[WH_BENCH_HKDF_OKM_SIZE];
52+
whKeyId keyId;
5153
int i;
5254

53-
(void)client;
55+
(void)devId;
5456

5557
for (i = 0; i < WOLFHSM_CFG_BENCH_KG_ITERS && ret == 0; i++) {
5658
int benchStartRet;
5759
int benchStopRet;
5860

61+
keyId = WH_KEYID_ERASED;
62+
5963
benchStartRet = wh_Bench_StartOp(ctx, id);
60-
ret = wc_HKDF_ex(WC_SHA256, hkdf_ikm, (word32)sizeof(hkdf_ikm),
61-
hkdf_salt, (word32)sizeof(hkdf_salt), hkdf_info,
62-
(word32)sizeof(hkdf_info), okm, (word32)sizeof(okm),
63-
NULL, /* heap */
64-
devId);
64+
ret = wh_Client_HkdfMakeCacheKey(
65+
client, WC_SHA256, WH_KEYID_ERASED, hkdf_ikm,
66+
(uint32_t)sizeof(hkdf_ikm), hkdf_salt, (uint32_t)sizeof(hkdf_salt),
67+
hkdf_info, (uint32_t)sizeof(hkdf_info), &keyId, WH_NVM_FLAGS_NONE,
68+
label, (uint32_t)sizeof(label), WH_BENCH_HKDF_OKM_SIZE);
6569
benchStopRet = wh_Bench_StopOp(ctx, id);
6670

6771
if (benchStartRet != 0) {
@@ -70,14 +74,21 @@ static int _benchHkdf(whClientContext* client, whBenchOpContext* ctx, int id,
7074
break;
7175
}
7276
if (ret != 0) {
73-
WH_BENCH_PRINTF("Failed to wc_HKDF_ex %d\n", ret);
77+
WH_BENCH_PRINTF("Failed to wh_Client_HkdfMakeCacheKey %d\n", ret);
7478
break;
7579
}
7680
if (benchStopRet != 0) {
7781
WH_BENCH_PRINTF("Failed to wh_Bench_StopOp %d\n", benchStopRet);
7882
ret = benchStopRet;
7983
break;
8084
}
85+
86+
/* Evict the cached key to free resources for next iteration */
87+
ret = wh_Client_KeyEvict(client, keyId);
88+
if (ret != 0) {
89+
WH_BENCH_PRINTF("Failed to wh_Client_KeyEvict %d\n", ret);
90+
break;
91+
}
8192
}
8293

8394
return ret;

benchmark/config/user_settings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ extern "C" {
157157

158158
/** Composite features */
159159
#define HAVE_HKDF
160+
#define HAVE_CMAC_KDF
160161

161162
/* Remove unneeded crypto */
162163
#define NO_DSA

benchmark/wh_bench.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ typedef enum BenchModuleIdx {
167167
BENCH_MODULE_IDX_HKDF_SHA2_256,
168168
#endif /* HAVE_HKDF */
169169

170+
/* CMAC KDF */
171+
#if defined(HAVE_CMAC_KDF) && defined(WOLFSSL_CMAC)
172+
BENCH_MODULE_IDX_CMAC_KDF,
173+
#endif /* HAVE_CMAC_KDF && WOLFSSL_CMAC */
174+
170175
/* ECC */
171176
#if defined(HAVE_ECC)
172177
BENCH_MODULE_IDX_ECC_P256_SIGN,
@@ -335,6 +340,11 @@ static BenchModule g_benchModules[] = {
335340
[BENCH_MODULE_IDX_HKDF_SHA2_256] = {"HKDF-SHA2-256", wh_Bench_Mod_HkdfSha256, BENCH_THROUGHPUT_OPS, 0, NULL},
336341
#endif /* HAVE_HKDF */
337342

343+
/* CMAC KDF */
344+
#if defined(HAVE_CMAC_KDF) && defined(WOLFSSL_CMAC)
345+
[BENCH_MODULE_IDX_CMAC_KDF] = {"CMAC-KDF-AES", wh_Bench_Mod_CmacKdf, BENCH_THROUGHPUT_OPS, 0, NULL},
346+
#endif /* HAVE_CMAC_KDF && WOLFSSL_CMAC */
347+
338348
/* ECC */
339349
#if defined(HAVE_ECC)
340350
[BENCH_MODULE_IDX_ECC_P256_SIGN] = {"ECC-P256-SIGN", wh_Bench_Mod_EccP256Sign, BENCH_THROUGHPUT_OPS, 0, NULL},

benchmark/wh_bench_ops.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include <stdint.h>
2727

2828
/* Maximum number of operations that can be registered */
29-
#define MAX_BENCH_OPS 88
29+
#define MAX_BENCH_OPS 89
3030
/* Maximum length of operation name */
3131
#define MAX_OP_NAME 64
3232

examples/demo/client/wh_demo_client_all.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,23 @@ int wh_DemoClient_All(whClientContext* clientContext)
132132
}
133133
#endif /* HAVE_HKDF */
134134

135+
#if defined(HAVE_CMAC_KDF) && defined(WOLFSSL_CMAC)
136+
rc = wh_DemoClient_CryptoCmacKdfExport(clientContext);
137+
if (rc != 0) {
138+
return rc;
139+
}
140+
141+
rc = wh_DemoClient_CryptoCmacKdfCache(clientContext);
142+
if (rc != 0) {
143+
return rc;
144+
}
145+
146+
rc = wh_DemoClient_CryptoCmacKdfCacheInputs(clientContext);
147+
if (rc != 0) {
148+
return rc;
149+
}
150+
#endif /* HAVE_CMAC_KDF && WOLFSSL_CMAC */
151+
135152
#if defined(WOLFSSL_CMAC)
136153
rc = wh_DemoClient_CryptoCmac(clientContext);
137154
if (rc != 0) {

0 commit comments

Comments
 (0)