Coverage Report

Created: 2025-07-04 06:22

/src/wolfssl/wolfcrypt/src/hmac.c
Line
Count
Source (jump to first uncovered line)
1
/* hmac.c
2
 *
3
 * Copyright (C) 2006-2025 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 2 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
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
24
25
#ifndef NO_HMAC
26
27
#if FIPS_VERSION3_GE(2,0,0)
28
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
29
    #define FIPS_NO_WRAPPERS
30
31
    #ifdef USE_WINDOWS_API
32
        #pragma code_seg(".fipsA$g")
33
        #pragma const_seg(".fipsB$g")
34
    #endif
35
#endif
36
37
#include <wolfssl/wolfcrypt/hmac.h>
38
39
#ifdef WOLF_CRYPTO_CB
40
    #include <wolfssl/wolfcrypt/cryptocb.h>
41
#endif
42
43
#ifdef NO_INLINE
44
    #include <wolfssl/wolfcrypt/misc.h>
45
#else
46
    #define WOLFSSL_MISC_INCLUDED
47
    #include <wolfcrypt/src/misc.c>
48
#endif
49
50
#ifdef WOLFSSL_KCAPI_HMAC
51
    #include <wolfssl/wolfcrypt/port/kcapi/kcapi_hmac.h>
52
53
    /* map the _Software calls used by kcapi_hmac.c */
54
    #define wc_HmacSetKey  wc_HmacSetKey_Software
55
    #define wc_HmacUpdate  wc_HmacUpdate_Software
56
    #define wc_HmacFinal   wc_HmacFinal_Software
57
#endif
58
59
#if FIPS_VERSION3_GE(6,0,0)
60
    const unsigned int wolfCrypt_FIPS_hmac_ro_sanity[2] =
61
                                                     { 0x1a2b3c4d, 0x00000008 };
62
    int wolfCrypt_FIPS_HMAC_sanity(void)
63
    {
64
        return 0;
65
    }
66
#endif
67
68
int wc_HmacSizeByType(int type)
69
0
{
70
0
    int ret;
71
72
0
    if (!(type == WC_MD5 || type == WC_SHA ||
73
    #ifdef WOLFSSL_SM3
74
            type == WC_SM3 ||
75
    #endif
76
0
            type == WC_SHA224 || type == WC_SHA256 ||
77
0
            type == WC_SHA384 || type == WC_SHA512 ||
78
0
            type == WC_SHA3_224 || type == WC_SHA3_256 ||
79
0
            type == WC_SHA3_384 || type == WC_SHA3_512)) {
80
0
        return BAD_FUNC_ARG;
81
0
    }
82
83
0
    switch (type) {
84
    #ifndef NO_MD5
85
        case WC_MD5:
86
            ret = WC_MD5_DIGEST_SIZE;
87
            break;
88
    #endif /* !NO_MD5 */
89
90
0
    #ifndef NO_SHA
91
0
        case WC_SHA:
92
0
            ret = WC_SHA_DIGEST_SIZE;
93
0
            break;
94
0
    #endif /* !NO_SHA */
95
96
0
    #ifdef WOLFSSL_SHA224
97
0
        case WC_SHA224:
98
0
            ret = WC_SHA224_DIGEST_SIZE;
99
0
            break;
100
0
    #endif /* WOLFSSL_SHA224 */
101
102
0
    #ifndef NO_SHA256
103
0
        case WC_SHA256:
104
0
            ret = WC_SHA256_DIGEST_SIZE;
105
0
            break;
106
0
    #endif /* !NO_SHA256 */
107
108
0
    #ifdef WOLFSSL_SHA384
109
0
        case WC_SHA384:
110
0
            ret = WC_SHA384_DIGEST_SIZE;
111
0
            break;
112
0
    #endif /* WOLFSSL_SHA384 */
113
0
    #ifdef WOLFSSL_SHA512
114
0
        case WC_SHA512:
115
0
            ret = WC_SHA512_DIGEST_SIZE;
116
0
            break;
117
0
    #endif /* WOLFSSL_SHA512 */
118
119
0
    #ifdef WOLFSSL_SHA3
120
0
        case WC_SHA3_224:
121
0
            ret = WC_SHA3_224_DIGEST_SIZE;
122
0
            break;
123
124
0
        case WC_SHA3_256:
125
0
            ret = WC_SHA3_256_DIGEST_SIZE;
126
0
            break;
127
128
0
        case WC_SHA3_384:
129
0
            ret = WC_SHA3_384_DIGEST_SIZE;
130
0
            break;
131
132
0
        case WC_SHA3_512:
133
0
            ret = WC_SHA3_512_DIGEST_SIZE;
134
0
            break;
135
0
    #endif /* WOLFSSL_SHA3 */
136
137
    #ifdef WOLFSSL_SM3
138
        case WC_SM3:
139
            ret = WC_SM3_DIGEST_SIZE;
140
            break;
141
    #endif
142
143
0
        default:
144
0
            ret = BAD_FUNC_ARG;
145
0
            break;
146
0
    }
147
148
0
    return ret;
149
0
}
150
151
static int HmacKeyInitHash(wc_HmacHash* hash, int type, void* heap, int devId)
152
0
{
153
0
    int ret = 0;
154
155
0
    switch (type) {
156
    #ifndef NO_MD5
157
        case WC_MD5:
158
            ret = wc_InitMd5_ex(&hash->md5, heap, devId);
159
            break;
160
    #endif /* !NO_MD5 */
161
162
0
    #ifndef NO_SHA
163
0
        case WC_SHA:
164
0
            ret = wc_InitSha_ex(&hash->sha, heap, devId);
165
0
            break;
166
0
    #endif /* !NO_SHA */
167
168
0
    #ifdef WOLFSSL_SHA224
169
0
        case WC_SHA224:
170
0
            ret = wc_InitSha224_ex(&hash->sha224, heap, devId);
171
0
            break;
172
0
    #endif /* WOLFSSL_SHA224 */
173
174
0
    #ifndef NO_SHA256
175
0
        case WC_SHA256:
176
0
            ret = wc_InitSha256_ex(&hash->sha256, heap, devId);
177
0
            break;
178
0
    #endif /* !NO_SHA256 */
179
180
0
    #ifdef WOLFSSL_SHA384
181
0
        case WC_SHA384:
182
0
            ret = wc_InitSha384_ex(&hash->sha384, heap, devId);
183
0
            break;
184
0
    #endif /* WOLFSSL_SHA384 */
185
0
    #ifdef WOLFSSL_SHA512
186
0
        case WC_SHA512:
187
0
            ret = wc_InitSha512_ex(&hash->sha512, heap, devId);
188
0
            break;
189
0
    #endif /* WOLFSSL_SHA512 */
190
191
0
    #ifdef WOLFSSL_SHA3
192
0
    #ifndef WOLFSSL_NOSHA3_224
193
0
        case WC_SHA3_224:
194
0
            ret = wc_InitSha3_224(&hash->sha3, heap, devId);
195
0
            break;
196
0
    #endif
197
0
    #ifndef WOLFSSL_NOSHA3_256
198
0
        case WC_SHA3_256:
199
0
            ret = wc_InitSha3_256(&hash->sha3, heap, devId);
200
0
            break;
201
0
    #endif
202
0
    #ifndef WOLFSSL_NOSHA3_384
203
0
        case WC_SHA3_384:
204
0
            ret = wc_InitSha3_384(&hash->sha3, heap, devId);
205
0
            break;
206
0
    #endif
207
0
    #ifndef WOLFSSL_NOSHA3_512
208
0
        case WC_SHA3_512:
209
0
            ret = wc_InitSha3_512(&hash->sha3, heap, devId);
210
0
            break;
211
0
    #endif
212
0
    #endif
213
214
    #ifdef WOLFSSL_SM3
215
        case WC_SM3:
216
            ret = wc_InitSm3(&hash->sm3, heap, devId);
217
            break;
218
    #endif
219
220
0
        default:
221
0
            ret = BAD_FUNC_ARG;
222
0
            break;
223
0
    }
224
225
0
    return ret;
226
0
}
227
228
int _InitHmac(Hmac* hmac, int type, void* heap)
229
0
{
230
0
    int ret;
231
#ifdef WOLF_CRYPTO_CB
232
    int devId = hmac->devId;
233
#else
234
0
    int devId = INVALID_DEVID;
235
0
#endif
236
237
0
    ret = HmacKeyInitHash(&hmac->hash, type, heap, devId);
238
0
    if (ret != 0)
239
0
        return ret;
240
241
    /* default to NULL heap hint or test value */
242
#ifdef WOLFSSL_HEAP_TEST
243
    hmac->heap = (void*)WOLFSSL_HEAP_TEST;
244
#else
245
0
    hmac->heap = heap;
246
0
#endif /* WOLFSSL_HEAP_TEST */
247
248
0
    return ret;
249
0
}
250
251
#ifdef WOLFSSL_HMAC_COPY_HASH
252
static int HmacKeyCopyHash(byte macType, wc_HmacHash* src, wc_HmacHash* dst)
253
{
254
    int ret = 0;
255
256
    switch (macType) {
257
    #ifndef NO_MD5
258
        case WC_MD5:
259
            ret = wc_Md5Copy(&src->md5, &dst->md5);
260
            break;
261
    #endif /* !NO_MD5 */
262
263
    #ifndef NO_SHA
264
        case WC_SHA:
265
            ret = wc_ShaCopy(&src->sha, &dst->sha);
266
            break;
267
    #endif /* !NO_SHA */
268
269
    #ifdef WOLFSSL_SHA224
270
        case WC_SHA224:
271
            ret = wc_Sha224Copy(&src->sha224, &dst->sha224);
272
            break;
273
    #endif /* WOLFSSL_SHA224 */
274
    #ifndef NO_SHA256
275
        case WC_SHA256:
276
            ret = wc_Sha256Copy(&src->sha256, &dst->sha256);
277
            break;
278
    #endif /* !NO_SHA256 */
279
280
    #ifdef WOLFSSL_SHA384
281
        case WC_SHA384:
282
            ret = wc_Sha384Copy(&src->sha384, &dst->sha384);
283
            break;
284
    #endif /* WOLFSSL_SHA384 */
285
    #ifdef WOLFSSL_SHA512
286
        case WC_SHA512:
287
            ret = wc_Sha512Copy(&src->sha512, &dst->sha512);
288
            break;
289
    #endif /* WOLFSSL_SHA512 */
290
291
    #ifdef WOLFSSL_SHA3
292
    #ifndef WOLFSSL_NOSHA3_224
293
        case WC_SHA3_224:
294
            ret = wc_Sha3_224_Copy(&src->sha3, &dst->sha3);
295
            break;
296
    #endif
297
    #ifndef WOLFSSL_NOSHA3_256
298
        case WC_SHA3_256:
299
            ret = wc_Sha3_256_Copy(&src->sha3, &dst->sha3);
300
            break;
301
    #endif
302
    #ifndef WOLFSSL_NOSHA3_384
303
        case WC_SHA3_384:
304
            ret = wc_Sha3_384_Copy(&src->sha3, &dst->sha3);
305
            break;
306
    #endif
307
    #ifndef WOLFSSL_NOSHA3_512
308
        case WC_SHA3_512:
309
            ret = wc_Sha3_512_Copy(&src->sha3, &dst->sha3);
310
            break;
311
    #endif
312
    #endif /* WOLFSSL_SHA3 */
313
314
    #ifdef WOLFSSL_SM3
315
        case WC_SM3:
316
            ret = wc_Sm3Copy(&src->sm3, &dst->sm3);
317
            break;
318
    #endif
319
320
        default:
321
            break;
322
    }
323
324
    return ret;
325
}
326
#endif
327
328
static int HmacKeyHashUpdate(byte macType, wc_HmacHash* hash, byte* pad)
329
0
{
330
0
    int ret = 0;
331
332
0
    switch (macType) {
333
    #ifndef NO_MD5
334
        case WC_MD5:
335
            ret = wc_Md5Update(&hash->md5, pad, WC_MD5_BLOCK_SIZE);
336
            break;
337
    #endif /* !NO_MD5 */
338
339
0
    #ifndef NO_SHA
340
0
        case WC_SHA:
341
0
            ret = wc_ShaUpdate(&hash->sha, pad, WC_SHA_BLOCK_SIZE);
342
0
            break;
343
0
    #endif /* !NO_SHA */
344
345
0
    #ifdef WOLFSSL_SHA224
346
0
        case WC_SHA224:
347
0
            ret = wc_Sha224Update(&hash->sha224, pad, WC_SHA224_BLOCK_SIZE);
348
0
            break;
349
0
    #endif /* WOLFSSL_SHA224 */
350
0
    #ifndef NO_SHA256
351
0
        case WC_SHA256:
352
0
            ret = wc_Sha256Update(&hash->sha256, pad, WC_SHA256_BLOCK_SIZE);
353
0
            break;
354
0
    #endif /* !NO_SHA256 */
355
356
0
    #ifdef WOLFSSL_SHA384
357
0
        case WC_SHA384:
358
0
            ret = wc_Sha384Update(&hash->sha384, pad, WC_SHA384_BLOCK_SIZE);
359
0
            break;
360
0
    #endif /* WOLFSSL_SHA384 */
361
0
    #ifdef WOLFSSL_SHA512
362
0
        case WC_SHA512:
363
0
            ret = wc_Sha512Update(&hash->sha512, pad, WC_SHA512_BLOCK_SIZE);
364
0
            break;
365
0
    #endif /* WOLFSSL_SHA512 */
366
367
0
    #ifdef WOLFSSL_SHA3
368
0
    #ifndef WOLFSSL_NOSHA3_224
369
0
        case WC_SHA3_224:
370
0
            ret = wc_Sha3_224_Update(&hash->sha3, pad, WC_SHA3_224_BLOCK_SIZE);
371
0
            break;
372
0
    #endif
373
0
    #ifndef WOLFSSL_NOSHA3_256
374
0
        case WC_SHA3_256:
375
0
            ret = wc_Sha3_256_Update(&hash->sha3, pad, WC_SHA3_256_BLOCK_SIZE);
376
0
            break;
377
0
    #endif
378
0
    #ifndef WOLFSSL_NOSHA3_384
379
0
        case WC_SHA3_384:
380
0
            ret = wc_Sha3_384_Update(&hash->sha3, pad, WC_SHA3_384_BLOCK_SIZE);
381
0
            break;
382
0
    #endif
383
0
    #ifndef WOLFSSL_NOSHA3_512
384
0
        case WC_SHA3_512:
385
0
            ret = wc_Sha3_512_Update(&hash->sha3, pad, WC_SHA3_512_BLOCK_SIZE);
386
0
            break;
387
0
    #endif
388
0
    #endif /* WOLFSSL_SHA3 */
389
390
    #ifdef WOLFSSL_SM3
391
        case WC_SM3:
392
            ret = wc_Sm3Update(&hash->sm3, pad, WC_SM3_BLOCK_SIZE);
393
            break;
394
    #endif
395
396
0
        default:
397
0
            break;
398
0
    }
399
400
0
    return ret;
401
0
}
402
403
#ifdef WOLFSSL_HMAC_COPY_HASH
404
int _HmacInitIOHashes(Hmac* hmac)
405
{
406
    int ret;
407
#ifdef WOLF_CRYPTO_CB
408
    int devId = hmac->devId;
409
#else
410
    int devId = INVALID_DEVID;
411
#endif
412
413
    ret = HmacKeyInitHash(&hmac->i_hash, hmac->macType, hmac->heap, devId);
414
    if (ret == 0) {
415
        ret = HmacKeyInitHash(&hmac->o_hash, hmac->macType, hmac->heap, devId);
416
    }
417
    if (ret == 0) {
418
        ret = HmacKeyHashUpdate(hmac->macType, &hmac->i_hash,
419
            (byte*)hmac->ipad);
420
    }
421
    if (ret == 0) {
422
        ret = HmacKeyHashUpdate(hmac->macType, &hmac->o_hash,
423
            (byte*)hmac->opad);
424
    }
425
426
    return ret;
427
}
428
#endif
429
430
int wc_HmacSetKey_ex(Hmac* hmac, int type, const byte* key, word32 length,
431
                     int allowFlag)
432
0
{
433
0
#ifndef WOLFSSL_MAXQ108X
434
0
    byte*  ip;
435
0
    byte*  op;
436
0
    word32 hmac_block_size = 0;
437
0
#endif
438
0
    int    ret = 0;
439
0
    void*  heap = NULL;
440
441
0
    if (hmac == NULL || (key == NULL && length != 0) ||
442
0
       !(type == WC_MD5 || type == WC_SHA ||
443
    #ifdef WOLFSSL_SM3
444
            type == WC_SM3 ||
445
    #endif
446
0
            type == WC_SHA224 || type == WC_SHA256 ||
447
0
            type == WC_SHA384 || type == WC_SHA512 ||
448
0
            type == WC_SHA3_224 || type == WC_SHA3_256 ||
449
0
            type == WC_SHA3_384 || type == WC_SHA3_512)) {
450
0
        return BAD_FUNC_ARG;
451
0
    }
452
453
0
    heap = hmac->heap;
454
0
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
455
    /* if set key has already been run then make sure and free existing */
456
    /* This is for async and PIC32MZ situations, and just normally OK,
457
       provided the user calls wc_HmacInit() first. That function is not
458
       available in FIPS builds. In current FIPS builds, the hashes are
459
       not allocating resources. */
460
0
    if (hmac->macType != WC_HASH_TYPE_NONE) {
461
    #ifdef WOLF_CRYPTO_CB
462
        int devId = hmac->devId;
463
    #endif
464
0
        wc_HmacFree(hmac);
465
    #ifdef WOLF_CRYPTO_CB
466
        hmac->devId = devId;
467
    #endif
468
0
    }
469
0
#endif
470
471
0
    hmac->innerHashKeyed = 0;
472
0
    hmac->macType = (byte)type;
473
474
0
    ret = _InitHmac(hmac, type, heap);
475
0
    if (ret != 0)
476
0
        return ret;
477
478
    /* Regarding the password length:
479
     * SP800-107r1 ss 5.3.2 states: "An HMAC key shall have a security strength
480
     * that meets or exceeds the security strength required to protect the data
481
     * over which the HMAC is computed" then refers to SP800-133 for HMAC keys
482
     * generation.
483
     *
484
     * SP800-133r2 ss 6.2.3 states: "When a key is generated from a password,
485
     * the entropy provided (and thus, the maximum security strength that can be
486
     * supported by the generated key) shall be considered to be zero unless the
487
     * password is generated using an approved RBG"
488
     *
489
     * wolfSSL Notes: The statement from SP800-133r2 applies to
490
     * all password lengths. Any human generated password is considered to have
491
     * 0 security strength regardless of length, there is no minimum length that
492
     * is OK or will provide any amount of security strength other than 0. If
493
     * a security strength is required users shall generate random passwords
494
     * using a FIPS approved RBG of sufficient length that any HMAC key
495
     * generated from that password can claim to inherit the needed security
496
     * strength from that input.
497
     */
498
499
    /* In light of the above, Loosen past restriction that limited passwords to
500
     * no less than 14-bytes to allow for shorter Passwords.
501
     * User needs to pass true (non-zero) to override historical behavior that
502
     * prevented use of any password less than 14-bytes. ALL non-RBG generated
503
     * passwords shall inherit a security strength of zero
504
     * (no security strength)
505
     */
506
0
    if (!allowFlag) {
507
0
        if (length < HMAC_FIPS_MIN_KEY) {
508
0
            WOLFSSL_ERROR_VERBOSE(HMAC_MIN_KEYLEN_E);
509
0
            return HMAC_MIN_KEYLEN_E;
510
0
        }
511
0
    }
512
513
#ifdef WOLF_CRYPTO_CB
514
    hmac->keyRaw = key; /* use buffer directly */
515
    hmac->keyLen = (word16)length;
516
#endif
517
518
#ifdef WOLFSSL_MAXQ108X
519
    /* For MAXQ108x, nothing left to do. */
520
    return 0;
521
#else
522
523
0
    ip = (byte*)hmac->ipad;
524
0
    op = (byte*)hmac->opad;
525
526
0
    switch (hmac->macType) {
527
    #ifndef NO_MD5
528
        case WC_MD5:
529
            hmac_block_size = WC_MD5_BLOCK_SIZE;
530
            if (length <= WC_MD5_BLOCK_SIZE) {
531
                if (key != NULL) {
532
                    XMEMCPY(ip, key, length);
533
                }
534
            }
535
            else {
536
                ret = wc_Md5Update(&hmac->hash.md5, key, length);
537
                if (ret != 0)
538
                    break;
539
                ret = wc_Md5Final(&hmac->hash.md5, ip);
540
                if (ret != 0)
541
                    break;
542
                length = WC_MD5_DIGEST_SIZE;
543
            }
544
            break;
545
    #endif /* !NO_MD5 */
546
547
0
    #ifndef NO_SHA
548
0
        case WC_SHA:
549
0
            hmac_block_size = WC_SHA_BLOCK_SIZE;
550
0
            if (length <= WC_SHA_BLOCK_SIZE) {
551
0
                if (key != NULL) {
552
0
                    XMEMCPY(ip, key, length);
553
0
                }
554
0
            }
555
0
            else {
556
0
                ret = wc_ShaUpdate(&hmac->hash.sha, key, length);
557
0
                if (ret != 0)
558
0
                    break;
559
0
                ret = wc_ShaFinal(&hmac->hash.sha, ip);
560
0
                if (ret != 0)
561
0
                    break;
562
563
0
                length = WC_SHA_DIGEST_SIZE;
564
0
            }
565
0
            break;
566
0
    #endif /* !NO_SHA */
567
568
0
    #ifdef WOLFSSL_SHA224
569
0
        case WC_SHA224:
570
0
            hmac_block_size = WC_SHA224_BLOCK_SIZE;
571
0
            if (length <= WC_SHA224_BLOCK_SIZE) {
572
0
                if (key != NULL) {
573
0
                    XMEMCPY(ip, key, length);
574
0
                }
575
0
            }
576
0
            else {
577
0
                ret = wc_Sha224Update(&hmac->hash.sha224, key, length);
578
0
                if (ret != 0)
579
0
                    break;
580
0
                ret = wc_Sha224Final(&hmac->hash.sha224, ip);
581
0
                if (ret != 0)
582
0
                    break;
583
584
0
                length = WC_SHA224_DIGEST_SIZE;
585
0
            }
586
0
            break;
587
0
    #endif /* WOLFSSL_SHA224 */
588
0
    #ifndef NO_SHA256
589
0
        case WC_SHA256:
590
0
            hmac_block_size = WC_SHA256_BLOCK_SIZE;
591
0
            if (length <= WC_SHA256_BLOCK_SIZE) {
592
0
                if (key != NULL) {
593
0
                    XMEMCPY(ip, key, length);
594
0
                }
595
0
            }
596
0
            else {
597
0
                ret = wc_Sha256Update(&hmac->hash.sha256, key, length);
598
0
                if (ret != 0)
599
0
                    break;
600
0
                ret = wc_Sha256Final(&hmac->hash.sha256, ip);
601
0
                if (ret != 0)
602
0
                    break;
603
604
0
                length = WC_SHA256_DIGEST_SIZE;
605
0
            }
606
0
            break;
607
0
    #endif /* !NO_SHA256 */
608
609
0
    #ifdef WOLFSSL_SHA384
610
0
        case WC_SHA384:
611
0
            hmac_block_size = WC_SHA384_BLOCK_SIZE;
612
0
            if (length <= WC_SHA384_BLOCK_SIZE) {
613
0
                if (key != NULL) {
614
0
                    XMEMCPY(ip, key, length);
615
0
                }
616
0
            }
617
0
            else {
618
0
                ret = wc_Sha384Update(&hmac->hash.sha384, key, length);
619
0
                if (ret != 0)
620
0
                    break;
621
0
                ret = wc_Sha384Final(&hmac->hash.sha384, ip);
622
0
                if (ret != 0)
623
0
                    break;
624
625
0
                length = WC_SHA384_DIGEST_SIZE;
626
0
            }
627
0
            break;
628
0
    #endif /* WOLFSSL_SHA384 */
629
0
    #ifdef WOLFSSL_SHA512
630
0
        case WC_SHA512:
631
0
            hmac_block_size = WC_SHA512_BLOCK_SIZE;
632
0
            if (length <= WC_SHA512_BLOCK_SIZE) {
633
0
                if (key != NULL) {
634
0
                    XMEMCPY(ip, key, length);
635
0
                }
636
0
            }
637
0
            else {
638
0
                ret = wc_Sha512Update(&hmac->hash.sha512, key, length);
639
0
                if (ret != 0)
640
0
                    break;
641
0
                ret = wc_Sha512Final(&hmac->hash.sha512, ip);
642
0
                if (ret != 0)
643
0
                    break;
644
645
0
                length = WC_SHA512_DIGEST_SIZE;
646
0
            }
647
0
            break;
648
0
    #endif /* WOLFSSL_SHA512 */
649
650
0
    #ifdef WOLFSSL_SHA3
651
0
    #ifndef WOLFSSL_NOSHA3_224
652
0
        case WC_SHA3_224:
653
0
            hmac_block_size = WC_SHA3_224_BLOCK_SIZE;
654
0
            if (length <= WC_SHA3_224_BLOCK_SIZE) {
655
0
                if (key != NULL) {
656
0
                    XMEMCPY(ip, key, length);
657
0
                }
658
0
            }
659
0
            else {
660
0
                ret = wc_Sha3_224_Update(&hmac->hash.sha3, key, length);
661
0
                if (ret != 0)
662
0
                    break;
663
0
                ret = wc_Sha3_224_Final(&hmac->hash.sha3, ip);
664
0
                if (ret != 0)
665
0
                    break;
666
667
0
                length = WC_SHA3_224_DIGEST_SIZE;
668
0
            }
669
0
            break;
670
0
    #endif
671
0
    #ifndef WOLFSSL_NOSHA3_256
672
0
        case WC_SHA3_256:
673
0
            hmac_block_size = WC_SHA3_256_BLOCK_SIZE;
674
0
            if (length <= WC_SHA3_256_BLOCK_SIZE) {
675
0
                if (key != NULL) {
676
0
                    XMEMCPY(ip, key, length);
677
0
                }
678
0
            }
679
0
            else {
680
0
                ret = wc_Sha3_256_Update(&hmac->hash.sha3, key, length);
681
0
                if (ret != 0)
682
0
                    break;
683
0
                ret = wc_Sha3_256_Final(&hmac->hash.sha3, ip);
684
0
                if (ret != 0)
685
0
                    break;
686
687
0
                length = WC_SHA3_256_DIGEST_SIZE;
688
0
            }
689
0
            break;
690
0
    #endif
691
0
    #ifndef WOLFSSL_NOSHA3_384
692
0
        case WC_SHA3_384:
693
0
            hmac_block_size = WC_SHA3_384_BLOCK_SIZE;
694
0
            if (length <= WC_SHA3_384_BLOCK_SIZE) {
695
0
                if (key != NULL) {
696
0
                    XMEMCPY(ip, key, length);
697
0
                }
698
0
            }
699
0
            else {
700
0
                ret = wc_Sha3_384_Update(&hmac->hash.sha3, key, length);
701
0
                if (ret != 0)
702
0
                    break;
703
0
                ret = wc_Sha3_384_Final(&hmac->hash.sha3, ip);
704
0
                if (ret != 0)
705
0
                    break;
706
707
0
                length = WC_SHA3_384_DIGEST_SIZE;
708
0
            }
709
0
            break;
710
0
    #endif
711
0
    #ifndef WOLFSSL_NOSHA3_512
712
0
        case WC_SHA3_512:
713
0
            hmac_block_size = WC_SHA3_512_BLOCK_SIZE;
714
0
            if (length <= WC_SHA3_512_BLOCK_SIZE) {
715
0
                if (key != NULL) {
716
0
                    XMEMCPY(ip, key, length);
717
0
                }
718
0
            }
719
0
            else {
720
0
                ret = wc_Sha3_512_Update(&hmac->hash.sha3, key, length);
721
0
                if (ret != 0)
722
0
                    break;
723
0
                ret = wc_Sha3_512_Final(&hmac->hash.sha3, ip);
724
0
                if (ret != 0)
725
0
                    break;
726
727
0
                length = WC_SHA3_512_DIGEST_SIZE;
728
0
            }
729
0
            break;
730
0
    #endif
731
0
    #endif /* WOLFSSL_SHA3 */
732
733
    #ifdef WOLFSSL_SM3
734
        case WC_SM3:
735
            hmac_block_size = WC_SM3_BLOCK_SIZE;
736
            if (length <= WC_SM3_BLOCK_SIZE) {
737
                if (key != NULL) {
738
                    XMEMCPY(ip, key, length);
739
                }
740
            }
741
            else {
742
                ret = wc_Sm3Update(&hmac->hash.sm3, key, length);
743
                if (ret != 0)
744
                    break;
745
                ret = wc_Sm3Final(&hmac->hash.sm3, ip);
746
                if (ret != 0)
747
                    break;
748
749
                length = WC_SM3_DIGEST_SIZE;
750
            }
751
            break;
752
    #endif
753
754
0
        default:
755
0
            return BAD_FUNC_ARG;
756
0
    }
757
758
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
759
    if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
760
    #if defined(HAVE_INTEL_QA) || defined(HAVE_CAVIUM)
761
        #ifdef HAVE_INTEL_QA
762
        if (IntelQaHmacGetType(hmac->macType, NULL) == 0)
763
        #endif
764
        {
765
            if (length > hmac_block_size)
766
                length = hmac_block_size;
767
            /* update key length */
768
            hmac->keyLen = (word16)length;
769
770
            return ret;
771
        }
772
        /* no need to pad below */
773
    #endif
774
    }
775
#endif
776
777
0
    if (ret == 0) {
778
0
        word32 i;
779
780
0
        if (length < hmac_block_size)
781
0
            XMEMSET(ip + length, 0, hmac_block_size - length);
782
783
0
        for(i = 0; i < hmac_block_size; i++) {
784
0
            op[i] = (byte)(ip[i] ^ OPAD);
785
0
            ip[i] ^= IPAD;
786
0
        }
787
0
    }
788
789
#ifdef WOLFSSL_HMAC_COPY_HASH
790
    if (ret == 0) {
791
        ret = _HmacInitIOHashes(hmac);
792
    }
793
#endif
794
795
0
    return ret;
796
0
#endif /* WOLFSSL_MAXQ108X */
797
0
}
798
799
int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
800
0
{
801
0
    int allowFlag;
802
    #if defined(HAVE_FIPS)
803
        allowFlag = 0; /* default false for FIPS cases */
804
    #else
805
0
        allowFlag = 1; /* default true for all non-FIPS cases */
806
0
    #endif
807
0
    return wc_HmacSetKey_ex(hmac, type, key, length, allowFlag);
808
0
}
809
810
int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length)
811
0
{
812
0
    int ret = 0;
813
814
0
    if (hmac == NULL || (msg == NULL && length > 0)) {
815
0
        return BAD_FUNC_ARG;
816
0
    }
817
818
#ifdef WOLF_CRYPTO_CB
819
    if (hmac->devId != INVALID_DEVID) {
820
        ret = wc_CryptoCb_Hmac(hmac, hmac->macType, msg, length, NULL);
821
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
822
            return ret;
823
        /* fall-through when unavailable */
824
        ret = 0; /* reset error code */
825
    }
826
#endif
827
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
828
    if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
829
    #if defined(HAVE_CAVIUM)
830
        return NitroxHmacUpdate(hmac, msg, length);
831
    #elif defined(HAVE_INTEL_QA)
832
        if (IntelQaHmacGetType(hmac->macType, NULL) == 0) {
833
            return IntelQaHmac(&hmac->asyncDev, hmac->macType,
834
                (byte*)hmac->ipad, hmac->keyLen, NULL, msg, length);
835
        }
836
    #endif
837
    }
838
#endif /* WOLFSSL_ASYNC_CRYPT */
839
840
0
    if (!hmac->innerHashKeyed) {
841
0
#ifndef WOLFSSL_HMAC_COPY_HASH
842
0
        ret = HmacKeyHashUpdate(hmac->macType, &hmac->hash, (byte*)hmac->ipad);
843
#else
844
        ret = HmacKeyCopyHash(hmac->macType, &hmac->i_hash, &hmac->hash);
845
#endif
846
0
        if (ret != 0)
847
0
            return ret;
848
0
        hmac->innerHashKeyed = WC_HMAC_INNER_HASH_KEYED_SW;
849
0
    }
850
851
0
    switch (hmac->macType) {
852
    #ifndef NO_MD5
853
        case WC_MD5:
854
            ret = wc_Md5Update(&hmac->hash.md5, msg, length);
855
            break;
856
    #endif /* !NO_MD5 */
857
858
0
    #ifndef NO_SHA
859
0
        case WC_SHA:
860
0
            ret = wc_ShaUpdate(&hmac->hash.sha, msg, length);
861
0
            break;
862
0
    #endif /* !NO_SHA */
863
864
0
    #ifdef WOLFSSL_SHA224
865
0
        case WC_SHA224:
866
0
            ret = wc_Sha224Update(&hmac->hash.sha224, msg, length);
867
0
            break;
868
0
    #endif /* WOLFSSL_SHA224 */
869
870
0
    #ifndef NO_SHA256
871
0
        case WC_SHA256:
872
0
            ret = wc_Sha256Update(&hmac->hash.sha256, msg, length);
873
0
            break;
874
0
    #endif /* !NO_SHA256 */
875
876
0
    #ifdef WOLFSSL_SHA384
877
0
        case WC_SHA384:
878
0
            ret = wc_Sha384Update(&hmac->hash.sha384, msg, length);
879
0
            break;
880
0
    #endif /* WOLFSSL_SHA384 */
881
0
    #ifdef WOLFSSL_SHA512
882
0
        case WC_SHA512:
883
0
            ret = wc_Sha512Update(&hmac->hash.sha512, msg, length);
884
0
            break;
885
0
    #endif /* WOLFSSL_SHA512 */
886
887
0
    #ifdef WOLFSSL_SHA3
888
0
    #ifndef WOLFSSL_NOSHA3_224
889
0
        case WC_SHA3_224:
890
0
            ret = wc_Sha3_224_Update(&hmac->hash.sha3, msg, length);
891
0
            break;
892
0
    #endif
893
0
    #ifndef WOLFSSL_NOSHA3_256
894
0
        case WC_SHA3_256:
895
0
            ret = wc_Sha3_256_Update(&hmac->hash.sha3, msg, length);
896
0
            break;
897
0
    #endif
898
0
    #ifndef WOLFSSL_NOSHA3_384
899
0
        case WC_SHA3_384:
900
0
            ret = wc_Sha3_384_Update(&hmac->hash.sha3, msg, length);
901
0
            break;
902
0
    #endif
903
0
    #ifndef WOLFSSL_NOSHA3_512
904
0
        case WC_SHA3_512:
905
0
            ret = wc_Sha3_512_Update(&hmac->hash.sha3, msg, length);
906
0
            break;
907
0
    #endif
908
0
    #endif /* WOLFSSL_SHA3 */
909
910
    #ifdef WOLFSSL_SM3
911
        case WC_SM3:
912
            ret = wc_Sm3Update(&hmac->hash.sm3, msg, length);
913
            break;
914
    #endif
915
916
0
        default:
917
0
            break;
918
0
    }
919
920
0
    return ret;
921
0
}
922
923
924
int wc_HmacFinal(Hmac* hmac, byte* hash)
925
0
{
926
0
    int ret;
927
928
0
    if (hmac == NULL || hash == NULL) {
929
0
        return BAD_FUNC_ARG;
930
0
    }
931
932
#ifdef WOLF_CRYPTO_CB
933
    if (hmac->devId != INVALID_DEVID) {
934
        ret = wc_CryptoCb_Hmac(hmac, hmac->macType, NULL, 0, hash);
935
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
936
            return ret;
937
        /* fall-through when unavailable */
938
    }
939
#endif
940
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
941
    if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
942
        int hashLen = wc_HmacSizeByType(hmac->macType);
943
        if (hashLen <= 0)
944
            return hashLen;
945
946
    #if defined(HAVE_CAVIUM)
947
        return NitroxHmacFinal(hmac, hash, hashLen);
948
    #elif defined(HAVE_INTEL_QA)
949
        if (IntelQaHmacGetType(hmac->macType, NULL) == 0) {
950
            return IntelQaHmac(&hmac->asyncDev, hmac->macType,
951
                (byte*)hmac->ipad, hmac->keyLen, hash, NULL, hashLen);
952
        }
953
    #endif
954
    }
955
#endif /* WOLFSSL_ASYNC_CRYPT */
956
957
0
    if (!hmac->innerHashKeyed) {
958
0
#ifndef WOLFSSL_HMAC_COPY_HASH
959
0
        ret = HmacKeyHashUpdate(hmac->macType, &hmac->hash, (byte*)hmac->ipad);
960
#else
961
        ret = HmacKeyCopyHash(hmac->macType, &hmac->i_hash, &hmac->hash);
962
#endif
963
0
        if (ret != 0)
964
0
            return ret;
965
0
        hmac->innerHashKeyed = WC_HMAC_INNER_HASH_KEYED_SW;
966
0
    }
967
968
0
    switch (hmac->macType) {
969
    #ifndef NO_MD5
970
        case WC_MD5:
971
            ret = wc_Md5Final(&hmac->hash.md5, (byte*)hmac->innerHash);
972
            if (ret != 0)
973
                break;
974
       #ifndef WOLFSSL_HMAC_COPY_HASH
975
            ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->opad,
976
                                                             WC_MD5_BLOCK_SIZE);
977
       #else
978
            ret = HmacKeyCopyHash(WC_MD5, &hmac->o_hash, &hmac->hash);
979
       #endif
980
            if (ret != 0)
981
                break;
982
            ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->innerHash,
983
                                                            WC_MD5_DIGEST_SIZE);
984
            if (ret != 0)
985
                break;
986
            ret = wc_Md5Final(&hmac->hash.md5, hash);
987
            break;
988
    #endif /* !NO_MD5 */
989
990
0
    #ifndef NO_SHA
991
0
        case WC_SHA:
992
0
            ret = wc_ShaFinal(&hmac->hash.sha, (byte*)hmac->innerHash);
993
0
            if (ret != 0)
994
0
                break;
995
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
996
0
            ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->opad,
997
0
                                                             WC_SHA_BLOCK_SIZE);
998
       #else
999
            ret = HmacKeyCopyHash(WC_SHA, &hmac->o_hash, &hmac->hash);
1000
       #endif
1001
0
            if (ret != 0)
1002
0
                break;
1003
0
            ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->innerHash,
1004
0
                                                            WC_SHA_DIGEST_SIZE);
1005
0
            if (ret != 0)
1006
0
                break;
1007
0
            ret = wc_ShaFinal(&hmac->hash.sha, hash);
1008
0
            break;
1009
0
    #endif /* !NO_SHA */
1010
1011
0
    #ifdef WOLFSSL_SHA224
1012
0
        case WC_SHA224:
1013
0
            ret = wc_Sha224Final(&hmac->hash.sha224, (byte*)hmac->innerHash);
1014
0
            if (ret != 0)
1015
0
                break;
1016
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
1017
0
            ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->opad,
1018
0
                                                          WC_SHA224_BLOCK_SIZE);
1019
       #else
1020
            ret = HmacKeyCopyHash(WC_SHA224, &hmac->o_hash, &hmac->hash);
1021
       #endif
1022
0
            if (ret != 0)
1023
0
                break;
1024
0
            ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->innerHash,
1025
0
                                                         WC_SHA224_DIGEST_SIZE);
1026
0
            if (ret != 0)
1027
0
                break;
1028
0
            ret = wc_Sha224Final(&hmac->hash.sha224, hash);
1029
0
            if (ret != 0)
1030
0
                break;
1031
0
            break;
1032
0
    #endif /* WOLFSSL_SHA224 */
1033
0
    #ifndef NO_SHA256
1034
0
        case WC_SHA256:
1035
0
            ret = wc_Sha256Final(&hmac->hash.sha256, (byte*)hmac->innerHash);
1036
0
            if (ret != 0)
1037
0
                break;
1038
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
1039
0
            ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->opad,
1040
0
                                                          WC_SHA256_BLOCK_SIZE);
1041
       #else
1042
            ret = HmacKeyCopyHash(WC_SHA256, &hmac->o_hash, &hmac->hash);
1043
       #endif
1044
0
            if (ret != 0)
1045
0
                break;
1046
0
            ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->innerHash,
1047
0
                                                         WC_SHA256_DIGEST_SIZE);
1048
0
            if (ret != 0)
1049
0
                break;
1050
0
            ret = wc_Sha256Final(&hmac->hash.sha256, hash);
1051
0
            break;
1052
0
    #endif /* !NO_SHA256 */
1053
1054
0
    #ifdef WOLFSSL_SHA384
1055
0
        case WC_SHA384:
1056
0
            ret = wc_Sha384Final(&hmac->hash.sha384, (byte*)hmac->innerHash);
1057
0
            if (ret != 0)
1058
0
                break;
1059
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
1060
0
            ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->opad,
1061
0
                                                          WC_SHA384_BLOCK_SIZE);
1062
       #else
1063
            ret = HmacKeyCopyHash(WC_SHA384, &hmac->o_hash, &hmac->hash);
1064
       #endif
1065
0
            if (ret != 0)
1066
0
                break;
1067
0
            ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->innerHash,
1068
0
                                                         WC_SHA384_DIGEST_SIZE);
1069
0
            if (ret != 0)
1070
0
                break;
1071
0
            ret = wc_Sha384Final(&hmac->hash.sha384, hash);
1072
0
            break;
1073
0
    #endif /* WOLFSSL_SHA384 */
1074
0
    #ifdef WOLFSSL_SHA512
1075
0
        case WC_SHA512:
1076
0
            ret = wc_Sha512Final(&hmac->hash.sha512, (byte*)hmac->innerHash);
1077
0
            if (ret != 0)
1078
0
                break;
1079
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
1080
0
            ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->opad,
1081
0
                                                          WC_SHA512_BLOCK_SIZE);
1082
       #else
1083
            ret = HmacKeyCopyHash(WC_SHA512, &hmac->o_hash, &hmac->hash);
1084
       #endif
1085
0
            if (ret != 0)
1086
0
                break;
1087
0
            ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->innerHash,
1088
0
                                                         WC_SHA512_DIGEST_SIZE);
1089
0
            if (ret != 0)
1090
0
                break;
1091
0
            ret = wc_Sha512Final(&hmac->hash.sha512, hash);
1092
0
            break;
1093
0
    #endif /* WOLFSSL_SHA512 */
1094
1095
0
    #ifdef WOLFSSL_SHA3
1096
0
    #ifndef WOLFSSL_NOSHA3_224
1097
0
        case WC_SHA3_224:
1098
0
            ret = wc_Sha3_224_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
1099
0
            if (ret != 0)
1100
0
                break;
1101
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
1102
0
            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->opad,
1103
0
                                                        WC_SHA3_224_BLOCK_SIZE);
1104
       #else
1105
            ret = HmacKeyCopyHash(WC_SHA3_224, &hmac->o_hash, &hmac->hash);
1106
       #endif
1107
0
            if (ret != 0)
1108
0
                break;
1109
0
            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
1110
0
                                                       WC_SHA3_224_DIGEST_SIZE);
1111
0
            if (ret != 0)
1112
0
                break;
1113
0
            ret = wc_Sha3_224_Final(&hmac->hash.sha3, hash);
1114
0
            break;
1115
0
    #endif
1116
0
    #ifndef WOLFSSL_NOSHA3_256
1117
0
        case WC_SHA3_256:
1118
0
            ret = wc_Sha3_256_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
1119
0
            if (ret != 0)
1120
0
                break;
1121
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
1122
0
            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->opad,
1123
0
                                                        WC_SHA3_256_BLOCK_SIZE);
1124
       #else
1125
            ret = HmacKeyCopyHash(WC_SHA3_256, &hmac->o_hash, &hmac->hash);
1126
       #endif
1127
0
            if (ret != 0)
1128
0
                break;
1129
0
            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
1130
0
                                                       WC_SHA3_256_DIGEST_SIZE);
1131
0
            if (ret != 0)
1132
0
                break;
1133
0
            ret = wc_Sha3_256_Final(&hmac->hash.sha3, hash);
1134
0
            break;
1135
0
    #endif
1136
0
    #ifndef WOLFSSL_NOSHA3_384
1137
0
        case WC_SHA3_384:
1138
0
            ret = wc_Sha3_384_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
1139
0
            if (ret != 0)
1140
0
                break;
1141
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
1142
0
            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->opad,
1143
0
                                                        WC_SHA3_384_BLOCK_SIZE);
1144
       #else
1145
            ret = HmacKeyCopyHash(WC_SHA3_384, &hmac->o_hash, &hmac->hash);
1146
       #endif
1147
0
            if (ret != 0)
1148
0
                break;
1149
0
            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
1150
0
                                                       WC_SHA3_384_DIGEST_SIZE);
1151
0
            if (ret != 0)
1152
0
                break;
1153
0
            ret = wc_Sha3_384_Final(&hmac->hash.sha3, hash);
1154
0
            break;
1155
0
    #endif
1156
0
    #ifndef WOLFSSL_NOSHA3_512
1157
0
        case WC_SHA3_512:
1158
0
            ret = wc_Sha3_512_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
1159
0
            if (ret != 0)
1160
0
                break;
1161
0
       #ifndef WOLFSSL_HMAC_COPY_HASH
1162
0
            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->opad,
1163
0
                                                        WC_SHA3_512_BLOCK_SIZE);
1164
       #else
1165
            ret = HmacKeyCopyHash(WC_SHA3_512, &hmac->o_hash, &hmac->hash);
1166
       #endif
1167
0
            if (ret != 0)
1168
0
                break;
1169
0
            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
1170
0
                                                       WC_SHA3_512_DIGEST_SIZE);
1171
0
            if (ret != 0)
1172
0
                break;
1173
0
            ret = wc_Sha3_512_Final(&hmac->hash.sha3, hash);
1174
0
            break;
1175
0
    #endif
1176
0
    #endif /* WOLFSSL_SHA3 */
1177
1178
    #ifdef WOLFSSL_SM3
1179
        case WC_SM3:
1180
            ret = wc_Sm3Final(&hmac->hash.sm3, (byte*)hmac->innerHash);
1181
            if (ret != 0)
1182
                break;
1183
       #ifndef WOLFSSL_HMAC_COPY_HASH
1184
            ret = wc_Sm3Update(&hmac->hash.sm3, (byte*)hmac->opad,
1185
                                                             WC_SM3_BLOCK_SIZE);
1186
       #else
1187
            ret = HmacKeyCopyHash(WC_SM3, &hmac->o_hash, &hmac->hash);
1188
       #endif
1189
            if (ret != 0)
1190
                break;
1191
            ret = wc_Sm3Update(&hmac->hash.sm3, (byte*)hmac->innerHash,
1192
                                                            WC_SM3_DIGEST_SIZE);
1193
            if (ret != 0)
1194
                break;
1195
            ret = wc_Sm3Final(&hmac->hash.sm3, hash);
1196
            break;
1197
    #endif
1198
1199
0
        default:
1200
0
            ret = BAD_FUNC_ARG;
1201
0
            break;
1202
0
    }
1203
1204
0
    if (ret == 0) {
1205
0
        hmac->innerHashKeyed = 0;
1206
0
    }
1207
1208
0
    return ret;
1209
0
}
1210
1211
#ifdef WOLFSSL_KCAPI_HMAC
1212
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hmac.c */
1213
1214
    /* unmap the _Software calls used by kcapi_hmac.c */
1215
    #undef wc_HmacSetKey
1216
    #undef wc_HmacUpdate
1217
    #undef wc_HmacFinal
1218
1219
#else
1220
/* Initialize Hmac for use with async device */
1221
int wc_HmacInit(Hmac* hmac, void* heap, int devId)
1222
0
{
1223
0
    int ret = 0;
1224
1225
0
    if (hmac == NULL)
1226
0
        return BAD_FUNC_ARG;
1227
1228
0
    XMEMSET(hmac, 0, sizeof(Hmac));
1229
0
    hmac->macType = WC_HASH_TYPE_NONE;
1230
0
    hmac->heap = heap;
1231
#ifdef WOLF_CRYPTO_CB
1232
    hmac->devId = devId;
1233
    hmac->devCtx = NULL;
1234
#endif
1235
#if defined(WOLFSSL_DEVCRYPTO_HMAC)
1236
    hmac->ctx.cfd = -1;
1237
#endif
1238
1239
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
1240
    ret = wolfAsync_DevCtxInit(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC,
1241
                                                         hmac->heap, devId);
1242
#else
1243
0
    (void)devId;
1244
0
#endif /* WOLFSSL_ASYNC_CRYPT */
1245
1246
0
    return ret;
1247
0
}
1248
1249
#ifdef WOLF_PRIVATE_KEY_ID
1250
int  wc_HmacInit_Id(Hmac* hmac, unsigned char* id, int len, void* heap,
1251
                    int devId)
1252
{
1253
    int ret = 0;
1254
1255
    if (hmac == NULL)
1256
        ret = BAD_FUNC_ARG;
1257
    if (ret == 0 && (len < 0 || len > HMAC_MAX_ID_LEN))
1258
        ret = BUFFER_E;
1259
1260
    if (ret == 0)
1261
        ret = wc_HmacInit(hmac, heap, devId);
1262
    if (ret == 0) {
1263
        XMEMCPY(hmac->id, id, (size_t)len);
1264
        hmac->idLen = len;
1265
    }
1266
1267
    return ret;
1268
}
1269
1270
int wc_HmacInit_Label(Hmac* hmac, const char* label, void* heap, int devId)
1271
{
1272
    int ret = 0;
1273
    int labelLen = 0;
1274
1275
    if (hmac == NULL || label == NULL)
1276
        ret = BAD_FUNC_ARG;
1277
    if (ret == 0) {
1278
        labelLen = (int)XSTRLEN(label);
1279
        if (labelLen == 0 || labelLen > HMAC_MAX_LABEL_LEN)
1280
            ret = BUFFER_E;
1281
    }
1282
1283
    if (ret == 0)
1284
        ret  = wc_HmacInit(hmac, heap, devId);
1285
    if (ret == 0) {
1286
        XMEMCPY(hmac->label, label, (size_t)labelLen);
1287
        hmac->labelLen = labelLen;
1288
    }
1289
1290
    return ret;
1291
}
1292
#endif /* WOLF_PRIVATE_KEY_ID */
1293
1294
/* Free Hmac from use with async device */
1295
void wc_HmacFree(Hmac* hmac)
1296
0
{
1297
0
    if (hmac == NULL)
1298
0
        return;
1299
1300
#ifdef WOLF_CRYPTO_CB
1301
    /* handle cleanup case where final is not called */
1302
    if (hmac->devId != INVALID_DEVID && hmac->devCtx != NULL) {
1303
        int  ret;
1304
        byte finalHash[WC_HMAC_BLOCK_SIZE];
1305
        ret = wc_CryptoCb_Hmac(hmac, hmac->macType, NULL, 0, finalHash);
1306
        (void)ret; /* must ignore return code here */
1307
        (void)finalHash;
1308
    }
1309
#endif
1310
1311
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
1312
    wolfAsync_DevCtxFree(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC);
1313
#endif /* WOLFSSL_ASYNC_CRYPT */
1314
1315
0
    switch (hmac->macType) {
1316
    #ifndef NO_MD5
1317
        case WC_MD5:
1318
            wc_Md5Free(&hmac->hash.md5);
1319
        #ifdef WOLFSSL_HMAC_COPY_HASH
1320
            wc_Md5Free(&hmac->i_hash.md5);
1321
            wc_Md5Free(&hmac->o_hash.md5);
1322
        #endif
1323
            break;
1324
    #endif /* !NO_MD5 */
1325
1326
0
    #ifndef NO_SHA
1327
0
        case WC_SHA:
1328
0
            wc_ShaFree(&hmac->hash.sha);
1329
        #ifdef WOLFSSL_HMAC_COPY_HASH
1330
            wc_ShaFree(&hmac->i_hash.sha);
1331
            wc_ShaFree(&hmac->o_hash.sha);
1332
        #endif
1333
0
            break;
1334
0
    #endif /* !NO_SHA */
1335
1336
0
    #ifdef WOLFSSL_SHA224
1337
0
        case WC_SHA224:
1338
0
            wc_Sha224Free(&hmac->hash.sha224);
1339
        #ifdef WOLFSSL_HMAC_COPY_HASH
1340
            wc_Sha224Free(&hmac->i_hash.sha224);
1341
            wc_Sha224Free(&hmac->o_hash.sha224);
1342
        #endif
1343
0
            break;
1344
0
    #endif /* WOLFSSL_SHA224 */
1345
0
    #ifndef NO_SHA256
1346
0
        case WC_SHA256:
1347
0
            wc_Sha256Free(&hmac->hash.sha256);
1348
        #ifdef WOLFSSL_HMAC_COPY_HASH
1349
            wc_Sha256Free(&hmac->i_hash.sha256);
1350
            wc_Sha256Free(&hmac->o_hash.sha256);
1351
        #endif
1352
0
            break;
1353
0
    #endif /* !NO_SHA256 */
1354
1355
0
    #ifdef WOLFSSL_SHA384
1356
0
        case WC_SHA384:
1357
0
            wc_Sha384Free(&hmac->hash.sha384);
1358
        #ifdef WOLFSSL_HMAC_COPY_HASH
1359
            wc_Sha384Free(&hmac->i_hash.sha384);
1360
            wc_Sha384Free(&hmac->o_hash.sha384);
1361
        #endif
1362
0
            break;
1363
0
    #endif /* WOLFSSL_SHA384 */
1364
0
    #ifdef WOLFSSL_SHA512
1365
0
        case WC_SHA512:
1366
0
            wc_Sha512Free(&hmac->hash.sha512);
1367
        #ifdef WOLFSSL_HMAC_COPY_HASH
1368
            wc_Sha512Free(&hmac->i_hash.sha512);
1369
            wc_Sha512Free(&hmac->o_hash.sha512);
1370
        #endif
1371
0
            break;
1372
0
    #endif /* WOLFSSL_SHA512 */
1373
1374
0
    #ifdef WOLFSSL_SHA3
1375
0
    #ifndef WOLFSSL_NOSHA3_224
1376
0
        case WC_SHA3_224:
1377
0
            wc_Sha3_224_Free(&hmac->hash.sha3);
1378
        #ifdef WOLFSSL_HMAC_COPY_HASH
1379
            wc_Sha3_224_Free(&hmac->i_hash.sha3);
1380
            wc_Sha3_224_Free(&hmac->o_hash.sha3);
1381
        #endif
1382
0
            break;
1383
0
    #endif
1384
0
    #ifndef WOLFSSL_NOSHA3_256
1385
0
        case WC_SHA3_256:
1386
0
            wc_Sha3_256_Free(&hmac->hash.sha3);
1387
        #ifdef WOLFSSL_HMAC_COPY_HASH
1388
            wc_Sha3_256_Free(&hmac->i_hash.sha3);
1389
            wc_Sha3_256_Free(&hmac->o_hash.sha3);
1390
        #endif
1391
0
            break;
1392
0
    #endif
1393
0
    #ifndef WOLFSSL_NOSHA3_384
1394
0
        case WC_SHA3_384:
1395
0
            wc_Sha3_384_Free(&hmac->hash.sha3);
1396
        #ifdef WOLFSSL_HMAC_COPY_HASH
1397
            wc_Sha3_384_Free(&hmac->i_hash.sha3);
1398
            wc_Sha3_384_Free(&hmac->o_hash.sha3);
1399
        #endif
1400
0
            break;
1401
0
    #endif
1402
0
    #ifndef WOLFSSL_NOSHA3_512
1403
0
        case WC_SHA3_512:
1404
0
            wc_Sha3_512_Free(&hmac->hash.sha3);
1405
        #ifdef WOLFSSL_HMAC_COPY_HASH
1406
            wc_Sha3_512_Free(&hmac->i_hash.sha3);
1407
            wc_Sha3_512_Free(&hmac->o_hash.sha3);
1408
        #endif
1409
0
            break;
1410
0
    #endif
1411
0
    #endif /* WOLFSSL_SHA3 */
1412
1413
    #ifdef WOLFSSL_SM3
1414
        case WC_SM3:
1415
            wc_Sm3Free(&hmac->hash.sm3);
1416
        #ifdef WOLFSSL_HMAC_COPY_HASH
1417
            wc_Sm3Free(&hmac->i_hash.sm3);
1418
            wc_Sm3Free(&hmac->i_hash.sm3);
1419
        #endif
1420
            break;
1421
    #endif
1422
1423
0
        default:
1424
0
            break;
1425
0
    }
1426
1427
0
    ForceZero(hmac, sizeof(*hmac));
1428
0
}
1429
#endif /* WOLFSSL_KCAPI_HMAC */
1430
1431
int wolfSSL_GetHmacMaxSize(void)
1432
0
{
1433
0
    return WC_MAX_DIGEST_SIZE;
1434
0
}
1435
1436
#ifdef HAVE_HKDF
1437
    /* HMAC-KDF-Extract.
1438
     * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
1439
     *
1440
     * type     The hash algorithm type.
1441
     * salt     The optional salt value.
1442
     * saltSz   The size of the salt.
1443
     * inKey    The input keying material.
1444
     * inKeySz  The size of the input keying material.
1445
     * out      The pseudorandom key with the length that of the hash.
1446
     * returns 0 on success, otherwise failure.
1447
     */
1448
    int wc_HKDF_Extract_ex(int type, const byte* salt, word32 saltSz,
1449
        const byte* inKey, word32 inKeySz, byte* out, void* heap, int devId)
1450
0
    {
1451
0
        byte   tmp[WC_MAX_DIGEST_SIZE]; /* localSalt helper */
1452
    #ifdef WOLFSSL_SMALL_STACK
1453
        Hmac*  myHmac;
1454
    #else
1455
0
        Hmac   myHmac[1];
1456
0
    #endif
1457
0
        int    ret;
1458
0
        const  byte* localSalt;  /* either points to user input or tmp */
1459
0
        word32 hashSz;
1460
1461
0
        ret = wc_HmacSizeByType(type);
1462
0
        if (ret < 0) {
1463
0
            return ret;
1464
0
        }
1465
1466
    #ifdef WOLFSSL_SMALL_STACK
1467
        myHmac = (Hmac*)XMALLOC(sizeof(Hmac), NULL, DYNAMIC_TYPE_HMAC);
1468
        if (myHmac == NULL) {
1469
            return MEMORY_E;
1470
        }
1471
    #endif
1472
1473
0
        hashSz = (word32)ret;
1474
0
        localSalt = salt;
1475
0
        if (localSalt == NULL) {
1476
0
            XMEMSET(tmp, 0, hashSz);
1477
0
            localSalt = tmp;
1478
0
            saltSz    = hashSz;
1479
0
        }
1480
1481
0
        ret = wc_HmacInit(myHmac, heap, devId);
1482
0
        if (ret == 0) {
1483
        #if FIPS_VERSION3_GE(6,0,0)
1484
            ret = wc_HmacSetKey_ex(myHmac, type, localSalt, saltSz,
1485
                                   FIPS_ALLOW_SHORT);
1486
        #else
1487
0
            ret = wc_HmacSetKey(myHmac, type, localSalt, saltSz);
1488
0
        #endif
1489
0
            if (ret == 0)
1490
0
                ret = wc_HmacUpdate(myHmac, inKey, inKeySz);
1491
0
            if (ret == 0)
1492
0
                ret = wc_HmacFinal(myHmac,  out);
1493
0
            wc_HmacFree(myHmac);
1494
0
        }
1495
    #ifdef WOLFSSL_SMALL_STACK
1496
        XFREE(myHmac, NULL, DYNAMIC_TYPE_HMAC);
1497
    #endif
1498
1499
0
        return ret;
1500
0
    }
1501
1502
    int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz,
1503
                        const byte* inKey, word32 inKeySz, byte* out)
1504
0
    {
1505
0
        return wc_HKDF_Extract_ex(type, salt, saltSz, inKey, inKeySz, out, NULL,
1506
0
            INVALID_DEVID);
1507
0
    }
1508
1509
    /* HMAC-KDF-Expand.
1510
     * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
1511
     *
1512
     * type     The hash algorithm type.
1513
     * inKey    The input key.
1514
     * inKeySz  The size of the input key.
1515
     * info     The application specific information.
1516
     * infoSz   The size of the application specific information.
1517
     * out      The output keying material.
1518
     * returns 0 on success, otherwise failure.
1519
     */
1520
    int wc_HKDF_Expand_ex(int type, const byte* inKey, word32 inKeySz,
1521
                       const byte* info, word32 infoSz, byte* out, word32 outSz,
1522
                       void* heap, int devId)
1523
0
    {
1524
0
        byte   tmp[WC_MAX_DIGEST_SIZE];
1525
    #ifdef WOLFSSL_SMALL_STACK
1526
        Hmac*  myHmac;
1527
    #else
1528
0
        Hmac   myHmac[1];
1529
0
    #endif
1530
0
        int    ret = 0;
1531
0
        word32 outIdx = 0;
1532
0
        word32 hashSz;
1533
0
        byte   n = 0x1;
1534
1535
0
        ret = wc_HmacSizeByType(type);
1536
0
        if (ret < 0) {
1537
0
            return ret;
1538
0
        }
1539
0
        hashSz = (word32)ret;
1540
1541
        /* RFC 5869 states that the length of output keying material in
1542
         * octets must be L <= 255*HashLen or N = ceil(L/HashLen) */
1543
1544
0
        if (out == NULL || ((outSz/hashSz) + ((outSz % hashSz) != 0)) > 255) {
1545
0
            return BAD_FUNC_ARG;
1546
0
        }
1547
1548
    #ifdef WOLFSSL_SMALL_STACK
1549
        myHmac = (Hmac*)XMALLOC(sizeof(Hmac), NULL, DYNAMIC_TYPE_HMAC);
1550
        if (myHmac == NULL) {
1551
            return MEMORY_E;
1552
        }
1553
    #endif
1554
1555
0
        ret = wc_HmacInit(myHmac, heap, devId);
1556
0
        if (ret != 0) {
1557
    #ifdef WOLFSSL_SMALL_STACK
1558
        XFREE(myHmac, NULL, DYNAMIC_TYPE_HMAC);
1559
    #endif
1560
0
            return ret;
1561
0
        }
1562
1563
0
        XMEMSET(tmp, 0, WC_MAX_DIGEST_SIZE);
1564
1565
0
        while (outIdx < outSz) {
1566
0
            word32 tmpSz = (n == 1) ? 0 : hashSz;
1567
0
            word32 left = outSz - outIdx;
1568
1569
        #if FIPS_VERSION3_GE(6,0,0)
1570
            ret = wc_HmacSetKey_ex(myHmac, type, inKey, inKeySz,
1571
                                   FIPS_ALLOW_SHORT);
1572
        #else
1573
0
            ret = wc_HmacSetKey(myHmac, type, inKey, inKeySz);
1574
0
        #endif
1575
0
            if (ret != 0)
1576
0
                break;
1577
0
            ret = wc_HmacUpdate(myHmac, tmp, tmpSz);
1578
0
            if (ret != 0)
1579
0
                break;
1580
0
            ret = wc_HmacUpdate(myHmac, info, infoSz);
1581
0
            if (ret != 0)
1582
0
                break;
1583
0
            ret = wc_HmacUpdate(myHmac, &n, 1);
1584
0
            if (ret != 0)
1585
0
                break;
1586
0
            ret = wc_HmacFinal(myHmac, tmp);
1587
0
            if (ret != 0)
1588
0
                break;
1589
1590
0
            left = min(left, hashSz);
1591
0
            XMEMCPY(out+outIdx, tmp, left);
1592
1593
0
            outIdx += left;
1594
0
            n++;
1595
0
        }
1596
1597
0
        wc_HmacFree(myHmac);
1598
    #ifdef WOLFSSL_SMALL_STACK
1599
        XFREE(myHmac, NULL, DYNAMIC_TYPE_HMAC);
1600
    #endif
1601
1602
0
        return ret;
1603
0
    }
1604
1605
    int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz,
1606
                       const byte* info, word32 infoSz, byte* out, word32 outSz)
1607
0
    {
1608
0
        return wc_HKDF_Expand_ex(type, inKey, inKeySz, info, infoSz, out, outSz,
1609
0
            NULL, INVALID_DEVID);
1610
0
    }
1611
1612
    /* HMAC-KDF.
1613
     * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
1614
     *
1615
     * type     The hash algorithm type.
1616
     * inKey    The input keying material.
1617
     * inKeySz  The size of the input keying material.
1618
     * salt     The optional salt value.
1619
     * saltSz   The size of the salt.
1620
     * info     The application specific information.
1621
     * infoSz   The size of the application specific information.
1622
     * out      The output keying material.
1623
     * returns 0 on success, otherwise failure.
1624
     */
1625
    int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
1626
                       const byte* salt,  word32 saltSz,
1627
                       const byte* info,  word32 infoSz,
1628
                       byte* out,         word32 outSz)
1629
0
    {
1630
0
        byte   prk[WC_MAX_DIGEST_SIZE];
1631
0
        word32 hashSz;
1632
0
        int    ret;
1633
1634
0
        ret = wc_HmacSizeByType(type);
1635
0
        if (ret < 0) {
1636
0
            return ret;
1637
0
        }
1638
0
        hashSz = (word32)ret;
1639
1640
0
        ret = wc_HKDF_Extract(type, salt, saltSz, inKey, inKeySz, prk);
1641
0
        if (ret != 0)
1642
0
            return ret;
1643
1644
0
        return wc_HKDF_Expand(type, prk, hashSz, info, infoSz, out, outSz);
1645
0
    }
1646
1647
#endif /* HAVE_HKDF */
1648
1649
#endif /* NO_HMAC */