Coverage Report

Created: 2026-08-15 06:21

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