Coverage Report

Created: 2026-11-12 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math-all/wolfcrypt/src/hmac.c
Line
Count
Source
1
/* hmac.c
2
 *
3
 * Copyright (C) 2006-2026 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
23
/*
24
 * HMAC Build Options:
25
 *
26
 * NO_HMAC:                  Disable HMAC support entirely         default: off
27
 * HAVE_HKDF:                Enable HKDF (RFC 5869) key derivation default: off
28
 * WOLFSSL_HMAC_COPY_HASH:   Copy hash state instead of re-init   default: off
29
 *                            for HMAC operations (performance)
30
 * STM32_HMAC:               STM32 hardware HMAC acceleration     default: off
31
 *
32
 * Hardware Acceleration (HMAC-specific):
33
 * WC_ASYNC_ENABLE_HMAC:     Enable async HMAC operations          default: off
34
 * WOLFSSL_DEVCRYPTO_HMAC:   /dev/crypto HMAC acceleration        default: off
35
 * WOLFSSL_KCAPI_HMAC:       Linux kernel crypto API for HMAC     default: off
36
 */
37
38
#define WC_FIPS_LL_CRYPTO
39
#define _WC_BUILDING_HMAC_C
40
41
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
42
43
#ifndef NO_HMAC
44
45
#if FIPS_VERSION3_GE(2,0,0)
46
    #if defined(USE_WINDOWS_API) && defined(_MSC_VER)
47
        #pragma code_seg(".fipsA$g")
48
        #pragma const_seg(".fipsB$g")
49
    #endif
50
#endif
51
52
#include <wolfssl/wolfcrypt/hmac.h>
53
54
#ifdef WOLF_CRYPTO_CB
55
    #include <wolfssl/wolfcrypt/cryptocb.h>
56
57
    /* Is this HMAC a cryptocb candidate? WOLF_CRYPTO_CB_FIND can map any id
58
     * (INVALID_DEVID included) to a device, so every HMAC qualifies there. */
59
    #ifdef WOLF_CRYPTO_CB_FIND
60
        #define WC_HMAC_USE_CRYPTOCB(hmac)  1
61
    #else
62
186k
        #define WC_HMAC_USE_CRYPTOCB(hmac)  ((hmac)->devId != INVALID_DEVID)
63
    #endif
64
#endif
65
66
#ifdef NO_INLINE
67
    #include <wolfssl/wolfcrypt/misc.h>
68
#else
69
    #define WOLFSSL_MISC_INCLUDED
70
    #include <wolfcrypt/src/misc.c>
71
#endif
72
73
#ifdef WOLFSSL_KCAPI_HMAC
74
    #include <wolfssl/wolfcrypt/port/kcapi/kcapi_hmac.h>
75
76
    /* map the _Software calls used by kcapi_hmac.c */
77
    #define wc_HmacSetKey  wc_HmacSetKey_Software
78
    #define wc_HmacUpdate  wc_HmacUpdate_Software
79
    #define wc_HmacFinal   wc_HmacFinal_Software
80
#endif
81
82
#if FIPS_VERSION3_GE(6,0,0)
83
    const unsigned int wolfCrypt_FIPS_hmac_ro_sanity[2] =
84
                                                     { 0x1a2b3c4d, 0x00000008 };
85
    int wolfCrypt_FIPS_HMAC_sanity(void)
86
    {
87
        return 0;
88
    }
89
#endif
90
91
int wc_HmacSizeByType(int type)
92
1.58k
{
93
1.58k
    int ret;
94
95
1.58k
    if (!(type == WC_MD5 || type == WC_SHA ||
96
1.42k
    #ifdef WOLFSSL_SM3
97
1.42k
            type == WC_SM3 ||
98
1.42k
    #endif
99
1.42k
    #ifndef WOLFSSL_NOSHA512_224
100
1.42k
            type == WC_SHA512_224 ||
101
1.42k
    #endif
102
1.42k
    #ifndef WOLFSSL_NOSHA512_256
103
1.42k
            type == WC_SHA512_256 ||
104
1.42k
    #endif
105
1.42k
            type == WC_SHA224 || type == WC_SHA256 ||
106
269
            type == WC_SHA384 || type == WC_SHA512 ||
107
8
            type == WC_SHA3_224 || type == WC_SHA3_256 ||
108
8
            type == WC_SHA3_384 || type == WC_SHA3_512)) {
109
8
        return BAD_FUNC_ARG;
110
8
    }
111
112
1.57k
    switch (type) {
113
0
    #ifndef NO_MD5
114
31
        case WC_MD5:
115
31
            ret = WC_MD5_DIGEST_SIZE;
116
31
            break;
117
0
    #endif /* !NO_MD5 */
118
119
0
    #ifndef NO_SHA
120
128
        case WC_SHA:
121
128
            ret = WC_SHA_DIGEST_SIZE;
122
128
            break;
123
0
    #endif /* !NO_SHA */
124
125
0
    #ifdef WOLFSSL_SHA224
126
105
        case WC_SHA224:
127
105
            ret = WC_SHA224_DIGEST_SIZE;
128
105
            break;
129
0
    #endif /* WOLFSSL_SHA224 */
130
131
0
    #ifndef NO_SHA256
132
1.04k
        case WC_SHA256:
133
1.04k
            ret = WC_SHA256_DIGEST_SIZE;
134
1.04k
            break;
135
0
    #endif /* !NO_SHA256 */
136
137
0
    #ifdef WOLFSSL_SHA384
138
135
        case WC_SHA384:
139
135
            ret = WC_SHA384_DIGEST_SIZE;
140
135
            break;
141
0
    #endif /* WOLFSSL_SHA384 */
142
0
    #ifdef WOLFSSL_SHA512
143
126
        case WC_SHA512:
144
126
            ret = WC_SHA512_DIGEST_SIZE;
145
126
            break;
146
0
    #ifndef WOLFSSL_NOSHA512_224
147
0
        case WC_SHA512_224:
148
0
            ret = WC_SHA512_224_DIGEST_SIZE;
149
0
            break;
150
0
    #endif
151
0
    #ifndef WOLFSSL_NOSHA512_256
152
0
        case WC_SHA512_256:
153
0
            ret = WC_SHA512_256_DIGEST_SIZE;
154
0
            break;
155
0
    #endif
156
0
    #endif /* WOLFSSL_SHA512 */
157
158
0
    #ifdef WOLFSSL_SHA3
159
0
        case WC_SHA3_224:
160
0
            ret = WC_SHA3_224_DIGEST_SIZE;
161
0
            break;
162
163
0
        case WC_SHA3_256:
164
0
            ret = WC_SHA3_256_DIGEST_SIZE;
165
0
            break;
166
167
0
        case WC_SHA3_384:
168
0
            ret = WC_SHA3_384_DIGEST_SIZE;
169
0
            break;
170
171
0
        case WC_SHA3_512:
172
0
            ret = WC_SHA3_512_DIGEST_SIZE;
173
0
            break;
174
0
    #endif /* WOLFSSL_SHA3 */
175
176
0
    #ifdef WOLFSSL_SM3
177
0
        case WC_SM3:
178
0
            ret = WC_SM3_DIGEST_SIZE;
179
0
            break;
180
0
    #endif
181
182
0
        default:
183
0
            ret = BAD_FUNC_ARG;
184
0
            break;
185
1.57k
    }
186
187
1.57k
    return ret;
188
1.57k
}
189
190
static int HmacKeyInitHash(wc_HmacHash* hash, int type, void* heap, int devId)
191
15.2k
{
192
15.2k
    int ret = 0;
193
194
15.2k
    switch (type) {
195
0
    #ifndef NO_MD5
196
552
        case WC_MD5:
197
552
            ret = wc_InitMd5_ex(&hash->md5, heap, devId);
198
552
            break;
199
0
    #endif /* !NO_MD5 */
200
201
0
    #ifndef NO_SHA
202
2.72k
        case WC_SHA:
203
2.72k
            ret = wc_InitSha_ex(&hash->sha, heap, devId);
204
2.72k
            break;
205
0
    #endif /* !NO_SHA */
206
207
0
    #ifdef WOLFSSL_SHA224
208
582
        case WC_SHA224:
209
582
            ret = wc_InitSha224_ex(&hash->sha224, heap, devId);
210
582
            break;
211
0
    #endif /* WOLFSSL_SHA224 */
212
213
0
    #ifndef NO_SHA256
214
2.09k
        case WC_SHA256:
215
2.09k
            ret = wc_InitSha256_ex(&hash->sha256, heap, devId);
216
2.09k
            break;
217
0
    #endif /* !NO_SHA256 */
218
219
0
    #ifdef WOLFSSL_SHA384
220
3.38k
        case WC_SHA384:
221
3.38k
            ret = wc_InitSha384_ex(&hash->sha384, heap, devId);
222
3.38k
            break;
223
0
    #endif /* WOLFSSL_SHA384 */
224
0
    #ifdef WOLFSSL_SHA512
225
5.93k
        case WC_SHA512:
226
5.93k
            ret = wc_InitSha512_ex(&hash->sha512, heap, devId);
227
5.93k
            break;
228
0
    #ifndef WOLFSSL_NOSHA512_224
229
0
        case WC_SHA512_224:
230
0
            ret = wc_InitSha512_224_ex(&hash->sha512, heap, devId);
231
0
            break;
232
0
    #endif
233
0
    #ifndef WOLFSSL_NOSHA512_256
234
0
        case WC_SHA512_256:
235
0
            ret = wc_InitSha512_256_ex(&hash->sha512, heap, devId);
236
0
            break;
237
0
    #endif
238
0
    #endif /* WOLFSSL_SHA512 */
239
240
0
    #ifdef WOLFSSL_SHA3
241
0
    #ifndef WOLFSSL_NOSHA3_224
242
0
        case WC_SHA3_224:
243
0
            ret = wc_InitSha3_224(&hash->sha3, heap, devId);
244
0
            break;
245
0
    #endif
246
0
    #ifndef WOLFSSL_NOSHA3_256
247
0
        case WC_SHA3_256:
248
0
            ret = wc_InitSha3_256(&hash->sha3, heap, devId);
249
0
            break;
250
0
    #endif
251
0
    #ifndef WOLFSSL_NOSHA3_384
252
0
        case WC_SHA3_384:
253
0
            ret = wc_InitSha3_384(&hash->sha3, heap, devId);
254
0
            break;
255
0
    #endif
256
0
    #ifndef WOLFSSL_NOSHA3_512
257
0
        case WC_SHA3_512:
258
0
            ret = wc_InitSha3_512(&hash->sha3, heap, devId);
259
0
            break;
260
0
    #endif
261
0
    #endif
262
263
0
    #ifdef WOLFSSL_SM3
264
0
        case WC_SM3:
265
0
            ret = wc_InitSm3(&hash->sm3, heap, devId);
266
0
            break;
267
0
    #endif
268
269
0
        default:
270
0
            ret = BAD_FUNC_ARG;
271
0
            break;
272
15.2k
    }
273
274
15.2k
    return ret;
275
15.2k
}
276
277
int _InitHmac(Hmac* hmac, int type, void* heap)
278
48.0k
{
279
48.0k
    int ret;
280
48.0k
#ifdef WOLF_CRYPTO_CB
281
48.0k
    int devId = hmac->devId;
282
#else
283
    int devId = INVALID_DEVID;
284
#endif
285
286
48.0k
    ret = HmacKeyInitHash(&hmac->hash, type, heap, devId);
287
48.0k
    if (ret != 0)
288
0
        return ret;
289
290
    /* default to NULL heap hint or test value */
291
#ifdef WOLFSSL_HEAP_TEST
292
    hmac->heap = (void*)WOLFSSL_HEAP_TEST;
293
#else
294
48.0k
    hmac->heap = heap;
295
48.0k
#endif /* WOLFSSL_HEAP_TEST */
296
297
48.0k
    return ret;
298
48.0k
}
299
300
static int HmacKeyCopyHash(byte macType, wc_HmacHash* src, wc_HmacHash* dst)
301
0
{
302
0
    int ret = 0;
303
304
0
    switch (macType) {
305
0
    #ifndef NO_MD5
306
0
        case WC_MD5:
307
0
            ret = wc_Md5Copy(&src->md5, &dst->md5);
308
0
            break;
309
0
    #endif /* !NO_MD5 */
310
311
0
    #ifndef NO_SHA
312
0
        case WC_SHA:
313
0
            ret = wc_ShaCopy(&src->sha, &dst->sha);
314
0
            break;
315
0
    #endif /* !NO_SHA */
316
317
0
    #ifdef WOLFSSL_SHA224
318
0
        case WC_SHA224:
319
0
            ret = wc_Sha224Copy(&src->sha224, &dst->sha224);
320
0
            break;
321
0
    #endif /* WOLFSSL_SHA224 */
322
0
    #ifndef NO_SHA256
323
0
        case WC_SHA256:
324
0
            ret = wc_Sha256Copy(&src->sha256, &dst->sha256);
325
0
            break;
326
0
    #endif /* !NO_SHA256 */
327
328
0
    #ifdef WOLFSSL_SHA384
329
0
        case WC_SHA384:
330
0
            ret = wc_Sha384Copy(&src->sha384, &dst->sha384);
331
0
            break;
332
0
    #endif /* WOLFSSL_SHA384 */
333
0
    #ifdef WOLFSSL_SHA512
334
0
        case WC_SHA512:
335
0
            ret = wc_Sha512Copy(&src->sha512, &dst->sha512);
336
0
            break;
337
0
    #ifndef WOLFSSL_NOSHA512_224
338
0
        case WC_SHA512_224:
339
0
            ret = wc_Sha512_224Copy(&src->sha512, &dst->sha512);
340
0
            break;
341
0
    #endif
342
0
    #ifndef WOLFSSL_NOSHA512_256
343
0
        case WC_SHA512_256:
344
0
            ret = wc_Sha512_256Copy(&src->sha512, &dst->sha512);
345
0
            break;
346
0
    #endif
347
0
    #endif /* WOLFSSL_SHA512 */
348
349
0
    #ifdef WOLFSSL_SHA3
350
0
    #ifndef WOLFSSL_NOSHA3_224
351
0
        case WC_SHA3_224:
352
0
            ret = wc_Sha3_224_Copy(&src->sha3, &dst->sha3);
353
0
            break;
354
0
    #endif
355
0
    #ifndef WOLFSSL_NOSHA3_256
356
0
        case WC_SHA3_256:
357
0
            ret = wc_Sha3_256_Copy(&src->sha3, &dst->sha3);
358
0
            break;
359
0
    #endif
360
0
    #ifndef WOLFSSL_NOSHA3_384
361
0
        case WC_SHA3_384:
362
0
            ret = wc_Sha3_384_Copy(&src->sha3, &dst->sha3);
363
0
            break;
364
0
    #endif
365
0
    #ifndef WOLFSSL_NOSHA3_512
366
0
        case WC_SHA3_512:
367
0
            ret = wc_Sha3_512_Copy(&src->sha3, &dst->sha3);
368
0
            break;
369
0
    #endif
370
0
    #endif /* WOLFSSL_SHA3 */
371
372
0
    #ifdef WOLFSSL_SM3
373
0
        case WC_SM3:
374
0
            ret = wc_Sm3Copy(&src->sm3, &dst->sm3);
375
0
            break;
376
0
    #endif
377
378
0
        default:
379
0
            ret = BAD_FUNC_ARG;
380
0
            break;
381
0
    }
382
383
0
    return ret;
384
0
}
385
386
/* Free a hash context of the given macType.  Tolerates zeroed,
387
 * never-initialized contexts, matching wc_HmacFree()'s existing contract
388
 * (e.g. i_hash/o_hash on device-keyed paths).
389
 */
390
static void HmacKeyFreeHash(byte macType, wc_HmacHash* hash)
391
15.6k
{
392
15.6k
    switch (macType) {
393
0
    #ifndef NO_MD5
394
571
        case WC_MD5:
395
571
            wc_Md5Free(&hash->md5);
396
571
            break;
397
0
    #endif /* !NO_MD5 */
398
399
0
    #ifndef NO_SHA
400
2.75k
        case WC_SHA:
401
2.75k
            wc_ShaFree(&hash->sha);
402
2.75k
            break;
403
0
    #endif /* !NO_SHA */
404
405
0
    #ifdef WOLFSSL_SHA224
406
630
        case WC_SHA224:
407
630
            wc_Sha224Free(&hash->sha224);
408
630
            break;
409
0
    #endif /* WOLFSSL_SHA224 */
410
0
    #ifndef NO_SHA256
411
2.14k
        case WC_SHA256:
412
2.14k
            wc_Sha256Free(&hash->sha256);
413
2.14k
            break;
414
0
    #endif /* !NO_SHA256 */
415
416
0
    #ifdef WOLFSSL_SHA384
417
3.40k
        case WC_SHA384:
418
3.40k
            wc_Sha384Free(&hash->sha384);
419
3.40k
            break;
420
0
    #endif /* WOLFSSL_SHA384 */
421
0
    #ifdef WOLFSSL_SHA512
422
5.97k
        case WC_SHA512:
423
5.97k
            wc_Sha512Free(&hash->sha512);
424
5.97k
            break;
425
0
    #ifndef WOLFSSL_NOSHA512_224
426
0
        case WC_SHA512_224:
427
0
            wc_Sha512_224Free(&hash->sha512);
428
0
            break;
429
0
    #endif
430
0
    #ifndef WOLFSSL_NOSHA512_256
431
0
        case WC_SHA512_256:
432
0
            wc_Sha512_256Free(&hash->sha512);
433
0
            break;
434
0
    #endif
435
0
    #endif /* WOLFSSL_SHA512 */
436
437
0
    #ifdef WOLFSSL_SHA3
438
0
    #ifndef WOLFSSL_NOSHA3_224
439
0
        case WC_SHA3_224:
440
0
            wc_Sha3_224_Free(&hash->sha3);
441
0
            break;
442
0
    #endif
443
0
    #ifndef WOLFSSL_NOSHA3_256
444
0
        case WC_SHA3_256:
445
0
            wc_Sha3_256_Free(&hash->sha3);
446
0
            break;
447
0
    #endif
448
0
    #ifndef WOLFSSL_NOSHA3_384
449
0
        case WC_SHA3_384:
450
0
            wc_Sha3_384_Free(&hash->sha3);
451
0
            break;
452
0
    #endif
453
0
    #ifndef WOLFSSL_NOSHA3_512
454
0
        case WC_SHA3_512:
455
0
            wc_Sha3_512_Free(&hash->sha3);
456
0
            break;
457
0
    #endif
458
0
    #endif /* WOLFSSL_SHA3 */
459
460
0
    #ifdef WOLFSSL_SM3
461
0
        case WC_SM3:
462
0
            wc_Sm3Free(&hash->sm3);
463
0
            break;
464
0
    #endif
465
466
187
        default:
467
187
            break;
468
15.6k
    }
469
15.6k
}
470
471
0
int wc_HmacCopy(Hmac* src, Hmac* dst) {
472
0
    int ret;
473
0
    int hashes_copied = 0;
474
475
0
    if ((src == NULL) || (dst == NULL))
476
0
        return BAD_FUNC_ARG;
477
0
#ifdef WC_CTX_IS_ALIGNED
478
0
    if (!WC_CTX_IS_ALIGNED(dst, Hmac))
479
0
        return BAD_ALIGN_E;
480
0
#endif
481
482
0
    XMEMCPY(dst, src, sizeof(*dst));
483
484
    /* Zero the hash contexts after the shallow copy to prevent shared
485
     * sub-pointers (e.g., msg, W buffers) with src.  Each corresponding hash
486
     * Copy call below then performs the proper deep copy.  Under
487
     * WOLFSSL_HMAC_COPY_HASH, i_hash and o_hash own state of their own and
488
     * need the same treatment as hash (freeing both src and a shallow-aliased
489
     * dst would otherwise double-free their sub-objects).
490
     */
491
0
    XMEMSET(&dst->hash, 0, sizeof(wc_HmacHash));
492
#ifdef WOLFSSL_HMAC_COPY_HASH
493
    XMEMSET(&dst->i_hash, 0, sizeof(wc_HmacHash));
494
    XMEMSET(&dst->o_hash, 0, sizeof(wc_HmacHash));
495
#endif
496
497
0
    ret = HmacKeyCopyHash(src->macType, &src->hash, &dst->hash);
498
0
    if (ret == 0)
499
0
        hashes_copied++;
500
#ifdef WOLFSSL_HMAC_COPY_HASH
501
    if (ret == 0) {
502
        ret = HmacKeyCopyHash(src->macType, &src->i_hash, &dst->i_hash);
503
        if (ret == 0)
504
            hashes_copied++;
505
    }
506
    if (ret == 0) {
507
        ret = HmacKeyCopyHash(src->macType, &src->o_hash, &dst->o_hash);
508
        if (ret == 0)
509
            hashes_copied++;
510
    }
511
#endif
512
513
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_COPY)
514
    /* The shallow copy above left dst sharing any per-context state a device
515
     * hung off devCtx; let the device give dst its own copy. The struct and the
516
     * hash contexts are already copied, so the callback only fixes up devCtx.
517
     */
518
    #ifndef WOLF_CRYPTO_CB_FIND
519
    if ((ret == 0) && (src->devId != INVALID_DEVID))
520
    #else
521
    if (ret == 0)
522
    #endif
523
    {
524
        int cbRet = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HMAC,
525
            src->macType, (void*)src, (void*)dst);
526
        if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
527
            ret = cbRet;
528
    }
529
#endif
530
531
0
    if (ret != 0) {
532
        /* Release whichever deep copies succeeded before zeroing dst, lest
533
         * their owned sub-objects leak.
534
         */
535
0
        if (hashes_copied >= 1)
536
0
            HmacKeyFreeHash(src->macType, &dst->hash);
537
#ifdef WOLFSSL_HMAC_COPY_HASH
538
        if (hashes_copied >= 2)
539
            HmacKeyFreeHash(src->macType, &dst->i_hash);
540
        if (hashes_copied >= 3)
541
            HmacKeyFreeHash(src->macType, &dst->o_hash);
542
#endif
543
0
        ForceZero(dst, sizeof(*dst));
544
0
    }
545
0
    return ret;
546
0
}
547
548
static int HmacKeyHashUpdate(byte macType, wc_HmacHash* hash, byte* pad)
549
24.3k
{
550
24.3k
    int ret = 0;
551
552
24.3k
    switch (macType) {
553
0
    #ifndef NO_MD5
554
3.02k
        case WC_MD5:
555
3.02k
            ret = wc_Md5Update(&hash->md5, pad, WC_MD5_BLOCK_SIZE);
556
3.02k
            break;
557
0
    #endif /* !NO_MD5 */
558
559
0
    #ifndef NO_SHA
560
4.15k
        case WC_SHA:
561
4.15k
            ret = wc_ShaUpdate(&hash->sha, pad, WC_SHA_BLOCK_SIZE);
562
4.15k
            break;
563
0
    #endif /* !NO_SHA */
564
565
0
    #ifdef WOLFSSL_SHA224
566
898
        case WC_SHA224:
567
898
            ret = wc_Sha224Update(&hash->sha224, pad, WC_SHA224_BLOCK_SIZE);
568
898
            break;
569
0
    #endif /* WOLFSSL_SHA224 */
570
0
    #ifndef NO_SHA256
571
4.99k
        case WC_SHA256:
572
4.99k
            ret = wc_Sha256Update(&hash->sha256, pad, WC_SHA256_BLOCK_SIZE);
573
4.99k
            break;
574
0
    #endif /* !NO_SHA256 */
575
576
0
    #ifdef WOLFSSL_SHA384
577
4.82k
        case WC_SHA384:
578
4.82k
            ret = wc_Sha384Update(&hash->sha384, pad, WC_SHA384_BLOCK_SIZE);
579
4.82k
            break;
580
0
    #endif /* WOLFSSL_SHA384 */
581
0
    #ifdef WOLFSSL_SHA512
582
6.49k
        case WC_SHA512:
583
6.49k
            ret = wc_Sha512Update(&hash->sha512, pad, WC_SHA512_BLOCK_SIZE);
584
6.49k
            break;
585
0
    #ifndef WOLFSSL_NOSHA512_224
586
0
        case WC_SHA512_224:
587
0
            ret = wc_Sha512_224Update(&hash->sha512, pad,
588
0
                                                  WC_SHA512_224_BLOCK_SIZE);
589
0
            break;
590
0
    #endif
591
0
    #ifndef WOLFSSL_NOSHA512_256
592
0
        case WC_SHA512_256:
593
0
            ret = wc_Sha512_256Update(&hash->sha512, pad,
594
0
                                                  WC_SHA512_256_BLOCK_SIZE);
595
0
            break;
596
0
    #endif
597
0
    #endif /* WOLFSSL_SHA512 */
598
599
0
    #ifdef WOLFSSL_SHA3
600
0
    #ifndef WOLFSSL_NOSHA3_224
601
0
        case WC_SHA3_224:
602
0
            ret = wc_Sha3_224_Update(&hash->sha3, pad, WC_SHA3_224_BLOCK_SIZE);
603
0
            break;
604
0
    #endif
605
0
    #ifndef WOLFSSL_NOSHA3_256
606
0
        case WC_SHA3_256:
607
0
            ret = wc_Sha3_256_Update(&hash->sha3, pad, WC_SHA3_256_BLOCK_SIZE);
608
0
            break;
609
0
    #endif
610
0
    #ifndef WOLFSSL_NOSHA3_384
611
0
        case WC_SHA3_384:
612
0
            ret = wc_Sha3_384_Update(&hash->sha3, pad, WC_SHA3_384_BLOCK_SIZE);
613
0
            break;
614
0
    #endif
615
0
    #ifndef WOLFSSL_NOSHA3_512
616
0
        case WC_SHA3_512:
617
0
            ret = wc_Sha3_512_Update(&hash->sha3, pad, WC_SHA3_512_BLOCK_SIZE);
618
0
            break;
619
0
    #endif
620
0
    #endif /* WOLFSSL_SHA3 */
621
622
0
    #ifdef WOLFSSL_SM3
623
0
        case WC_SM3:
624
0
            ret = wc_Sm3Update(&hash->sm3, pad, WC_SM3_BLOCK_SIZE);
625
0
            break;
626
0
    #endif
627
628
0
        default:
629
0
            ret = BAD_FUNC_ARG;
630
0
            break;
631
24.3k
    }
632
633
24.3k
    return ret;
634
24.3k
}
635
636
#ifdef WOLFSSL_HMAC_COPY_HASH
637
int _HmacInitIOHashes(Hmac* hmac)
638
{
639
    int ret;
640
#ifdef WOLF_CRYPTO_CB
641
    int devId = hmac->devId;
642
#else
643
    int devId = INVALID_DEVID;
644
#endif
645
646
    ret = HmacKeyInitHash(&hmac->i_hash, hmac->macType, hmac->heap, devId);
647
    if (ret == 0) {
648
        ret = HmacKeyInitHash(&hmac->o_hash, hmac->macType, hmac->heap, devId);
649
    }
650
    if (ret == 0) {
651
        ret = HmacKeyHashUpdate(hmac->macType, &hmac->i_hash,
652
            (byte*)hmac->ipad);
653
    }
654
    if (ret == 0) {
655
        ret = HmacKeyHashUpdate(hmac->macType, &hmac->o_hash,
656
            (byte*)hmac->opad);
657
    }
658
659
    return ret;
660
}
661
#endif
662
663
int wc_HmacSetKey_ex(Hmac* hmac, int type, const byte* key, word32 length,
664
                     int allowFlag)
665
15.3k
{
666
15.3k
#ifndef WOLFSSL_MAXQ108X
667
15.3k
    byte*  ip;
668
15.3k
    byte*  op;
669
15.3k
    word32 hmac_block_size = 0;
670
15.3k
#endif
671
15.3k
    int    ret = 0;
672
15.3k
    void*  heap = NULL;
673
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
674
    int    cbRet;
675
#endif
676
677
15.3k
    if (hmac == NULL || (key == NULL && length != 0) ||
678
15.3k
       !(type == WC_MD5 || type == WC_SHA ||
679
12.0k
    #ifdef WOLFSSL_SM3
680
12.0k
            type == WC_SM3 ||
681
12.0k
    #endif
682
12.0k
    #ifndef WOLFSSL_NOSHA512_224
683
12.0k
            type == WC_SHA512_224 ||
684
12.0k
    #endif
685
12.0k
    #ifndef WOLFSSL_NOSHA512_256
686
12.0k
            type == WC_SHA512_256 ||
687
12.0k
    #endif
688
12.0k
            type == WC_SHA224 || type == WC_SHA256 ||
689
9.37k
            type == WC_SHA384 || type == WC_SHA512 ||
690
45
            type == WC_SHA3_224 || type == WC_SHA3_256 ||
691
45
            type == WC_SHA3_384 || type == WC_SHA3_512)) {
692
45
        return BAD_FUNC_ARG;
693
45
    }
694
695
#if !defined(NO_MD5) && defined(HAVE_FIPS)
696
    if (type == WC_MD5)
697
        return BAD_FUNC_ARG;
698
#endif
699
700
15.2k
    heap = hmac->heap;
701
15.2k
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
702
    /* if set key has already been run then make sure and free existing */
703
    /* This is for async and PIC32MZ situations, and just normally OK,
704
       provided the user calls wc_HmacInit() first. That function is not
705
       available in FIPS builds. In current FIPS builds, the hashes are
706
       not allocating resources. */
707
15.2k
    if (hmac->macType != WC_HASH_TYPE_NONE) {
708
13.4k
    #ifdef WOLF_CRYPTO_CB
709
13.4k
        int devId = hmac->devId;
710
13.4k
    #endif
711
13.4k
    #ifdef WOLF_PRIVATE_KEY_ID
712
13.4k
        byte id[HMAC_MAX_ID_LEN];
713
13.4k
        int idLen = hmac->idLen;
714
13.4k
        char label[HMAC_MAX_LABEL_LEN];
715
13.4k
        int labelLen = hmac->labelLen;
716
717
13.4k
        XMEMCPY(id, hmac->id, sizeof(id));
718
13.4k
        XMEMCPY(label, hmac->label, sizeof(label));
719
13.4k
    #endif
720
13.4k
        wc_HmacFree(hmac);
721
13.4k
    #ifdef WOLF_CRYPTO_CB
722
13.4k
        hmac->devId = devId;
723
13.4k
    #endif
724
13.4k
    #ifdef WOLF_PRIVATE_KEY_ID
725
13.4k
        XMEMCPY(hmac->id, id, sizeof(id));
726
13.4k
        hmac->idLen = idLen;
727
13.4k
        XMEMCPY(hmac->label, label, sizeof(label));
728
13.4k
        hmac->labelLen = labelLen;
729
13.4k
    #endif
730
13.4k
    }
731
15.2k
#endif
732
733
15.2k
    hmac->innerHashKeyed = 0;
734
15.2k
    hmac->macType = (byte)type;
735
#ifdef WC_HMAC_HAVE_KEY_LOCATION
736
    hmac->keyLocation = WC_KEY_SW_STORED;
737
#endif
738
739
15.2k
    ret = _InitHmac(hmac, type, heap);
740
15.2k
    if (ret != 0)
741
0
        return ret;
742
743
    /* Regarding the password length:
744
     * SP800-107r1 ss 5.3.2 states: "An HMAC key shall have a security strength
745
     * that meets or exceeds the security strength required to protect the data
746
     * over which the HMAC is computed" then refers to SP800-133 for HMAC keys
747
     * generation.
748
     *
749
     * SP800-133r2 ss 6.2.3 states: "When a key is generated from a password,
750
     * the entropy provided (and thus, the maximum security strength that can be
751
     * supported by the generated key) shall be considered to be zero unless the
752
     * password is generated using an approved RBG"
753
     *
754
     * wolfSSL Notes: The statement from SP800-133r2 applies to
755
     * all password lengths. Any human generated password is considered to have
756
     * 0 security strength regardless of length, there is no minimum length that
757
     * is OK or will provide any amount of security strength other than 0. If
758
     * a security strength is required users shall generate random passwords
759
     * using a FIPS approved RBG of sufficient length that any HMAC key
760
     * generated from that password can claim to inherit the needed security
761
     * strength from that input.
762
     */
763
764
    /* In light of the above, Loosen past restriction that limited passwords to
765
     * no less than 14-bytes to allow for shorter Passwords.
766
     * User needs to pass true (non-zero) to override historical behavior that
767
     * prevented use of any password less than 14-bytes. ALL non-RBG generated
768
     * passwords shall inherit a security strength of zero
769
     * (no security strength)
770
     */
771
15.2k
    if (!allowFlag) {
772
0
        if (length < HMAC_FIPS_MIN_KEY) {
773
0
            WOLFSSL_ERROR_VERBOSE(HMAC_MIN_KEYLEN_E);
774
0
            return HMAC_MIN_KEYLEN_E;
775
0
        }
776
0
    }
777
778
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
779
    #ifndef WOLF_CRYPTO_CB_FIND
780
    if (hmac->devId != INVALID_DEVID)
781
    #endif
782
    {
783
        cbRet = wc_CryptoCb_SetKey(hmac->devId,
784
            WC_SETKEY_HMAC, hmac, (void*)key, length, NULL, 0, 0);
785
        if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
786
            return cbRet;
787
        /* fall-through to software when unavailable */
788
    }
789
#endif
790
791
15.2k
#ifdef WOLF_CRYPTO_CB
792
15.2k
    hmac->keyRaw = key; /* use buffer directly */
793
15.2k
    hmac->keyLen = (word16)length;
794
15.2k
#endif
795
796
#ifdef WOLFSSL_MAXQ108X
797
    /* For MAXQ108x, nothing left to do. */
798
    return 0;
799
#else
800
801
#if defined(STM32_HASH) && defined(STM32_HMAC)
802
    {
803
        word32 stmAlgo, stmBlockSize, stmDigestSize;
804
        /* Check if this hash type is supported by STM32 HMAC hardware */
805
        if (wc_Stm32_Hmac_GetAlgoInfo(type, &stmAlgo, &stmBlockSize,
806
                                       &stmDigestSize) == 0) {
807
            /* Cache algo info for Update/Final */
808
            hmac->stmAlgo = stmAlgo;
809
            hmac->stmBlockSize = stmBlockSize;
810
            hmac->stmDigestSize = stmDigestSize;
811
812
            /* Store raw key in ipad (unused in HW HMAC mode).
813
             * Pre-hash if longer than hash block size. */
814
            if (length <= stmBlockSize) {
815
                if (key != NULL) {
816
                    XMEMCPY(hmac->ipad, key, length);
817
                }
818
                hmac->stmKeyLen = length;
819
            }
820
            else {
821
                /* Pre-hash long key using stmCtx (re-initialized below) */
822
                wc_Stm32_Hash_Init(&hmac->stmCtx);
823
                ret = wolfSSL_CryptHwMutexLock();
824
                if (ret == 0) {
825
                    ret = wc_Stm32_Hash_Update(&hmac->stmCtx, stmAlgo,
826
                        key, length, stmBlockSize);
827
                    if (ret == 0) {
828
                        ret = wc_Stm32_Hash_Final(&hmac->stmCtx, stmAlgo,
829
                            (byte*)hmac->ipad, stmDigestSize);
830
                    }
831
                    wolfSSL_CryptHwMutexUnLock();
832
                }
833
                if (ret != 0)
834
                    return ret;
835
                hmac->stmKeyLen = stmDigestSize;
836
            }
837
838
            /* HW HMAC Phase 1: feed key */
839
            ret = wolfSSL_CryptHwMutexLock();
840
            if (ret == 0) {
841
                ret = wc_Stm32_Hmac_SetKey(&hmac->stmCtx, type,
842
                    (const byte*)hmac->ipad, hmac->stmKeyLen);
843
                wolfSSL_CryptHwMutexUnLock();
844
            }
845
            if (ret == 0) {
846
                hmac->innerHashKeyed = WC_HMAC_INNER_HASH_KEYED_DEV;
847
            }
848
            return ret;
849
        }
850
        /* Unsupported algo falls through to software */
851
    }
852
#endif /* STM32_HASH && STM32_HMAC */
853
854
15.2k
    ip = (byte*)hmac->ipad;
855
15.2k
    op = (byte*)hmac->opad;
856
857
15.2k
    switch (hmac->macType) {
858
0
    #ifndef NO_MD5
859
552
        case WC_MD5:
860
552
            hmac_block_size = WC_MD5_BLOCK_SIZE;
861
552
            if (length <= WC_MD5_BLOCK_SIZE) {
862
508
                if (key != NULL) {
863
508
                    XMEMCPY(ip, key, length);
864
508
                }
865
508
            }
866
44
            else {
867
44
                ret = wc_Md5Update(&hmac->hash.md5, key, length);
868
44
                if (ret != 0)
869
0
                    break;
870
44
                ret = wc_Md5Final(&hmac->hash.md5, ip);
871
44
                if (ret != 0)
872
0
                    break;
873
44
                length = WC_MD5_DIGEST_SIZE;
874
44
            }
875
552
            break;
876
552
    #endif /* !NO_MD5 */
877
878
552
    #ifndef NO_SHA
879
2.72k
        case WC_SHA:
880
2.72k
            hmac_block_size = WC_SHA_BLOCK_SIZE;
881
2.72k
            if (length <= WC_SHA_BLOCK_SIZE) {
882
2.68k
                if (key != NULL) {
883
2.68k
                    XMEMCPY(ip, key, length);
884
2.68k
                }
885
2.68k
            }
886
31
            else {
887
31
                ret = wc_ShaUpdate(&hmac->hash.sha, key, length);
888
31
                if (ret != 0)
889
0
                    break;
890
31
                ret = wc_ShaFinal(&hmac->hash.sha, ip);
891
31
                if (ret != 0)
892
0
                    break;
893
894
31
                length = WC_SHA_DIGEST_SIZE;
895
31
            }
896
2.72k
            break;
897
2.72k
    #endif /* !NO_SHA */
898
899
2.72k
    #ifdef WOLFSSL_SHA224
900
2.72k
        case WC_SHA224:
901
582
            hmac_block_size = WC_SHA224_BLOCK_SIZE;
902
582
            if (length <= WC_SHA224_BLOCK_SIZE) {
903
560
                if (key != NULL) {
904
560
                    XMEMCPY(ip, key, length);
905
560
                }
906
560
            }
907
22
            else {
908
22
                ret = wc_Sha224Update(&hmac->hash.sha224, key, length);
909
22
                if (ret != 0)
910
0
                    break;
911
22
                ret = wc_Sha224Final(&hmac->hash.sha224, ip);
912
22
                if (ret != 0)
913
0
                    break;
914
915
22
                length = WC_SHA224_DIGEST_SIZE;
916
22
            }
917
582
            break;
918
582
    #endif /* WOLFSSL_SHA224 */
919
582
    #ifndef NO_SHA256
920
2.09k
        case WC_SHA256:
921
2.09k
            hmac_block_size = WC_SHA256_BLOCK_SIZE;
922
2.09k
            if (length <= WC_SHA256_BLOCK_SIZE) {
923
2.05k
                if (key != NULL) {
924
2.05k
                    XMEMCPY(ip, key, length);
925
2.05k
                }
926
2.05k
            }
927
46
            else {
928
46
                ret = wc_Sha256Update(&hmac->hash.sha256, key, length);
929
46
                if (ret != 0)
930
0
                    break;
931
46
                ret = wc_Sha256Final(&hmac->hash.sha256, ip);
932
46
                if (ret != 0)
933
0
                    break;
934
935
46
                length = WC_SHA256_DIGEST_SIZE;
936
46
            }
937
2.09k
            break;
938
2.09k
    #endif /* !NO_SHA256 */
939
940
2.09k
    #ifdef WOLFSSL_SHA384
941
3.38k
        case WC_SHA384:
942
3.38k
            hmac_block_size = WC_SHA384_BLOCK_SIZE;
943
3.38k
            if (length <= WC_SHA384_BLOCK_SIZE) {
944
3.33k
                if (key != NULL) {
945
3.33k
                    XMEMCPY(ip, key, length);
946
3.33k
                }
947
3.33k
            }
948
52
            else {
949
52
                ret = wc_Sha384Update(&hmac->hash.sha384, key, length);
950
52
                if (ret != 0)
951
0
                    break;
952
52
                ret = wc_Sha384Final(&hmac->hash.sha384, ip);
953
52
                if (ret != 0)
954
0
                    break;
955
956
52
                length = WC_SHA384_DIGEST_SIZE;
957
52
            }
958
3.38k
            break;
959
3.38k
    #endif /* WOLFSSL_SHA384 */
960
3.38k
    #ifdef WOLFSSL_SHA512
961
5.93k
        case WC_SHA512:
962
5.93k
            hmac_block_size = WC_SHA512_BLOCK_SIZE;
963
5.93k
            if (length <= WC_SHA512_BLOCK_SIZE) {
964
5.89k
                if (key != NULL) {
965
5.89k
                    XMEMCPY(ip, key, length);
966
5.89k
                }
967
5.89k
            }
968
46
            else {
969
46
                ret = wc_Sha512Update(&hmac->hash.sha512, key, length);
970
46
                if (ret != 0)
971
0
                    break;
972
46
                ret = wc_Sha512Final(&hmac->hash.sha512, ip);
973
46
                if (ret != 0)
974
0
                    break;
975
976
46
                length = WC_SHA512_DIGEST_SIZE;
977
46
            }
978
5.93k
            break;
979
5.93k
    #ifndef WOLFSSL_NOSHA512_224
980
5.93k
        case WC_SHA512_224:
981
0
            hmac_block_size = WC_SHA512_224_BLOCK_SIZE;
982
0
            if (length <= WC_SHA512_224_BLOCK_SIZE) {
983
0
                if (key != NULL) {
984
0
                    XMEMCPY(ip, key, length);
985
0
                }
986
0
            }
987
0
            else {
988
0
                ret = wc_Sha512_224Update(&hmac->hash.sha512, key, length);
989
0
                if (ret != 0)
990
0
                    break;
991
0
                ret = wc_Sha512_224Final(&hmac->hash.sha512, ip);
992
0
                if (ret != 0)
993
0
                    break;
994
995
0
                length = WC_SHA512_224_DIGEST_SIZE;
996
0
            }
997
0
            break;
998
0
    #endif
999
0
    #ifndef WOLFSSL_NOSHA512_256
1000
0
        case WC_SHA512_256:
1001
0
            hmac_block_size = WC_SHA512_256_BLOCK_SIZE;
1002
0
            if (length <= WC_SHA512_256_BLOCK_SIZE) {
1003
0
                if (key != NULL) {
1004
0
                    XMEMCPY(ip, key, length);
1005
0
                }
1006
0
            }
1007
0
            else {
1008
0
                ret = wc_Sha512_256Update(&hmac->hash.sha512, key, length);
1009
0
                if (ret != 0)
1010
0
                    break;
1011
0
                ret = wc_Sha512_256Final(&hmac->hash.sha512, ip);
1012
0
                if (ret != 0)
1013
0
                    break;
1014
1015
0
                length = WC_SHA512_256_DIGEST_SIZE;
1016
0
            }
1017
0
            break;
1018
0
    #endif
1019
0
    #endif /* WOLFSSL_SHA512 */
1020
1021
0
    #ifdef WOLFSSL_SHA3
1022
0
    #ifndef WOLFSSL_NOSHA3_224
1023
0
        case WC_SHA3_224:
1024
0
            hmac_block_size = WC_SHA3_224_BLOCK_SIZE;
1025
0
            if (length <= WC_SHA3_224_BLOCK_SIZE) {
1026
0
                if (key != NULL) {
1027
0
                    XMEMCPY(ip, key, length);
1028
0
                }
1029
0
            }
1030
0
            else {
1031
0
                ret = wc_Sha3_224_Update(&hmac->hash.sha3, key, length);
1032
0
                if (ret != 0)
1033
0
                    break;
1034
0
                ret = wc_Sha3_224_Final(&hmac->hash.sha3, ip);
1035
0
                if (ret != 0)
1036
0
                    break;
1037
1038
0
                length = WC_SHA3_224_DIGEST_SIZE;
1039
0
            }
1040
0
            break;
1041
0
    #endif
1042
0
    #ifndef WOLFSSL_NOSHA3_256
1043
0
        case WC_SHA3_256:
1044
0
            hmac_block_size = WC_SHA3_256_BLOCK_SIZE;
1045
0
            if (length <= WC_SHA3_256_BLOCK_SIZE) {
1046
0
                if (key != NULL) {
1047
0
                    XMEMCPY(ip, key, length);
1048
0
                }
1049
0
            }
1050
0
            else {
1051
0
                ret = wc_Sha3_256_Update(&hmac->hash.sha3, key, length);
1052
0
                if (ret != 0)
1053
0
                    break;
1054
0
                ret = wc_Sha3_256_Final(&hmac->hash.sha3, ip);
1055
0
                if (ret != 0)
1056
0
                    break;
1057
1058
0
                length = WC_SHA3_256_DIGEST_SIZE;
1059
0
            }
1060
0
            break;
1061
0
    #endif
1062
0
    #ifndef WOLFSSL_NOSHA3_384
1063
0
        case WC_SHA3_384:
1064
0
            hmac_block_size = WC_SHA3_384_BLOCK_SIZE;
1065
0
            if (length <= WC_SHA3_384_BLOCK_SIZE) {
1066
0
                if (key != NULL) {
1067
0
                    XMEMCPY(ip, key, length);
1068
0
                }
1069
0
            }
1070
0
            else {
1071
0
                ret = wc_Sha3_384_Update(&hmac->hash.sha3, key, length);
1072
0
                if (ret != 0)
1073
0
                    break;
1074
0
                ret = wc_Sha3_384_Final(&hmac->hash.sha3, ip);
1075
0
                if (ret != 0)
1076
0
                    break;
1077
1078
0
                length = WC_SHA3_384_DIGEST_SIZE;
1079
0
            }
1080
0
            break;
1081
0
    #endif
1082
0
    #ifndef WOLFSSL_NOSHA3_512
1083
0
        case WC_SHA3_512:
1084
0
            hmac_block_size = WC_SHA3_512_BLOCK_SIZE;
1085
0
            if (length <= WC_SHA3_512_BLOCK_SIZE) {
1086
0
                if (key != NULL) {
1087
0
                    XMEMCPY(ip, key, length);
1088
0
                }
1089
0
            }
1090
0
            else {
1091
0
                ret = wc_Sha3_512_Update(&hmac->hash.sha3, key, length);
1092
0
                if (ret != 0)
1093
0
                    break;
1094
0
                ret = wc_Sha3_512_Final(&hmac->hash.sha3, ip);
1095
0
                if (ret != 0)
1096
0
                    break;
1097
1098
0
                length = WC_SHA3_512_DIGEST_SIZE;
1099
0
            }
1100
0
            break;
1101
0
    #endif
1102
0
    #endif /* WOLFSSL_SHA3 */
1103
1104
0
    #ifdef WOLFSSL_SM3
1105
0
        case WC_SM3:
1106
0
            hmac_block_size = WC_SM3_BLOCK_SIZE;
1107
0
            if (length <= WC_SM3_BLOCK_SIZE) {
1108
0
                if (key != NULL) {
1109
0
                    XMEMCPY(ip, key, length);
1110
0
                }
1111
0
            }
1112
0
            else {
1113
0
                ret = wc_Sm3Update(&hmac->hash.sm3, key, length);
1114
0
                if (ret != 0)
1115
0
                    break;
1116
0
                ret = wc_Sm3Final(&hmac->hash.sm3, ip);
1117
0
                if (ret != 0)
1118
0
                    break;
1119
1120
0
                length = WC_SM3_DIGEST_SIZE;
1121
0
            }
1122
0
            break;
1123
0
    #endif
1124
1125
0
        default:
1126
0
            return BAD_FUNC_ARG;
1127
15.2k
    }
1128
1129
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
1130
    if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
1131
    #if defined(HAVE_INTEL_QA) || defined(HAVE_CAVIUM)
1132
        #ifdef HAVE_INTEL_QA
1133
        if (IntelQaHmacGetType(hmac->macType, NULL) == 0)
1134
        #endif
1135
        {
1136
            if (length > hmac_block_size)
1137
                length = hmac_block_size;
1138
            /* update key length */
1139
            hmac->keyLen = (word16)length;
1140
1141
            return ret;
1142
        }
1143
        /* no need to pad below */
1144
    #endif
1145
    }
1146
#endif
1147
1148
15.2k
    if (ret == 0) {
1149
15.2k
        word32 i;
1150
1151
15.2k
        if (length < hmac_block_size)
1152
15.2k
            XMEMSET(ip + length, 0, hmac_block_size - length);
1153
1154
1.58M
        for(i = 0; i < hmac_block_size; i++) {
1155
1.57M
            op[i] = (byte)(ip[i] ^ OPAD);
1156
1.57M
            ip[i] ^= IPAD;
1157
1.57M
        }
1158
15.2k
    }
1159
1160
#ifdef WOLFSSL_HMAC_COPY_HASH
1161
    if (ret == 0) {
1162
        ret = _HmacInitIOHashes(hmac);
1163
    }
1164
#endif
1165
1166
15.2k
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
1167
15.2k
    if (ret != 0) {
1168
0
    #ifdef WOLF_CRYPTO_CB
1169
0
        int devId = hmac->devId;
1170
0
    #endif
1171
        /* The key entered the object; clear it (ISO/IEC 19790 7.9.7). */
1172
0
        wc_HmacFree(hmac);
1173
0
        hmac->heap = heap;
1174
0
    #ifdef WOLF_CRYPTO_CB
1175
0
        hmac->devId = devId;
1176
0
    #endif
1177
0
    }
1178
15.2k
#endif
1179
1180
15.2k
    return ret;
1181
15.2k
#endif /* WOLFSSL_MAXQ108X */
1182
15.2k
}
1183
1184
int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
1185
48.0k
{
1186
48.0k
    int allowFlag;
1187
    #if defined(HAVE_FIPS)
1188
        allowFlag = 0; /* default false for FIPS cases */
1189
    #else
1190
48.0k
        allowFlag = 1; /* default true for all non-FIPS cases */
1191
48.0k
    #endif
1192
48.0k
    return wc_HmacSetKey_ex(hmac, type, key, length, allowFlag);
1193
48.0k
}
1194
1195
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_PRIVATE_KEY_ID)
1196
/* A key named by id or label has no key bytes for software to use. */
1197
static int HmacKeyNotInSoftware(const Hmac* hmac)
1198
221k
{
1199
221k
    return ((hmac->idLen > 0) || (hmac->labelLen > 0)) &&
1200
0
           (hmac->keyRaw == NULL);
1201
221k
}
1202
#endif
1203
1204
#ifdef WC_HMAC_HAVE_KEY_LOCATION
1205
/* Records where the key is kept, for wc_CryptoCb_SetKeyLocation().
1206
 * WC_KEY_HW_STORED makes software Update and Final fail with MISSING_KEY.
1207
 * Returns 0, or BAD_FUNC_ARG for an unknown location. */
1208
int wc_HmacSetKeyLocation(Hmac* hmac, int location)
1209
{
1210
    if (location != WC_KEY_SW_STORED && location != WC_KEY_HW_STORED) {
1211
        return BAD_FUNC_ARG;
1212
    }
1213
    hmac->keyLocation = (byte)location;
1214
    return 0;
1215
}
1216
#endif
1217
1218
int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length)
1219
68.6k
{
1220
68.6k
    int ret = 0;
1221
1222
68.6k
    if (hmac == NULL || (msg == NULL && length > 0)) {
1223
0
        return BAD_FUNC_ARG;
1224
0
    }
1225
68.6k
    if (length == 0) {
1226
3.50k
        return 0; /* nothing to do, return success */
1227
3.50k
    }
1228
1229
65.1k
#ifdef WOLF_CRYPTO_CB
1230
65.1k
    if (WC_HMAC_USE_CRYPTOCB(hmac)) {
1231
0
        ret = wc_CryptoCb_Hmac(hmac, hmac->macType, msg, length, NULL);
1232
0
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1233
0
            return ret;
1234
        /* fall-through when unavailable */
1235
0
    }
1236
65.1k
#endif
1237
65.1k
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_PRIVATE_KEY_ID)
1238
65.1k
    if (HmacKeyNotInSoftware(hmac))
1239
0
        return MISSING_KEY;
1240
65.1k
#endif
1241
#ifdef WC_HMAC_HAVE_KEY_LOCATION
1242
    /* The key is on the device only: software has no ipad/opad to use. */
1243
    if (hmac->keyLocation == WC_KEY_HW_STORED) {
1244
        return MISSING_KEY;
1245
    }
1246
#endif
1247
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
1248
    if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
1249
    #if defined(HAVE_CAVIUM)
1250
        return NitroxHmacUpdate(hmac, msg, length);
1251
    #elif defined(HAVE_INTEL_QA)
1252
        if (IntelQaHmacGetType(hmac->macType, NULL) == 0) {
1253
            return IntelQaHmac(&hmac->asyncDev, hmac->macType,
1254
                (byte*)hmac->ipad, hmac->keyLen, NULL, msg, length);
1255
        }
1256
    #endif
1257
    }
1258
#endif /* WOLFSSL_ASYNC_CRYPT */
1259
1260
#if defined(STM32_HASH) && defined(STM32_HMAC)
1261
    if (hmac->innerHashKeyed == WC_HMAC_INNER_HASH_KEYED_DEV) {
1262
        ret = wolfSSL_CryptHwMutexLock();
1263
        if (ret == 0) {
1264
            ret = wc_Stm32_Hmac_Update(&hmac->stmCtx, hmac->stmAlgo,
1265
                msg, length, hmac->stmBlockSize);
1266
            wolfSSL_CryptHwMutexUnLock();
1267
        }
1268
        return ret;
1269
    }
1270
#endif /* STM32_HASH && STM32_HMAC */
1271
1272
65.1k
    if (!hmac->innerHashKeyed) {
1273
24.3k
#ifndef WOLFSSL_HMAC_COPY_HASH
1274
24.3k
        ret = HmacKeyHashUpdate(hmac->macType, &hmac->hash, (byte*)hmac->ipad);
1275
#else
1276
        ret = HmacKeyCopyHash(hmac->macType, &hmac->i_hash, &hmac->hash);
1277
#endif
1278
24.3k
        if (ret != 0)
1279
1
            return ret;
1280
24.3k
        hmac->innerHashKeyed = WC_HMAC_INNER_HASH_KEYED_SW;
1281
24.3k
    }
1282
1283
65.1k
    switch (hmac->macType) {
1284
0
    #ifndef NO_MD5
1285
8.93k
        case WC_MD5:
1286
8.93k
            ret = wc_Md5Update(&hmac->hash.md5, msg, length);
1287
8.93k
            break;
1288
0
    #endif /* !NO_MD5 */
1289
1290
0
    #ifndef NO_SHA
1291
12.3k
        case WC_SHA:
1292
12.3k
            ret = wc_ShaUpdate(&hmac->hash.sha, msg, length);
1293
12.3k
            break;
1294
0
    #endif /* !NO_SHA */
1295
1296
0
    #ifdef WOLFSSL_SHA224
1297
2.09k
        case WC_SHA224:
1298
2.09k
            ret = wc_Sha224Update(&hmac->hash.sha224, msg, length);
1299
2.09k
            break;
1300
0
    #endif /* WOLFSSL_SHA224 */
1301
1302
0
    #ifndef NO_SHA256
1303
9.02k
        case WC_SHA256:
1304
9.02k
            ret = wc_Sha256Update(&hmac->hash.sha256, msg, length);
1305
9.02k
            break;
1306
0
    #endif /* !NO_SHA256 */
1307
1308
0
    #ifdef WOLFSSL_SHA384
1309
13.7k
        case WC_SHA384:
1310
13.7k
            ret = wc_Sha384Update(&hmac->hash.sha384, msg, length);
1311
13.7k
            break;
1312
0
    #endif /* WOLFSSL_SHA384 */
1313
0
    #ifdef WOLFSSL_SHA512
1314
19.0k
        case WC_SHA512:
1315
19.0k
            ret = wc_Sha512Update(&hmac->hash.sha512, msg, length);
1316
19.0k
            break;
1317
0
    #ifndef WOLFSSL_NOSHA512_224
1318
0
        case WC_SHA512_224:
1319
0
            ret = wc_Sha512_224Update(&hmac->hash.sha512, msg, length);
1320
0
            break;
1321
0
    #endif
1322
0
    #ifndef WOLFSSL_NOSHA512_256
1323
0
        case WC_SHA512_256:
1324
0
            ret = wc_Sha512_256Update(&hmac->hash.sha512, msg, length);
1325
0
            break;
1326
0
    #endif
1327
0
    #endif /* WOLFSSL_SHA512 */
1328
1329
0
    #ifdef WOLFSSL_SHA3
1330
0
    #ifndef WOLFSSL_NOSHA3_224
1331
0
        case WC_SHA3_224:
1332
0
            ret = wc_Sha3_224_Update(&hmac->hash.sha3, msg, length);
1333
0
            break;
1334
0
    #endif
1335
0
    #ifndef WOLFSSL_NOSHA3_256
1336
0
        case WC_SHA3_256:
1337
0
            ret = wc_Sha3_256_Update(&hmac->hash.sha3, msg, length);
1338
0
            break;
1339
0
    #endif
1340
0
    #ifndef WOLFSSL_NOSHA3_384
1341
0
        case WC_SHA3_384:
1342
0
            ret = wc_Sha3_384_Update(&hmac->hash.sha3, msg, length);
1343
0
            break;
1344
0
    #endif
1345
0
    #ifndef WOLFSSL_NOSHA3_512
1346
0
        case WC_SHA3_512:
1347
0
            ret = wc_Sha3_512_Update(&hmac->hash.sha3, msg, length);
1348
0
            break;
1349
0
    #endif
1350
0
    #endif /* WOLFSSL_SHA3 */
1351
1352
0
    #ifdef WOLFSSL_SM3
1353
0
        case WC_SM3:
1354
0
            ret = wc_Sm3Update(&hmac->hash.sm3, msg, length);
1355
0
            break;
1356
0
    #endif
1357
1358
0
        default:
1359
0
            ret = BAD_FUNC_ARG;
1360
0
            break;
1361
65.1k
    }
1362
1363
65.1k
    return ret;
1364
65.1k
}
1365
1366
1367
int wc_HmacFinal(Hmac* hmac, byte* hash)
1368
24.3k
{
1369
24.3k
    int ret;
1370
1371
24.3k
    if (hmac == NULL || hash == NULL) {
1372
0
        return BAD_FUNC_ARG;
1373
0
    }
1374
1375
24.3k
#ifdef WOLF_CRYPTO_CB
1376
24.3k
    if (WC_HMAC_USE_CRYPTOCB(hmac)) {
1377
194
        ret = wc_CryptoCb_Hmac(hmac, hmac->macType, NULL, 0, hash);
1378
194
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1379
0
            return ret;
1380
        /* fall-through when unavailable */
1381
194
    }
1382
24.3k
#endif
1383
24.3k
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_PRIVATE_KEY_ID)
1384
24.3k
    if (HmacKeyNotInSoftware(hmac))
1385
0
        return MISSING_KEY;
1386
24.3k
#endif
1387
#ifdef WC_HMAC_HAVE_KEY_LOCATION
1388
    /* The key is on the device only: software has no ipad/opad to use. */
1389
    if (hmac->keyLocation == WC_KEY_HW_STORED) {
1390
        return MISSING_KEY;
1391
    }
1392
#endif
1393
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
1394
    if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
1395
        int hashLen = wc_HmacSizeByType(hmac->macType);
1396
        if (hashLen <= 0)
1397
            return hashLen;
1398
1399
    #if defined(HAVE_CAVIUM)
1400
        return NitroxHmacFinal(hmac, hash, hashLen);
1401
    #elif defined(HAVE_INTEL_QA)
1402
        if (IntelQaHmacGetType(hmac->macType, NULL) == 0) {
1403
            return IntelQaHmac(&hmac->asyncDev, hmac->macType,
1404
                (byte*)hmac->ipad, hmac->keyLen, hash, NULL, hashLen);
1405
        }
1406
    #endif
1407
    }
1408
#endif /* WOLFSSL_ASYNC_CRYPT */
1409
1410
#if defined(STM32_HASH) && defined(STM32_HMAC)
1411
    if (hmac->innerHashKeyed == WC_HMAC_INNER_HASH_KEYED_DEV) {
1412
        ret = wolfSSL_CryptHwMutexLock();
1413
        if (ret == 0) {
1414
            ret = wc_Stm32_Hmac_Final(&hmac->stmCtx, hmac->stmAlgo,
1415
                (const byte*)hmac->ipad, hmac->stmKeyLen, hash,
1416
                hmac->stmDigestSize);
1417
            /* Re-run Phase 1 so HMAC is ready for next Update/Final cycle
1418
             * (needed for PRF/HKDF loops that reuse the same key) */
1419
            if (ret == 0) {
1420
                ret = wc_Stm32_Hmac_SetKey(&hmac->stmCtx, hmac->macType,
1421
                    (const byte*)hmac->ipad, hmac->stmKeyLen);
1422
            }
1423
            wolfSSL_CryptHwMutexUnLock();
1424
        }
1425
        return ret;
1426
    }
1427
#endif /* STM32_HASH && STM32_HMAC */
1428
1429
24.3k
    if (!hmac->innerHashKeyed) {
1430
2
#ifndef WOLFSSL_HMAC_COPY_HASH
1431
2
        ret = HmacKeyHashUpdate(hmac->macType, &hmac->hash, (byte*)hmac->ipad);
1432
#else
1433
        ret = HmacKeyCopyHash(hmac->macType, &hmac->i_hash, &hmac->hash);
1434
#endif
1435
2
        if (ret != 0)
1436
0
            return ret;
1437
2
        hmac->innerHashKeyed = WC_HMAC_INNER_HASH_KEYED_SW;
1438
2
    }
1439
1440
24.3k
    switch (hmac->macType) {
1441
0
    #ifndef NO_MD5
1442
3.02k
        case WC_MD5:
1443
3.02k
            ret = wc_Md5Final(&hmac->hash.md5, (byte*)hmac->innerHash);
1444
3.02k
            if (ret != 0)
1445
0
                break;
1446
3.02k
       #ifndef WOLFSSL_HMAC_COPY_HASH
1447
3.02k
            ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->opad,
1448
3.02k
                                                             WC_MD5_BLOCK_SIZE);
1449
       #else
1450
            ret = HmacKeyCopyHash(WC_MD5, &hmac->o_hash, &hmac->hash);
1451
       #endif
1452
3.02k
            if (ret != 0)
1453
0
                break;
1454
3.02k
            ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->innerHash,
1455
3.02k
                                                            WC_MD5_DIGEST_SIZE);
1456
3.02k
            if (ret != 0)
1457
0
                break;
1458
3.02k
            ret = wc_Md5Final(&hmac->hash.md5, hash);
1459
3.02k
            break;
1460
0
    #endif /* !NO_MD5 */
1461
1462
0
    #ifndef NO_SHA
1463
4.15k
        case WC_SHA:
1464
4.15k
            ret = wc_ShaFinal(&hmac->hash.sha, (byte*)hmac->innerHash);
1465
4.15k
            if (ret != 0)
1466
0
                break;
1467
4.15k
       #ifndef WOLFSSL_HMAC_COPY_HASH
1468
4.15k
            ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->opad,
1469
4.15k
                                                             WC_SHA_BLOCK_SIZE);
1470
       #else
1471
            ret = HmacKeyCopyHash(WC_SHA, &hmac->o_hash, &hmac->hash);
1472
       #endif
1473
4.15k
            if (ret != 0)
1474
0
                break;
1475
4.15k
            ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->innerHash,
1476
4.15k
                                                            WC_SHA_DIGEST_SIZE);
1477
4.15k
            if (ret != 0)
1478
0
                break;
1479
4.15k
            ret = wc_ShaFinal(&hmac->hash.sha, hash);
1480
4.15k
            break;
1481
0
    #endif /* !NO_SHA */
1482
1483
0
    #ifdef WOLFSSL_SHA224
1484
898
        case WC_SHA224:
1485
898
            ret = wc_Sha224Final(&hmac->hash.sha224, (byte*)hmac->innerHash);
1486
898
            if (ret != 0)
1487
0
                break;
1488
898
       #ifndef WOLFSSL_HMAC_COPY_HASH
1489
898
            ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->opad,
1490
898
                                                          WC_SHA224_BLOCK_SIZE);
1491
       #else
1492
            ret = HmacKeyCopyHash(WC_SHA224, &hmac->o_hash, &hmac->hash);
1493
       #endif
1494
898
            if (ret != 0)
1495
0
                break;
1496
898
            ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->innerHash,
1497
898
                                                         WC_SHA224_DIGEST_SIZE);
1498
898
            if (ret != 0)
1499
0
                break;
1500
898
            ret = wc_Sha224Final(&hmac->hash.sha224, hash);
1501
898
            if (ret != 0)
1502
0
                break;
1503
898
            break;
1504
898
    #endif /* WOLFSSL_SHA224 */
1505
898
    #ifndef NO_SHA256
1506
4.99k
        case WC_SHA256:
1507
4.99k
            ret = wc_Sha256Final(&hmac->hash.sha256, (byte*)hmac->innerHash);
1508
4.99k
            if (ret != 0)
1509
2
                break;
1510
4.99k
       #ifndef WOLFSSL_HMAC_COPY_HASH
1511
4.99k
            ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->opad,
1512
4.99k
                                                          WC_SHA256_BLOCK_SIZE);
1513
       #else
1514
            ret = HmacKeyCopyHash(WC_SHA256, &hmac->o_hash, &hmac->hash);
1515
       #endif
1516
4.99k
            if (ret != 0)
1517
1
                break;
1518
4.99k
            ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->innerHash,
1519
4.99k
                                                         WC_SHA256_DIGEST_SIZE);
1520
4.99k
            if (ret != 0)
1521
0
                break;
1522
4.99k
            ret = wc_Sha256Final(&hmac->hash.sha256, hash);
1523
4.99k
            break;
1524
0
    #endif /* !NO_SHA256 */
1525
1526
0
    #ifdef WOLFSSL_SHA384
1527
4.82k
        case WC_SHA384:
1528
4.82k
            ret = wc_Sha384Final(&hmac->hash.sha384, (byte*)hmac->innerHash);
1529
4.82k
            if (ret != 0)
1530
0
                break;
1531
4.82k
       #ifndef WOLFSSL_HMAC_COPY_HASH
1532
4.82k
            ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->opad,
1533
4.82k
                                                          WC_SHA384_BLOCK_SIZE);
1534
       #else
1535
            ret = HmacKeyCopyHash(WC_SHA384, &hmac->o_hash, &hmac->hash);
1536
       #endif
1537
4.82k
            if (ret != 0)
1538
0
                break;
1539
4.82k
            ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->innerHash,
1540
4.82k
                                                         WC_SHA384_DIGEST_SIZE);
1541
4.82k
            if (ret != 0)
1542
0
                break;
1543
4.82k
            ret = wc_Sha384Final(&hmac->hash.sha384, hash);
1544
4.82k
            break;
1545
0
    #endif /* WOLFSSL_SHA384 */
1546
0
    #ifdef WOLFSSL_SHA512
1547
6.49k
        case WC_SHA512:
1548
6.49k
            ret = wc_Sha512Final(&hmac->hash.sha512, (byte*)hmac->innerHash);
1549
6.49k
            if (ret != 0)
1550
0
                break;
1551
6.49k
       #ifndef WOLFSSL_HMAC_COPY_HASH
1552
6.49k
            ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->opad,
1553
6.49k
                                                          WC_SHA512_BLOCK_SIZE);
1554
       #else
1555
            ret = HmacKeyCopyHash(WC_SHA512, &hmac->o_hash, &hmac->hash);
1556
       #endif
1557
6.49k
            if (ret != 0)
1558
0
                break;
1559
6.49k
            ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->innerHash,
1560
6.49k
                                                         WC_SHA512_DIGEST_SIZE);
1561
6.49k
            if (ret != 0)
1562
0
                break;
1563
6.49k
            ret = wc_Sha512Final(&hmac->hash.sha512, hash);
1564
6.49k
            break;
1565
0
    #ifndef WOLFSSL_NOSHA512_224
1566
0
        case WC_SHA512_224:
1567
0
            ret = wc_Sha512_224Final(&hmac->hash.sha512,
1568
0
                                                    (byte*)hmac->innerHash);
1569
0
            if (ret != 0)
1570
0
                break;
1571
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
1572
0
            ret = wc_Sha512_224Update(&hmac->hash.sha512, (byte*)hmac->opad,
1573
0
                                                      WC_SHA512_224_BLOCK_SIZE);
1574
       #else
1575
            ret = HmacKeyCopyHash(WC_SHA512_224, &hmac->o_hash, &hmac->hash);
1576
       #endif
1577
0
            if (ret != 0)
1578
0
                break;
1579
0
            ret = wc_Sha512_224Update(&hmac->hash.sha512,
1580
0
                              (byte*)hmac->innerHash, WC_SHA512_224_DIGEST_SIZE);
1581
0
            if (ret != 0)
1582
0
                break;
1583
0
            ret = wc_Sha512_224Final(&hmac->hash.sha512, hash);
1584
0
            break;
1585
0
    #endif
1586
0
    #ifndef WOLFSSL_NOSHA512_256
1587
0
        case WC_SHA512_256:
1588
0
            ret = wc_Sha512_256Final(&hmac->hash.sha512,
1589
0
                                                    (byte*)hmac->innerHash);
1590
0
            if (ret != 0)
1591
0
                break;
1592
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
1593
0
            ret = wc_Sha512_256Update(&hmac->hash.sha512, (byte*)hmac->opad,
1594
0
                                                      WC_SHA512_256_BLOCK_SIZE);
1595
       #else
1596
            ret = HmacKeyCopyHash(WC_SHA512_256, &hmac->o_hash, &hmac->hash);
1597
       #endif
1598
0
            if (ret != 0)
1599
0
                break;
1600
0
            ret = wc_Sha512_256Update(&hmac->hash.sha512,
1601
0
                              (byte*)hmac->innerHash, WC_SHA512_256_DIGEST_SIZE);
1602
0
            if (ret != 0)
1603
0
                break;
1604
0
            ret = wc_Sha512_256Final(&hmac->hash.sha512, hash);
1605
0
            break;
1606
0
    #endif
1607
0
    #endif /* WOLFSSL_SHA512 */
1608
1609
0
    #ifdef WOLFSSL_SHA3
1610
0
    #ifndef WOLFSSL_NOSHA3_224
1611
0
        case WC_SHA3_224:
1612
0
            ret = wc_Sha3_224_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
1613
0
            if (ret != 0)
1614
0
                break;
1615
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
1616
0
            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->opad,
1617
0
                                                        WC_SHA3_224_BLOCK_SIZE);
1618
       #else
1619
            ret = HmacKeyCopyHash(WC_SHA3_224, &hmac->o_hash, &hmac->hash);
1620
       #endif
1621
0
            if (ret != 0)
1622
0
                break;
1623
0
            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
1624
0
                                                       WC_SHA3_224_DIGEST_SIZE);
1625
0
            if (ret != 0)
1626
0
                break;
1627
0
            ret = wc_Sha3_224_Final(&hmac->hash.sha3, hash);
1628
0
            break;
1629
0
    #endif
1630
0
    #ifndef WOLFSSL_NOSHA3_256
1631
0
        case WC_SHA3_256:
1632
0
            ret = wc_Sha3_256_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
1633
0
            if (ret != 0)
1634
0
                break;
1635
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
1636
0
            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->opad,
1637
0
                                                        WC_SHA3_256_BLOCK_SIZE);
1638
       #else
1639
            ret = HmacKeyCopyHash(WC_SHA3_256, &hmac->o_hash, &hmac->hash);
1640
       #endif
1641
0
            if (ret != 0)
1642
0
                break;
1643
0
            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
1644
0
                                                       WC_SHA3_256_DIGEST_SIZE);
1645
0
            if (ret != 0)
1646
0
                break;
1647
0
            ret = wc_Sha3_256_Final(&hmac->hash.sha3, hash);
1648
0
            break;
1649
0
    #endif
1650
0
    #ifndef WOLFSSL_NOSHA3_384
1651
0
        case WC_SHA3_384:
1652
0
            ret = wc_Sha3_384_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
1653
0
            if (ret != 0)
1654
0
                break;
1655
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
1656
0
            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->opad,
1657
0
                                                        WC_SHA3_384_BLOCK_SIZE);
1658
       #else
1659
            ret = HmacKeyCopyHash(WC_SHA3_384, &hmac->o_hash, &hmac->hash);
1660
       #endif
1661
0
            if (ret != 0)
1662
0
                break;
1663
0
            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
1664
0
                                                       WC_SHA3_384_DIGEST_SIZE);
1665
0
            if (ret != 0)
1666
0
                break;
1667
0
            ret = wc_Sha3_384_Final(&hmac->hash.sha3, hash);
1668
0
            break;
1669
0
    #endif
1670
0
    #ifndef WOLFSSL_NOSHA3_512
1671
0
        case WC_SHA3_512:
1672
0
            ret = wc_Sha3_512_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
1673
0
            if (ret != 0)
1674
0
                break;
1675
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
1676
0
            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->opad,
1677
0
                                                        WC_SHA3_512_BLOCK_SIZE);
1678
       #else
1679
            ret = HmacKeyCopyHash(WC_SHA3_512, &hmac->o_hash, &hmac->hash);
1680
       #endif
1681
0
            if (ret != 0)
1682
0
                break;
1683
0
            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
1684
0
                                                       WC_SHA3_512_DIGEST_SIZE);
1685
0
            if (ret != 0)
1686
0
                break;
1687
0
            ret = wc_Sha3_512_Final(&hmac->hash.sha3, hash);
1688
0
            break;
1689
0
    #endif
1690
0
    #endif /* WOLFSSL_SHA3 */
1691
1692
0
    #ifdef WOLFSSL_SM3
1693
0
        case WC_SM3:
1694
0
            ret = wc_Sm3Final(&hmac->hash.sm3, (byte*)hmac->innerHash);
1695
0
            if (ret != 0)
1696
0
                break;
1697
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
1698
0
            ret = wc_Sm3Update(&hmac->hash.sm3, (byte*)hmac->opad,
1699
0
                                                             WC_SM3_BLOCK_SIZE);
1700
       #else
1701
            ret = HmacKeyCopyHash(WC_SM3, &hmac->o_hash, &hmac->hash);
1702
       #endif
1703
0
            if (ret != 0)
1704
0
                break;
1705
0
            ret = wc_Sm3Update(&hmac->hash.sm3, (byte*)hmac->innerHash,
1706
0
                                                            WC_SM3_DIGEST_SIZE);
1707
0
            if (ret != 0)
1708
0
                break;
1709
0
            ret = wc_Sm3Final(&hmac->hash.sm3, hash);
1710
0
            break;
1711
0
    #endif
1712
1713
0
        default:
1714
0
            ret = BAD_FUNC_ARG;
1715
0
            break;
1716
24.3k
    }
1717
1718
24.3k
    if (ret == 0) {
1719
24.3k
        hmac->innerHashKeyed = 0;
1720
24.3k
    }
1721
1722
24.3k
    return ret;
1723
24.3k
}
1724
1725
#ifdef WOLFSSL_KCAPI_HMAC
1726
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hmac.c */
1727
1728
    /* unmap the _Software calls used by kcapi_hmac.c */
1729
    #undef wc_HmacSetKey
1730
    #undef wc_HmacUpdate
1731
    #undef wc_HmacFinal
1732
1733
#else
1734
/* Initialize Hmac for use with async device */
1735
int wc_HmacInit(Hmac* hmac, void* heap, int devId)
1736
53.6k
{
1737
53.6k
    int ret = 0;
1738
1739
53.6k
    if (hmac == NULL)
1740
0
        return BAD_FUNC_ARG;
1741
53.6k
#ifdef WC_CTX_IS_ALIGNED
1742
53.6k
    if (!WC_CTX_IS_ALIGNED(hmac, Hmac))
1743
0
        return BAD_ALIGN_E;
1744
53.6k
#endif
1745
1746
53.6k
    XMEMSET(hmac, 0, sizeof(Hmac));
1747
53.6k
    hmac->macType = WC_HASH_TYPE_NONE;
1748
53.6k
    hmac->heap = heap;
1749
53.6k
#ifdef WOLF_CRYPTO_CB
1750
53.6k
    hmac->devId = devId;
1751
53.6k
    hmac->devCtx = NULL;
1752
53.6k
#endif
1753
#if defined(WOLFSSL_DEVCRYPTO_HMAC)
1754
    hmac->ctx.inited = 0;
1755
    hmac->ctx.cfd    = -1;
1756
#endif
1757
1758
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
1759
    ret = wolfAsync_DevCtxInit(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC,
1760
                                                         hmac->heap, devId);
1761
#else
1762
53.6k
    (void)devId;
1763
53.6k
#endif /* WOLFSSL_ASYNC_CRYPT */
1764
1765
53.6k
    return ret;
1766
53.6k
}
1767
1768
#ifdef WOLF_PRIVATE_KEY_ID
1769
int  wc_HmacInit_Id(Hmac* hmac, unsigned char* id, int len, void* heap,
1770
                    int devId)
1771
0
{
1772
0
    int ret = 0;
1773
1774
0
    if (hmac == NULL || (id == NULL && len > 0))
1775
0
        ret = BAD_FUNC_ARG;
1776
0
    if (ret == 0 && (len < 0 || len > HMAC_MAX_ID_LEN))
1777
0
        ret = BUFFER_E;
1778
1779
0
    if (ret == 0)
1780
0
        ret = wc_HmacInit(hmac, heap, devId);
1781
0
    if (ret == 0 && id != NULL && len != 0) {
1782
0
        XMEMCPY(hmac->id, id, (size_t)len);
1783
0
        hmac->idLen = len;
1784
0
    }
1785
1786
0
    return ret;
1787
0
}
1788
1789
int wc_HmacInit_Label(Hmac* hmac, const char* label, void* heap, int devId)
1790
0
{
1791
0
    int ret = 0;
1792
0
    int labelLen = 0;
1793
1794
0
    if (hmac == NULL || label == NULL)
1795
0
        ret = BAD_FUNC_ARG;
1796
0
    if (ret == 0) {
1797
0
        labelLen = (int)XSTRLEN(label);
1798
0
        if (labelLen == 0 || labelLen > HMAC_MAX_LABEL_LEN)
1799
0
            ret = BUFFER_E;
1800
0
    }
1801
1802
0
    if (ret == 0)
1803
0
        ret  = wc_HmacInit(hmac, heap, devId);
1804
0
    if (ret == 0) {
1805
0
        XMEMCPY(hmac->label, label, (size_t)labelLen);
1806
0
        hmac->labelLen = labelLen;
1807
0
    }
1808
1809
0
    return ret;
1810
0
}
1811
#endif /* WOLF_PRIVATE_KEY_ID */
1812
1813
/* Free Hmac from use with async device */
1814
void wc_HmacFree(Hmac* hmac)
1815
180k
{
1816
180k
    if (hmac == NULL)
1817
132k
        return;
1818
48.3k
#ifdef WC_CTX_IS_ALIGNED
1819
48.3k
    if (!WC_CTX_IS_ALIGNED(hmac, Hmac)) {
1820
0
        ForceZero(hmac, sizeof(*hmac));
1821
0
        return;
1822
0
    }
1823
48.3k
#endif
1824
1825
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
1826
    /* Let a device release any per-context state it hung off devCtx directly. If
1827
     * a device handles it, devCtx is cleared and the finalize fallback below is
1828
     * skipped; otherwise this is a no-op and the fallback still runs. */
1829
    #ifndef WOLF_CRYPTO_CB_FIND
1830
    if (hmac->devId != INVALID_DEVID && hmac->devCtx != NULL)
1831
    #else
1832
    if (hmac->devCtx != NULL)
1833
    #endif
1834
    {
1835
        (void)wc_CryptoCb_Free(hmac->devId, WC_ALGO_TYPE_HMAC, hmac->macType, 0,
1836
            (void*)hmac);
1837
    }
1838
#endif
1839
1840
48.3k
#ifdef WOLF_CRYPTO_CB
1841
    /* cleanup when final was not called; devCtx is set only by a device, so
1842
     * under WOLF_CRYPTO_CB_FIND it alone marks an op still owned by one. */
1843
48.3k
    if (WC_HMAC_USE_CRYPTOCB(hmac) && hmac->devCtx != NULL) {
1844
0
        int  ret;
1845
0
        byte finalHash[WC_HMAC_BLOCK_SIZE];
1846
0
        ret = wc_CryptoCb_Hmac(hmac, hmac->macType, NULL, 0, finalHash);
1847
0
        (void)ret; /* must ignore return code here */
1848
0
        (void)finalHash;
1849
0
    }
1850
48.3k
#endif
1851
1852
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
1853
    wolfAsync_DevCtxFree(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC);
1854
#endif /* WOLFSSL_ASYNC_CRYPT */
1855
1856
48.3k
    HmacKeyFreeHash(hmac->macType, &hmac->hash);
1857
#ifdef WOLFSSL_HMAC_COPY_HASH
1858
    HmacKeyFreeHash(hmac->macType, &hmac->i_hash);
1859
    HmacKeyFreeHash(hmac->macType, &hmac->o_hash);
1860
#endif
1861
1862
48.3k
    ForceZero(hmac, sizeof(*hmac));
1863
48.3k
}
1864
#endif /* WOLFSSL_KCAPI_HMAC */
1865
1866
int wolfSSL_GetHmacMaxSize(void)
1867
0
{
1868
0
    return WC_MAX_DIGEST_SIZE;
1869
0
}
1870
1871
#ifdef HAVE_HKDF
1872
    /* Wait out an async HMAC sub-op: the HKDF loops cannot resume
1873
     * mid-chain. QAT/Cavium only (not covered by CI); a crypto callback
1874
     * pending must instead propagate so the caller can re-invoke. */
1875
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) && \
1876
    (defined(HAVE_INTEL_QA) || defined(HAVE_CAVIUM))
1877
    /* QAT/Cavium only: WOLFSSL_ASYNC_REINVOKE is never defined for these
1878
     * backends (see internal.h), so an HKDF sub-op can only pend on the
1879
     * hardware device, never on a re-invokable crypto callback. Wait
1880
     * unconditionally: the HKDF loops cannot resume mid-chain. */
1881
    #define HKDF_HMAC_WAIT(ret, hmac)                                      \
1882
        do {                                                               \
1883
            (ret) = wc_AsyncWait((ret), &(hmac)->asyncDev,                 \
1884
                                 WC_ASYNC_FLAG_NONE);                      \
1885
        } while (0)
1886
#else
1887
    /* No HMAC device to wait on, or the pending must reach the caller
1888
     * (crypto callback re-invocation); hmac is unevaluated. */
1889
109k
    #define HKDF_HMAC_WAIT(ret, hmac) WC_DO_NOTHING
1890
#endif
1891
1892
    /* HMAC-KDF-Extract.
1893
     * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
1894
     *
1895
     * type     The hash algorithm type.
1896
     * salt     The optional salt value.
1897
     * saltSz   The size of the salt.
1898
     * inKey    The input keying material.
1899
     * inKeySz  The size of the input keying material.
1900
     * out      The pseudorandom key with the length that of the hash.
1901
     * returns 0 on success, otherwise failure.
1902
     */
1903
    int wc_HKDF_Extract_ex(int type, const byte* salt, word32 saltSz,
1904
        const byte* inKey, word32 inKeySz, byte* out, void* heap, int devId)
1905
5.50k
    {
1906
5.50k
        byte   tmp[WC_MAX_DIGEST_SIZE]; /* localSalt helper */
1907
5.50k
        WC_DECLARE_VAR(myHmac, Hmac, 1, 0);
1908
5.50k
        int    ret;
1909
5.50k
        const  byte* localSalt;  /* either points to user input or tmp */
1910
5.50k
        word32 hashSz;
1911
1912
5.50k
        if (out == NULL || (inKey == NULL && inKeySz > 0)) {
1913
0
            return BAD_FUNC_ARG;
1914
0
        }
1915
1916
5.50k
#ifdef WOLF_CRYPTO_CB
1917
        /* Try crypto callback first. Only CRYPTOCB_UNAVAILABLE falls back
1918
         * to software. WC_PENDING_E is returned as-is: the caller polls,
1919
         * re-invoking with identical arguments until it clears. */
1920
5.50k
        if (devId != INVALID_DEVID) {
1921
0
            ret = wc_CryptoCb_Hkdf_Extract(type, salt, saltSz, inKey, inKeySz,
1922
0
                                           out, devId);
1923
0
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1924
0
                return ret;
1925
0
        }
1926
5.50k
#endif
1927
1928
5.50k
        ret = wc_HmacSizeByType(type);
1929
5.50k
        if (ret < 0) {
1930
0
            return ret;
1931
0
        }
1932
5.50k
        hashSz = (word32)ret;
1933
1934
5.50k
        WC_ALLOC_VAR_EX(myHmac, Hmac, 1, NULL, DYNAMIC_TYPE_HMAC,
1935
5.50k
            return MEMORY_E);
1936
1937
5.49k
        localSalt = salt;
1938
5.49k
        if (localSalt == NULL) {
1939
5.09k
            XMEMSET(tmp, 0, hashSz);
1940
5.09k
            localSalt = tmp;
1941
5.09k
            saltSz    = hashSz;
1942
5.09k
        }
1943
1944
5.49k
        ret = wc_HmacInit(myHmac, heap, devId);
1945
5.49k
        if (ret == 0) {
1946
        #if FIPS_VERSION3_GE(6,0,0)
1947
            ret = wc_HmacSetKey_ex(myHmac, type, localSalt, saltSz,
1948
                                   FIPS_ALLOW_SHORT);
1949
        #else
1950
5.49k
            ret = wc_HmacSetKey(myHmac, type, localSalt, saltSz);
1951
5.49k
        #endif
1952
5.49k
            if (ret == 0) {
1953
5.49k
                ret = wc_HmacUpdate(myHmac, inKey, inKeySz);
1954
5.49k
                HKDF_HMAC_WAIT(ret, myHmac);
1955
5.49k
            }
1956
5.49k
            if (ret == 0) {
1957
5.49k
                ret = wc_HmacFinal(myHmac,  out);
1958
5.49k
                HKDF_HMAC_WAIT(ret, myHmac);
1959
5.49k
            }
1960
5.49k
            wc_HmacFree(myHmac);
1961
5.49k
        }
1962
5.49k
        WC_FREE_VAR_EX(myHmac, NULL, DYNAMIC_TYPE_HMAC);
1963
1964
5.49k
        return ret;
1965
5.50k
    }
1966
1967
    int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz,
1968
                        const byte* inKey, word32 inKeySz, byte* out)
1969
0
    {
1970
0
        return wc_HKDF_Extract_ex(type, salt, saltSz, inKey, inKeySz, out, NULL,
1971
0
            INVALID_DEVID);
1972
0
    }
1973
1974
    /* HMAC-KDF-Expand.
1975
     * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
1976
     *
1977
     * type     The hash algorithm type.
1978
     * inKey    The input key.
1979
     * inKeySz  The size of the input key.
1980
     * info     The application specific information.
1981
     * infoSz   The size of the application specific information.
1982
     * out      The output keying material.
1983
     * returns 0 on success, otherwise failure.
1984
     */
1985
    int wc_HKDF_Expand_ex(int type, const byte* inKey, word32 inKeySz,
1986
                       const byte* info, word32 infoSz, byte* out, word32 outSz,
1987
                       void* heap, int devId)
1988
11.2k
    {
1989
11.2k
        byte   tmp[WC_MAX_DIGEST_SIZE];
1990
11.2k
        WC_DECLARE_VAR(myHmac, Hmac, 1, 0);
1991
11.2k
        int    ret = 0;
1992
11.2k
        word32 outIdx = 0;
1993
11.2k
        word32 hashSz;
1994
11.2k
        byte   n = 0x1;
1995
1996
11.2k
        if (out == NULL || (inKey == NULL && inKeySz > 0)) {
1997
24
            return BAD_FUNC_ARG;
1998
24
        }
1999
2000
11.2k
        ret = wc_HmacSizeByType(type);
2001
11.2k
        if (ret < 0) {
2002
0
            return ret;
2003
0
        }
2004
11.2k
        else if (ret == 0)
2005
0
            return BAD_FUNC_ARG;
2006
2007
11.2k
        hashSz = (word32)ret;
2008
2009
        /* RFC 5869 states that the length of output keying material in
2010
         * octets must be L <= 255*HashLen or N = ceil(L/HashLen) */
2011
11.2k
        if (outSz/hashSz + ((outSz % hashSz) != 0) > 255)
2012
74
            return BAD_FUNC_ARG;
2013
2014
11.1k
#ifdef WOLF_CRYPTO_CB
2015
        /* Try crypto callback first. WC_PENDING_E is returned to the
2016
         * caller to poll, as in wc_HKDF_Extract_ex(). */
2017
11.1k
        if (devId != INVALID_DEVID) {
2018
0
            ret = wc_CryptoCb_Hkdf_Expand(type, inKey, inKeySz, info, infoSz,
2019
0
                                           out, outSz, devId);
2020
0
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2021
0
                return ret;
2022
0
        }
2023
11.1k
#endif
2024
2025
11.1k
        WC_ALLOC_VAR_EX(myHmac, Hmac, 1, NULL, DYNAMIC_TYPE_HMAC,
2026
11.1k
            return MEMORY_E);
2027
2028
11.1k
        ret = wc_HmacInit(myHmac, heap, devId);
2029
11.1k
        if (ret != 0) {
2030
0
            WC_FREE_VAR_EX(myHmac, NULL, DYNAMIC_TYPE_HMAC);
2031
0
            return ret;
2032
0
        }
2033
2034
11.1k
        XMEMSET(tmp, 0, WC_MAX_DIGEST_SIZE);
2035
#ifdef WOLFSSL_CHECK_MEM_ZERO
2036
        wc_MemZero_Add("wc_HKDF_Expand_ex tmp", tmp, WC_MAX_DIGEST_SIZE);
2037
#endif
2038
2039
35.7k
        while (outIdx < outSz) {
2040
24.6k
            word32 tmpSz = (n == 1) ? 0 : hashSz;
2041
24.6k
            word32 left = outSz - outIdx;
2042
2043
        #if FIPS_VERSION3_GE(6,0,0)
2044
            ret = wc_HmacSetKey_ex(myHmac, type, inKey, inKeySz,
2045
                                   FIPS_ALLOW_SHORT);
2046
        #else
2047
24.6k
            ret = wc_HmacSetKey(myHmac, type, inKey, inKeySz);
2048
24.6k
        #endif
2049
24.6k
            if (ret != 0)
2050
0
                break;
2051
24.6k
            ret = wc_HmacUpdate(myHmac, tmp, tmpSz);
2052
24.6k
            HKDF_HMAC_WAIT(ret, myHmac);
2053
24.6k
            if (ret != 0)
2054
0
                break;
2055
24.6k
            ret = wc_HmacUpdate(myHmac, info, infoSz);
2056
24.6k
            HKDF_HMAC_WAIT(ret, myHmac);
2057
24.6k
            if (ret != 0)
2058
1
                break;
2059
24.6k
            ret = wc_HmacUpdate(myHmac, &n, 1);
2060
24.6k
            HKDF_HMAC_WAIT(ret, myHmac);
2061
24.6k
            if (ret != 0)
2062
0
                break;
2063
24.6k
            ret = wc_HmacFinal(myHmac, tmp);
2064
24.6k
            HKDF_HMAC_WAIT(ret, myHmac);
2065
24.6k
            if (ret != 0)
2066
9
                break;
2067
2068
24.6k
            left = min(left, hashSz);
2069
24.6k
            XMEMCPY(out+outIdx, tmp, left);
2070
2071
24.6k
            outIdx += left;
2072
24.6k
            n++;
2073
24.6k
        }
2074
11.1k
        if (ret != 0) {
2075
            /* Partial OKM is not released (ISO/IEC 19790 7.9.7). */
2076
10
            ForceZero(out, outSz);
2077
10
        }
2078
2079
11.1k
        ForceZero(tmp, WC_MAX_DIGEST_SIZE);
2080
#ifdef WOLFSSL_CHECK_MEM_ZERO
2081
        wc_MemZero_Check(tmp, WC_MAX_DIGEST_SIZE);
2082
#endif
2083
11.1k
        wc_HmacFree(myHmac);
2084
11.1k
        WC_FREE_VAR_EX(myHmac, NULL, DYNAMIC_TYPE_HMAC);
2085
2086
11.1k
        return ret;
2087
11.1k
    }
2088
2089
    int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz,
2090
                       const byte* info, word32 infoSz, byte* out, word32 outSz)
2091
0
    {
2092
0
        return wc_HKDF_Expand_ex(type, inKey, inKeySz, info, infoSz, out, outSz,
2093
0
            NULL, INVALID_DEVID);
2094
0
    }
2095
2096
    /* HMAC-KDF.
2097
     * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
2098
     *
2099
     * type     The hash algorithm type.
2100
     * inKey    The input keying material.
2101
     * inKeySz  The size of the input keying material.
2102
     * salt     The optional salt value.
2103
     * saltSz   The size of the salt.
2104
     * info     The application specific information.
2105
     * infoSz   The size of the application specific information.
2106
     * out      The output keying material.
2107
     * returns 0 on success, otherwise failure.
2108
     */
2109
    int wc_HKDF_ex(int type, const byte* inKey, word32 inKeySz,
2110
                   const byte* salt, word32 saltSz, const byte* info,
2111
                   word32 infoSz, byte* out, word32 outSz, void* heap,
2112
                   int devId)
2113
542
    {
2114
542
        byte   prk[WC_MAX_DIGEST_SIZE];
2115
542
        word32 hashSz;
2116
542
        int    ret;
2117
2118
542
        (void)devId; /* suppress unused parameter warning */
2119
2120
542
#ifdef WOLF_CRYPTO_CB
2121
        /* Try crypto callback first. WC_PENDING_E is returned to the
2122
         * caller to poll, as in wc_HKDF_Extract_ex(). */
2123
542
        if (devId != INVALID_DEVID) {
2124
0
             ret = wc_CryptoCb_Hkdf(type, inKey, inKeySz, salt, saltSz, info,
2125
0
                                   infoSz, out, outSz, devId);
2126
0
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2127
0
                return ret;
2128
0
        }
2129
542
#endif
2130
2131
542
        ret = wc_HmacSizeByType(type);
2132
542
        if (ret < 0)
2133
8
            return ret;
2134
534
        hashSz = (word32)ret;
2135
2136
#ifdef WOLFSSL_CHECK_MEM_ZERO
2137
        XMEMSET(prk, 0, WC_MAX_DIGEST_SIZE);
2138
        wc_MemZero_Add("wc_HKDF_ex prk", prk, WC_MAX_DIGEST_SIZE);
2139
#endif
2140
        /* Restartable, not resumable: the retry redoes extract, so a
2141
         * device that pends must serve the repeat from its result. */
2142
534
        ret = wc_HKDF_Extract_ex(type, salt, saltSz, inKey, inKeySz, prk, heap,
2143
534
                                 devId);
2144
534
        if (ret == 0) {
2145
529
            ret = wc_HKDF_Expand_ex(type, prk, hashSz, info, infoSz,
2146
529
                                    out, outSz, heap, devId);
2147
529
        }
2148
534
        ForceZero(prk, WC_MAX_DIGEST_SIZE);
2149
#ifdef WOLFSSL_CHECK_MEM_ZERO
2150
        wc_MemZero_Check(prk, WC_MAX_DIGEST_SIZE);
2151
#endif
2152
534
        return ret;
2153
542
    }
2154
2155
    int wc_HKDF(int type, const byte* inKey, word32 inKeySz, const byte* salt,
2156
                word32 saltSz, const byte* info, word32 infoSz, byte* out,
2157
                word32 outSz)
2158
214
    {
2159
214
        return wc_HKDF_ex(type, inKey, inKeySz, salt, saltSz, info, infoSz, out,
2160
214
                          outSz, NULL, INVALID_DEVID);
2161
214
    }
2162
2163
#undef HKDF_HMAC_WAIT
2164
2165
#endif /* HAVE_HKDF */
2166
2167
#endif /* NO_HMAC */