Coverage Report

Created: 2026-05-21 06:58

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