Coverage Report

Created: 2022-08-24 06:37

/src/wolfssl-sp-math-all-8bit/wolfcrypt/src/hmac.c
Line
Count
Source (jump to first uncovered line)
1
/* hmac.c
2
 *
3
 * Copyright (C) 2006-2022 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
#ifdef HAVE_CONFIG_H
24
    #include <config.h>
25
#endif
26
27
#include <wolfssl/wolfcrypt/wc_port.h>
28
#include <wolfssl/wolfcrypt/error-crypt.h>
29
#include <wolfssl/wolfcrypt/logging.h>
30
31
#ifndef NO_HMAC
32
33
#if defined(HAVE_FIPS) && \
34
    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
35
36
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
37
    #define FIPS_NO_WRAPPERS
38
39
    #ifdef USE_WINDOWS_API
40
        #pragma code_seg(".fipsA$b")
41
        #pragma const_seg(".fipsB$b")
42
    #endif
43
#endif
44
45
#include <wolfssl/wolfcrypt/hmac.h>
46
47
#ifdef WOLF_CRYPTO_CB
48
    #include <wolfssl/wolfcrypt/cryptocb.h>
49
#endif
50
51
#ifdef NO_INLINE
52
    #include <wolfssl/wolfcrypt/misc.h>
53
#else
54
    #define WOLFSSL_MISC_INCLUDED
55
    #include <wolfcrypt/src/misc.c>
56
#endif
57
58
#ifdef WOLFSSL_KCAPI_HMAC
59
    #include <wolfssl/wolfcrypt/port/kcapi/kcapi_hmac.h>
60
61
    /* map the _Software calls used by kcapi_hmac.c */
62
    #define wc_HmacSetKey  wc_HmacSetKey_Software
63
    #define wc_HmacUpdate  wc_HmacUpdate_Software
64
    #define wc_HmacFinal   wc_HmacFinal_Software
65
#endif
66
67
68
/* fips wrapper calls, user can call direct */
69
/* If building for old FIPS. */
70
#if defined(HAVE_FIPS) && \
71
    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
72
73
    /* does init */
74
    int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 keySz)
75
    {
76
        if (hmac == NULL || (key == NULL && keySz != 0) ||
77
           !(type == WC_MD5 || type == WC_SHA || type == WC_SHA256 ||
78
                type == WC_SHA384 || type == WC_SHA512)) {
79
            return BAD_FUNC_ARG;
80
        }
81
82
        return HmacSetKey_fips(hmac, type, key, keySz);
83
    }
84
    int wc_HmacUpdate(Hmac* hmac, const byte* in, word32 sz)
85
    {
86
        if (hmac == NULL || (in == NULL && sz > 0)) {
87
            return BAD_FUNC_ARG;
88
        }
89
90
        return HmacUpdate_fips(hmac, in, sz);
91
    }
92
    int wc_HmacFinal(Hmac* hmac, byte* out)
93
    {
94
        if (hmac == NULL) {
95
            return BAD_FUNC_ARG;
96
        }
97
98
        return HmacFinal_fips(hmac, out);
99
    }
100
    int wolfSSL_GetHmacMaxSize(void)
101
    {
102
        return CyaSSL_GetHmacMaxSize();
103
    }
104
105
    int wc_HmacInit(Hmac* hmac, void* heap, int devId)
106
    {
107
    #ifndef WOLFSSL_KCAPI_HMAC
108
        (void)hmac;
109
        (void)heap;
110
        (void)devId;
111
        return 0;
112
    #else
113
        return HmacInit(hmac, heap, devId);
114
    #endif
115
    }
116
    void wc_HmacFree(Hmac* hmac)
117
    {
118
    #ifndef WOLFSSL_KCAPI_HMAC
119
        (void)hmac;
120
    #else
121
        HmacFree(hmac);
122
    #endif
123
    }
124
125
    #ifdef HAVE_HKDF
126
        int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
127
                    const byte* salt, word32 saltSz,
128
                    const byte* info, word32 infoSz,
129
                    byte* out, word32 outSz)
130
        {
131
            return HKDF(type, inKey, inKeySz, salt, saltSz,
132
                info, infoSz, out, outSz);
133
        }
134
    #endif /* HAVE_HKDF */
135
136
#else /* else build without fips, or for new fips */
137
138
139
int wc_HmacSizeByType(int type)
140
252
{
141
252
    int ret;
142
143
252
    if (!(type == WC_MD5 || type == WC_SHA ||
144
252
            type == WC_SHA224 || type == WC_SHA256 ||
145
252
            type == WC_SHA384 || type == WC_SHA512 ||
146
252
            type == WC_SHA3_224 || type == WC_SHA3_256 ||
147
252
            type == WC_SHA3_384 || type == WC_SHA3_512)) {
148
0
        return BAD_FUNC_ARG;
149
0
    }
150
151
252
    switch (type) {
152
0
    #ifndef NO_MD5
153
0
        case WC_MD5:
154
0
            ret = WC_MD5_DIGEST_SIZE;
155
0
            break;
156
0
    #endif /* !NO_MD5 */
157
158
0
    #ifndef NO_SHA
159
0
        case WC_SHA:
160
0
            ret = WC_SHA_DIGEST_SIZE;
161
0
            break;
162
0
    #endif /* !NO_SHA */
163
164
0
    #ifdef WOLFSSL_SHA224
165
0
        case WC_SHA224:
166
0
            ret = WC_SHA224_DIGEST_SIZE;
167
0
            break;
168
0
    #endif /* WOLFSSL_SHA224 */
169
170
0
    #ifndef NO_SHA256
171
252
        case WC_SHA256:
172
252
            ret = WC_SHA256_DIGEST_SIZE;
173
252
            break;
174
0
    #endif /* !NO_SHA256 */
175
176
0
    #ifdef WOLFSSL_SHA384
177
0
        case WC_SHA384:
178
0
            ret = WC_SHA384_DIGEST_SIZE;
179
0
            break;
180
0
    #endif /* WOLFSSL_SHA384 */
181
0
    #ifdef WOLFSSL_SHA512
182
0
        case WC_SHA512:
183
0
            ret = WC_SHA512_DIGEST_SIZE;
184
0
            break;
185
0
    #endif /* WOLFSSL_SHA512 */
186
187
0
    #ifdef WOLFSSL_SHA3
188
0
        case WC_SHA3_224:
189
0
            ret = WC_SHA3_224_DIGEST_SIZE;
190
0
            break;
191
192
0
        case WC_SHA3_256:
193
0
            ret = WC_SHA3_256_DIGEST_SIZE;
194
0
            break;
195
196
0
        case WC_SHA3_384:
197
0
            ret = WC_SHA3_384_DIGEST_SIZE;
198
0
            break;
199
200
0
        case WC_SHA3_512:
201
0
            ret = WC_SHA3_512_DIGEST_SIZE;
202
0
            break;
203
204
0
    #endif
205
206
0
        default:
207
0
            ret = BAD_FUNC_ARG;
208
0
            break;
209
252
    }
210
211
252
    return ret;
212
252
}
213
214
int _InitHmac(Hmac* hmac, int type, void* heap)
215
336
{
216
336
    int ret = 0;
217
336
#ifdef WOLF_CRYPTO_CB
218
336
    int devId = hmac->devId;
219
#else
220
    int devId = INVALID_DEVID;
221
#endif
222
336
    switch (type) {
223
0
    #ifndef NO_MD5
224
0
        case WC_MD5:
225
0
            ret = wc_InitMd5_ex(&hmac->hash.md5, heap, devId);
226
0
            break;
227
0
    #endif /* !NO_MD5 */
228
229
0
    #ifndef NO_SHA
230
0
        case WC_SHA:
231
0
            ret = wc_InitSha_ex(&hmac->hash.sha, heap, devId);
232
0
            break;
233
0
    #endif /* !NO_SHA */
234
235
0
    #ifdef WOLFSSL_SHA224
236
0
        case WC_SHA224:
237
0
            ret = wc_InitSha224_ex(&hmac->hash.sha224, heap, devId);
238
0
            break;
239
0
    #endif /* WOLFSSL_SHA224 */
240
241
0
    #ifndef NO_SHA256
242
336
        case WC_SHA256:
243
336
            ret = wc_InitSha256_ex(&hmac->hash.sha256, heap, devId);
244
336
            break;
245
0
    #endif /* !NO_SHA256 */
246
247
0
    #ifdef WOLFSSL_SHA384
248
0
        case WC_SHA384:
249
0
            ret = wc_InitSha384_ex(&hmac->hash.sha384, heap, devId);
250
0
            break;
251
0
    #endif /* WOLFSSL_SHA384 */
252
0
    #ifdef WOLFSSL_SHA512
253
0
        case WC_SHA512:
254
0
            ret = wc_InitSha512_ex(&hmac->hash.sha512, heap, devId);
255
0
            break;
256
0
    #endif /* WOLFSSL_SHA512 */
257
258
0
    #ifdef WOLFSSL_SHA3
259
0
    #ifndef WOLFSSL_NOSHA3_224
260
0
        case WC_SHA3_224:
261
0
            ret = wc_InitSha3_224(&hmac->hash.sha3, heap, devId);
262
0
            break;
263
0
    #endif
264
0
    #ifndef WOLFSSL_NOSHA3_256
265
0
        case WC_SHA3_256:
266
0
            ret = wc_InitSha3_256(&hmac->hash.sha3, heap, devId);
267
0
            break;
268
0
    #endif
269
0
    #ifndef WOLFSSL_NOSHA3_384
270
0
        case WC_SHA3_384:
271
0
            ret = wc_InitSha3_384(&hmac->hash.sha3, heap, devId);
272
0
            break;
273
0
    #endif
274
0
    #ifndef WOLFSSL_NOSHA3_512
275
0
        case WC_SHA3_512:
276
0
            ret = wc_InitSha3_512(&hmac->hash.sha3, heap, devId);
277
0
            break;
278
0
    #endif
279
0
    #endif
280
281
0
        default:
282
0
            ret = BAD_FUNC_ARG;
283
0
            break;
284
336
    }
285
286
    /* default to NULL heap hint or test value */
287
#ifdef WOLFSSL_HEAP_TEST
288
    hmac->heap = (void*)WOLFSSL_HEAP_TEST;
289
#else
290
336
    hmac->heap = heap;
291
336
#endif /* WOLFSSL_HEAP_TEST */
292
293
336
    return ret;
294
336
}
295
296
297
int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
298
336
{
299
336
    byte*  ip;
300
336
    byte*  op;
301
336
    word32 i, hmac_block_size = 0;
302
336
    int    ret = 0;
303
336
    void*  heap = NULL;
304
305
336
    if (hmac == NULL || (key == NULL && length != 0) ||
306
336
       !(type == WC_MD5 || type == WC_SHA ||
307
336
            type == WC_SHA224 || type == WC_SHA256 ||
308
336
            type == WC_SHA384 || type == WC_SHA512 ||
309
336
            type == WC_SHA3_224 || type == WC_SHA3_256 ||
310
336
            type == WC_SHA3_384 || type == WC_SHA3_512)) {
311
0
        return BAD_FUNC_ARG;
312
0
    }
313
314
336
#ifndef HAVE_FIPS
315
    /* if set key has already been run then make sure and free existing */
316
    /* This is for async and PIC32MZ situations, and just normally OK,
317
       provided the user calls wc_HmacInit() first. That function is not
318
       available in FIPS builds. In current FIPS builds, the hashes are
319
       not allocating resources. */
320
336
    if (hmac->macType != WC_HASH_TYPE_NONE) {
321
84
        wc_HmacFree(hmac);
322
84
    }
323
336
#endif
324
325
336
    hmac->innerHashKeyed = 0;
326
336
    hmac->macType = (byte)type;
327
328
336
    ret = _InitHmac(hmac, type, heap);
329
336
    if (ret != 0)
330
0
        return ret;
331
332
#ifdef HAVE_FIPS
333
    if (length < HMAC_FIPS_MIN_KEY) {
334
        WOLFSSL_ERROR_VERBOSE(HMAC_MIN_KEYLEN_E);
335
        return HMAC_MIN_KEYLEN_E;
336
    }
337
#endif
338
339
336
#ifdef WOLF_CRYPTO_CB
340
336
    hmac->keyRaw = key; /* use buffer directly */
341
336
    hmac->keyLen = length;
342
336
#endif
343
344
336
    ip = (byte*)hmac->ipad;
345
336
    op = (byte*)hmac->opad;
346
347
336
    switch (hmac->macType) {
348
0
    #ifndef NO_MD5
349
0
        case WC_MD5:
350
0
            hmac_block_size = WC_MD5_BLOCK_SIZE;
351
0
            if (length <= WC_MD5_BLOCK_SIZE) {
352
0
                if (key != NULL) {
353
0
                    XMEMCPY(ip, key, length);
354
0
                }
355
0
            }
356
0
            else {
357
0
                ret = wc_Md5Update(&hmac->hash.md5, key, length);
358
0
                if (ret != 0)
359
0
                    break;
360
0
                ret = wc_Md5Final(&hmac->hash.md5, ip);
361
0
                if (ret != 0)
362
0
                    break;
363
0
                length = WC_MD5_DIGEST_SIZE;
364
0
            }
365
0
            break;
366
0
    #endif /* !NO_MD5 */
367
368
0
    #ifndef NO_SHA
369
0
        case WC_SHA:
370
0
            hmac_block_size = WC_SHA_BLOCK_SIZE;
371
0
            if (length <= WC_SHA_BLOCK_SIZE) {
372
0
                if (key != NULL) {
373
0
                    XMEMCPY(ip, key, length);
374
0
                }
375
0
            }
376
0
            else {
377
0
                ret = wc_ShaUpdate(&hmac->hash.sha, key, length);
378
0
                if (ret != 0)
379
0
                    break;
380
0
                ret = wc_ShaFinal(&hmac->hash.sha, ip);
381
0
                if (ret != 0)
382
0
                    break;
383
384
0
                length = WC_SHA_DIGEST_SIZE;
385
0
            }
386
0
            break;
387
0
    #endif /* !NO_SHA */
388
389
0
    #ifdef WOLFSSL_SHA224
390
0
        case WC_SHA224:
391
0
            hmac_block_size = WC_SHA224_BLOCK_SIZE;
392
0
            if (length <= WC_SHA224_BLOCK_SIZE) {
393
0
                if (key != NULL) {
394
0
                    XMEMCPY(ip, key, length);
395
0
                }
396
0
            }
397
0
            else {
398
0
                ret = wc_Sha224Update(&hmac->hash.sha224, key, length);
399
0
                if (ret != 0)
400
0
                    break;
401
0
                ret = wc_Sha224Final(&hmac->hash.sha224, ip);
402
0
                if (ret != 0)
403
0
                    break;
404
405
0
                length = WC_SHA224_DIGEST_SIZE;
406
0
            }
407
0
            break;
408
0
    #endif /* WOLFSSL_SHA224 */
409
0
    #ifndef NO_SHA256
410
336
        case WC_SHA256:
411
336
            hmac_block_size = WC_SHA256_BLOCK_SIZE;
412
336
            if (length <= WC_SHA256_BLOCK_SIZE) {
413
336
                if (key != NULL) {
414
336
                    XMEMCPY(ip, key, length);
415
336
                }
416
336
            }
417
0
            else {
418
0
                ret = wc_Sha256Update(&hmac->hash.sha256, key, length);
419
0
                if (ret != 0)
420
0
                    break;
421
0
                ret = wc_Sha256Final(&hmac->hash.sha256, ip);
422
0
                if (ret != 0)
423
0
                    break;
424
425
0
                length = WC_SHA256_DIGEST_SIZE;
426
0
            }
427
336
            break;
428
336
    #endif /* !NO_SHA256 */
429
430
336
    #ifdef WOLFSSL_SHA384
431
336
        case WC_SHA384:
432
0
            hmac_block_size = WC_SHA384_BLOCK_SIZE;
433
0
            if (length <= WC_SHA384_BLOCK_SIZE) {
434
0
                if (key != NULL) {
435
0
                    XMEMCPY(ip, key, length);
436
0
                }
437
0
            }
438
0
            else {
439
0
                ret = wc_Sha384Update(&hmac->hash.sha384, key, length);
440
0
                if (ret != 0)
441
0
                    break;
442
0
                ret = wc_Sha384Final(&hmac->hash.sha384, ip);
443
0
                if (ret != 0)
444
0
                    break;
445
446
0
                length = WC_SHA384_DIGEST_SIZE;
447
0
            }
448
0
            break;
449
0
    #endif /* WOLFSSL_SHA384 */
450
0
    #ifdef WOLFSSL_SHA512
451
0
        case WC_SHA512:
452
0
            hmac_block_size = WC_SHA512_BLOCK_SIZE;
453
0
            if (length <= WC_SHA512_BLOCK_SIZE) {
454
0
                if (key != NULL) {
455
0
                    XMEMCPY(ip, key, length);
456
0
                }
457
0
            }
458
0
            else {
459
0
                ret = wc_Sha512Update(&hmac->hash.sha512, key, length);
460
0
                if (ret != 0)
461
0
                    break;
462
0
                ret = wc_Sha512Final(&hmac->hash.sha512, ip);
463
0
                if (ret != 0)
464
0
                    break;
465
466
0
                length = WC_SHA512_DIGEST_SIZE;
467
0
            }
468
0
            break;
469
0
    #endif /* WOLFSSL_SHA512 */
470
471
0
    #ifdef WOLFSSL_SHA3
472
0
    #ifndef WOLFSSL_NOSHA3_224
473
0
        case WC_SHA3_224:
474
0
            hmac_block_size = WC_SHA3_224_BLOCK_SIZE;
475
0
            if (length <= WC_SHA3_224_BLOCK_SIZE) {
476
0
                if (key != NULL) {
477
0
                    XMEMCPY(ip, key, length);
478
0
                }
479
0
            }
480
0
            else {
481
0
                ret = wc_Sha3_224_Update(&hmac->hash.sha3, key, length);
482
0
                if (ret != 0)
483
0
                    break;
484
0
                ret = wc_Sha3_224_Final(&hmac->hash.sha3, ip);
485
0
                if (ret != 0)
486
0
                    break;
487
488
0
                length = WC_SHA3_224_DIGEST_SIZE;
489
0
            }
490
0
            break;
491
0
    #endif
492
0
    #ifndef WOLFSSL_NOSHA3_256
493
0
        case WC_SHA3_256:
494
0
            hmac_block_size = WC_SHA3_256_BLOCK_SIZE;
495
0
            if (length <= WC_SHA3_256_BLOCK_SIZE) {
496
0
                if (key != NULL) {
497
0
                    XMEMCPY(ip, key, length);
498
0
                }
499
0
            }
500
0
            else {
501
0
                ret = wc_Sha3_256_Update(&hmac->hash.sha3, key, length);
502
0
                if (ret != 0)
503
0
                    break;
504
0
                ret = wc_Sha3_256_Final(&hmac->hash.sha3, ip);
505
0
                if (ret != 0)
506
0
                    break;
507
508
0
                length = WC_SHA3_256_DIGEST_SIZE;
509
0
            }
510
0
            break;
511
0
    #endif
512
0
    #ifndef WOLFSSL_NOSHA3_384
513
0
        case WC_SHA3_384:
514
0
            hmac_block_size = WC_SHA3_384_BLOCK_SIZE;
515
0
            if (length <= WC_SHA3_384_BLOCK_SIZE) {
516
0
                if (key != NULL) {
517
0
                    XMEMCPY(ip, key, length);
518
0
                }
519
0
            }
520
0
            else {
521
0
                ret = wc_Sha3_384_Update(&hmac->hash.sha3, key, length);
522
0
                if (ret != 0)
523
0
                    break;
524
0
                ret = wc_Sha3_384_Final(&hmac->hash.sha3, ip);
525
0
                if (ret != 0)
526
0
                    break;
527
528
0
                length = WC_SHA3_384_DIGEST_SIZE;
529
0
            }
530
0
            break;
531
0
    #endif
532
0
    #ifndef WOLFSSL_NOSHA3_512
533
0
        case WC_SHA3_512:
534
0
            hmac_block_size = WC_SHA3_512_BLOCK_SIZE;
535
0
            if (length <= WC_SHA3_512_BLOCK_SIZE) {
536
0
                if (key != NULL) {
537
0
                    XMEMCPY(ip, key, length);
538
0
                }
539
0
            }
540
0
            else {
541
0
                ret = wc_Sha3_512_Update(&hmac->hash.sha3, key, length);
542
0
                if (ret != 0)
543
0
                    break;
544
0
                ret = wc_Sha3_512_Final(&hmac->hash.sha3, ip);
545
0
                if (ret != 0)
546
0
                    break;
547
548
0
                length = WC_SHA3_512_DIGEST_SIZE;
549
0
            }
550
0
            break;
551
0
    #endif
552
0
    #endif /* WOLFSSL_SHA3 */
553
554
0
        default:
555
0
            return BAD_FUNC_ARG;
556
336
    }
557
558
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
559
    if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
560
    #if defined(HAVE_INTEL_QA) || defined(HAVE_CAVIUM)
561
        #ifdef HAVE_INTEL_QA
562
        if (IntelQaHmacGetType(hmac->macType, NULL) == 0)
563
        #endif
564
        {
565
            if (length > hmac_block_size)
566
                length = hmac_block_size;
567
            /* update key length */
568
            hmac->keyLen = (word16)length;
569
570
            return ret;
571
        }
572
        /* no need to pad below */
573
    #endif
574
    }
575
#endif
576
577
336
    if (ret == 0) {
578
336
        if (length < hmac_block_size)
579
336
            XMEMSET(ip + length, 0, hmac_block_size - length);
580
581
21.8k
        for(i = 0; i < hmac_block_size; i++) {
582
21.5k
            op[i] = ip[i] ^ OPAD;
583
21.5k
            ip[i] ^= IPAD;
584
21.5k
        }
585
336
    }
586
587
336
    return ret;
588
336
}
589
590
591
static int HmacKeyInnerHash(Hmac* hmac)
592
336
{
593
336
    int ret = 0;
594
595
336
    switch (hmac->macType) {
596
0
    #ifndef NO_MD5
597
0
        case WC_MD5:
598
0
            ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->ipad,
599
0
                                                             WC_MD5_BLOCK_SIZE);
600
0
            break;
601
0
    #endif /* !NO_MD5 */
602
603
0
    #ifndef NO_SHA
604
0
        case WC_SHA:
605
0
            ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->ipad,
606
0
                                                             WC_SHA_BLOCK_SIZE);
607
0
            break;
608
0
    #endif /* !NO_SHA */
609
610
0
    #ifdef WOLFSSL_SHA224
611
0
        case WC_SHA224:
612
0
            ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->ipad,
613
0
                                                          WC_SHA224_BLOCK_SIZE);
614
0
            break;
615
0
    #endif /* WOLFSSL_SHA224 */
616
0
    #ifndef NO_SHA256
617
336
        case WC_SHA256:
618
336
            ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->ipad,
619
336
                                                          WC_SHA256_BLOCK_SIZE);
620
336
            break;
621
0
    #endif /* !NO_SHA256 */
622
623
0
    #ifdef WOLFSSL_SHA384
624
0
        case WC_SHA384:
625
0
            ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->ipad,
626
0
                                                          WC_SHA384_BLOCK_SIZE);
627
0
            break;
628
0
    #endif /* WOLFSSL_SHA384 */
629
0
    #ifdef WOLFSSL_SHA512
630
0
        case WC_SHA512:
631
0
            ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->ipad,
632
0
                                                          WC_SHA512_BLOCK_SIZE);
633
0
            break;
634
0
    #endif /* WOLFSSL_SHA512 */
635
636
0
    #ifdef WOLFSSL_SHA3
637
0
    #ifndef WOLFSSL_NOSHA3_224
638
0
        case WC_SHA3_224:
639
0
            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
640
0
                                                        WC_SHA3_224_BLOCK_SIZE);
641
0
            break;
642
0
    #endif
643
0
    #ifndef WOLFSSL_NOSHA3_256
644
0
        case WC_SHA3_256:
645
0
            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
646
0
                                                        WC_SHA3_256_BLOCK_SIZE);
647
0
            break;
648
0
    #endif
649
0
    #ifndef WOLFSSL_NOSHA3_384
650
0
        case WC_SHA3_384:
651
0
            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
652
0
                                                        WC_SHA3_384_BLOCK_SIZE);
653
0
            break;
654
0
    #endif
655
0
    #ifndef WOLFSSL_NOSHA3_512
656
0
        case WC_SHA3_512:
657
0
            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
658
0
                                                        WC_SHA3_512_BLOCK_SIZE);
659
0
            break;
660
0
    #endif
661
0
    #endif /* WOLFSSL_SHA3 */
662
663
0
        default:
664
0
            break;
665
336
    }
666
667
336
    if (ret == 0)
668
336
        hmac->innerHashKeyed = WC_HMAC_INNER_HASH_KEYED_SW;
669
670
336
    return ret;
671
336
}
672
673
674
int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length)
675
756
{
676
756
    int ret = 0;
677
678
756
    if (hmac == NULL || (msg == NULL && length > 0)) {
679
0
        return BAD_FUNC_ARG;
680
0
    }
681
682
756
#ifdef WOLF_CRYPTO_CB
683
756
    if (hmac->devId != INVALID_DEVID) {
684
0
        ret = wc_CryptoCb_Hmac(hmac, hmac->macType, msg, length, NULL);
685
0
        if (ret != CRYPTOCB_UNAVAILABLE)
686
0
            return ret;
687
        /* fall-through when unavailable */
688
0
        ret = 0; /* reset error code */
689
0
    }
690
756
#endif
691
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
692
    if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
693
    #if defined(HAVE_CAVIUM)
694
        return NitroxHmacUpdate(hmac, msg, length);
695
    #elif defined(HAVE_INTEL_QA)
696
        if (IntelQaHmacGetType(hmac->macType, NULL) == 0) {
697
            return IntelQaHmac(&hmac->asyncDev, hmac->macType,
698
                (byte*)hmac->ipad, hmac->keyLen, NULL, msg, length);
699
        }
700
    #endif
701
    }
702
#endif /* WOLFSSL_ASYNC_CRYPT */
703
704
756
    if (!hmac->innerHashKeyed) {
705
336
        ret = HmacKeyInnerHash(hmac);
706
336
        if (ret != 0)
707
0
            return ret;
708
336
    }
709
710
756
    switch (hmac->macType) {
711
0
    #ifndef NO_MD5
712
0
        case WC_MD5:
713
0
            ret = wc_Md5Update(&hmac->hash.md5, msg, length);
714
0
            break;
715
0
    #endif /* !NO_MD5 */
716
717
0
    #ifndef NO_SHA
718
0
        case WC_SHA:
719
0
            ret = wc_ShaUpdate(&hmac->hash.sha, msg, length);
720
0
            break;
721
0
    #endif /* !NO_SHA */
722
723
0
    #ifdef WOLFSSL_SHA224
724
0
        case WC_SHA224:
725
0
            ret = wc_Sha224Update(&hmac->hash.sha224, msg, length);
726
0
            break;
727
0
    #endif /* WOLFSSL_SHA224 */
728
729
0
    #ifndef NO_SHA256
730
756
        case WC_SHA256:
731
756
            ret = wc_Sha256Update(&hmac->hash.sha256, msg, length);
732
756
            break;
733
0
    #endif /* !NO_SHA256 */
734
735
0
    #ifdef WOLFSSL_SHA384
736
0
        case WC_SHA384:
737
0
            ret = wc_Sha384Update(&hmac->hash.sha384, msg, length);
738
0
            break;
739
0
    #endif /* WOLFSSL_SHA384 */
740
0
    #ifdef WOLFSSL_SHA512
741
0
        case WC_SHA512:
742
0
            ret = wc_Sha512Update(&hmac->hash.sha512, msg, length);
743
0
            break;
744
0
    #endif /* WOLFSSL_SHA512 */
745
746
0
    #ifdef WOLFSSL_SHA3
747
0
    #ifndef WOLFSSL_NOSHA3_224
748
0
        case WC_SHA3_224:
749
0
            ret = wc_Sha3_224_Update(&hmac->hash.sha3, msg, length);
750
0
            break;
751
0
    #endif
752
0
    #ifndef WOLFSSL_NOSHA3_256
753
0
        case WC_SHA3_256:
754
0
            ret = wc_Sha3_256_Update(&hmac->hash.sha3, msg, length);
755
0
            break;
756
0
    #endif
757
0
    #ifndef WOLFSSL_NOSHA3_384
758
0
        case WC_SHA3_384:
759
0
            ret = wc_Sha3_384_Update(&hmac->hash.sha3, msg, length);
760
0
            break;
761
0
    #endif
762
0
    #ifndef WOLFSSL_NOSHA3_512
763
0
        case WC_SHA3_512:
764
0
            ret = wc_Sha3_512_Update(&hmac->hash.sha3, msg, length);
765
0
            break;
766
0
    #endif
767
0
    #endif /* WOLFSSL_SHA3 */
768
769
0
        default:
770
0
            break;
771
756
    }
772
773
756
    return ret;
774
756
}
775
776
777
int wc_HmacFinal(Hmac* hmac, byte* hash)
778
336
{
779
336
    int ret;
780
781
336
    if (hmac == NULL || hash == NULL) {
782
0
        return BAD_FUNC_ARG;
783
0
    }
784
785
336
#ifdef WOLF_CRYPTO_CB
786
336
    if (hmac->devId != INVALID_DEVID) {
787
0
        ret = wc_CryptoCb_Hmac(hmac, hmac->macType, NULL, 0, hash);
788
0
        if (ret != CRYPTOCB_UNAVAILABLE)
789
0
            return ret;
790
        /* fall-through when unavailable */
791
0
    }
792
336
#endif
793
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
794
    if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
795
        int hashLen = wc_HmacSizeByType(hmac->macType);
796
        if (hashLen <= 0)
797
            return hashLen;
798
799
    #if defined(HAVE_CAVIUM)
800
        return NitroxHmacFinal(hmac, hash, hashLen);
801
    #elif defined(HAVE_INTEL_QA)
802
        if (IntelQaHmacGetType(hmac->macType, NULL) == 0) {
803
            return IntelQaHmac(&hmac->asyncDev, hmac->macType,
804
                (byte*)hmac->ipad, hmac->keyLen, hash, NULL, hashLen);
805
        }
806
    #endif
807
    }
808
#endif /* WOLFSSL_ASYNC_CRYPT */
809
810
336
    if (!hmac->innerHashKeyed) {
811
0
        ret = HmacKeyInnerHash(hmac);
812
0
        if (ret != 0)
813
0
            return ret;
814
0
    }
815
816
336
    switch (hmac->macType) {
817
0
    #ifndef NO_MD5
818
0
        case WC_MD5:
819
0
            ret = wc_Md5Final(&hmac->hash.md5, (byte*)hmac->innerHash);
820
0
            if (ret != 0)
821
0
                break;
822
0
            ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->opad,
823
0
                                                             WC_MD5_BLOCK_SIZE);
824
0
            if (ret != 0)
825
0
                break;
826
0
            ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->innerHash,
827
0
                                                            WC_MD5_DIGEST_SIZE);
828
0
            if (ret != 0)
829
0
                break;
830
0
            ret = wc_Md5Final(&hmac->hash.md5, hash);
831
0
            break;
832
0
    #endif /* !NO_MD5 */
833
834
0
    #ifndef NO_SHA
835
0
        case WC_SHA:
836
0
            ret = wc_ShaFinal(&hmac->hash.sha, (byte*)hmac->innerHash);
837
0
            if (ret != 0)
838
0
                break;
839
0
            ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->opad,
840
0
                                                             WC_SHA_BLOCK_SIZE);
841
0
            if (ret != 0)
842
0
                break;
843
0
            ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->innerHash,
844
0
                                                            WC_SHA_DIGEST_SIZE);
845
0
            if (ret != 0)
846
0
                break;
847
0
            ret = wc_ShaFinal(&hmac->hash.sha, hash);
848
0
            break;
849
0
    #endif /* !NO_SHA */
850
851
0
    #ifdef WOLFSSL_SHA224
852
0
        case WC_SHA224:
853
0
            ret = wc_Sha224Final(&hmac->hash.sha224, (byte*)hmac->innerHash);
854
0
            if (ret != 0)
855
0
                break;
856
0
            ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->opad,
857
0
                                                          WC_SHA224_BLOCK_SIZE);
858
0
            if (ret != 0)
859
0
                break;
860
0
            ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->innerHash,
861
0
                                                         WC_SHA224_DIGEST_SIZE);
862
0
            if (ret != 0)
863
0
                break;
864
0
            ret = wc_Sha224Final(&hmac->hash.sha224, hash);
865
0
            if (ret != 0)
866
0
                break;
867
0
            break;
868
0
    #endif /* WOLFSSL_SHA224 */
869
0
    #ifndef NO_SHA256
870
336
        case WC_SHA256:
871
336
            ret = wc_Sha256Final(&hmac->hash.sha256, (byte*)hmac->innerHash);
872
336
            if (ret != 0)
873
0
                break;
874
336
            ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->opad,
875
336
                                                          WC_SHA256_BLOCK_SIZE);
876
336
            if (ret != 0)
877
0
                break;
878
336
            ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->innerHash,
879
336
                                                         WC_SHA256_DIGEST_SIZE);
880
336
            if (ret != 0)
881
0
                break;
882
336
            ret = wc_Sha256Final(&hmac->hash.sha256, hash);
883
336
            break;
884
0
    #endif /* !NO_SHA256 */
885
886
0
    #ifdef WOLFSSL_SHA384
887
0
        case WC_SHA384:
888
0
            ret = wc_Sha384Final(&hmac->hash.sha384, (byte*)hmac->innerHash);
889
0
            if (ret != 0)
890
0
                break;
891
0
            ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->opad,
892
0
                                                          WC_SHA384_BLOCK_SIZE);
893
0
            if (ret != 0)
894
0
                break;
895
0
            ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->innerHash,
896
0
                                                         WC_SHA384_DIGEST_SIZE);
897
0
            if (ret != 0)
898
0
                break;
899
0
            ret = wc_Sha384Final(&hmac->hash.sha384, hash);
900
0
            break;
901
0
    #endif /* WOLFSSL_SHA384 */
902
0
    #ifdef WOLFSSL_SHA512
903
0
        case WC_SHA512:
904
0
            ret = wc_Sha512Final(&hmac->hash.sha512, (byte*)hmac->innerHash);
905
0
            if (ret != 0)
906
0
                break;
907
0
            ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->opad,
908
0
                                                          WC_SHA512_BLOCK_SIZE);
909
0
            if (ret != 0)
910
0
                break;
911
0
            ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->innerHash,
912
0
                                                         WC_SHA512_DIGEST_SIZE);
913
0
            if (ret != 0)
914
0
                break;
915
0
            ret = wc_Sha512Final(&hmac->hash.sha512, hash);
916
0
            break;
917
0
    #endif /* WOLFSSL_SHA512 */
918
919
0
    #ifdef WOLFSSL_SHA3
920
0
    #ifndef WOLFSSL_NOSHA3_224
921
0
        case WC_SHA3_224:
922
0
            ret = wc_Sha3_224_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
923
0
            if (ret != 0)
924
0
                break;
925
0
            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->opad,
926
0
                                                        WC_SHA3_224_BLOCK_SIZE);
927
0
            if (ret != 0)
928
0
                break;
929
0
            ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
930
0
                                                       WC_SHA3_224_DIGEST_SIZE);
931
0
            if (ret != 0)
932
0
                break;
933
0
            ret = wc_Sha3_224_Final(&hmac->hash.sha3, hash);
934
0
            break;
935
0
    #endif
936
0
    #ifndef WOLFSSL_NOSHA3_256
937
0
        case WC_SHA3_256:
938
0
            ret = wc_Sha3_256_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
939
0
            if (ret != 0)
940
0
                break;
941
0
            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->opad,
942
0
                                                        WC_SHA3_256_BLOCK_SIZE);
943
0
            if (ret != 0)
944
0
                break;
945
0
            ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
946
0
                                                       WC_SHA3_256_DIGEST_SIZE);
947
0
            if (ret != 0)
948
0
                break;
949
0
            ret = wc_Sha3_256_Final(&hmac->hash.sha3, hash);
950
0
            break;
951
0
    #endif
952
0
    #ifndef WOLFSSL_NOSHA3_384
953
0
        case WC_SHA3_384:
954
0
            ret = wc_Sha3_384_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
955
0
            if (ret != 0)
956
0
                break;
957
0
            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->opad,
958
0
                                                        WC_SHA3_384_BLOCK_SIZE);
959
0
            if (ret != 0)
960
0
                break;
961
0
            ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
962
0
                                                       WC_SHA3_384_DIGEST_SIZE);
963
0
            if (ret != 0)
964
0
                break;
965
0
            ret = wc_Sha3_384_Final(&hmac->hash.sha3, hash);
966
0
            break;
967
0
    #endif
968
0
    #ifndef WOLFSSL_NOSHA3_512
969
0
        case WC_SHA3_512:
970
0
            ret = wc_Sha3_512_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
971
0
            if (ret != 0)
972
0
                break;
973
0
            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->opad,
974
0
                                                        WC_SHA3_512_BLOCK_SIZE);
975
0
            if (ret != 0)
976
0
                break;
977
0
            ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
978
0
                                                       WC_SHA3_512_DIGEST_SIZE);
979
0
            if (ret != 0)
980
0
                break;
981
0
            ret = wc_Sha3_512_Final(&hmac->hash.sha3, hash);
982
0
            break;
983
0
    #endif
984
0
    #endif /* WOLFSSL_SHA3 */
985
986
0
        default:
987
0
            ret = BAD_FUNC_ARG;
988
0
            break;
989
336
    }
990
991
336
    if (ret == 0) {
992
336
        hmac->innerHashKeyed = 0;
993
336
    }
994
995
336
    return ret;
996
336
}
997
998
#ifdef WOLFSSL_KCAPI_HMAC
999
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hmac.c */
1000
1001
    /* unmap the _Software calls used by kcapi_hmac.c */
1002
    #undef wc_HmacSetKey
1003
    #undef wc_HmacUpdate
1004
    #undef wc_HmacFinal
1005
1006
#else
1007
/* Initialize Hmac for use with async device */
1008
int wc_HmacInit(Hmac* hmac, void* heap, int devId)
1009
252
{
1010
252
    int ret = 0;
1011
1012
252
    if (hmac == NULL)
1013
0
        return BAD_FUNC_ARG;
1014
1015
252
    XMEMSET(hmac, 0, sizeof(Hmac));
1016
252
    hmac->macType = WC_HASH_TYPE_NONE;
1017
252
    hmac->heap = heap;
1018
252
#ifdef WOLF_CRYPTO_CB
1019
252
    hmac->devId = devId;
1020
252
    hmac->devCtx = NULL;
1021
252
#endif
1022
#if defined(WOLFSSL_DEVCRYPTO_HMAC)
1023
    hmac->ctx.cfd = -1;
1024
#endif
1025
1026
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
1027
    ret = wolfAsync_DevCtxInit(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC,
1028
                                                         hmac->heap, devId);
1029
#else
1030
252
    (void)devId;
1031
252
#endif /* WOLFSSL_ASYNC_CRYPT */
1032
1033
252
    return ret;
1034
252
}
1035
1036
#ifdef WOLF_PRIVATE_KEY_ID
1037
int  wc_HmacInit_Id(Hmac* hmac, unsigned char* id, int len, void* heap,
1038
                    int devId)
1039
0
{
1040
0
    int ret = 0;
1041
1042
0
    if (hmac == NULL)
1043
0
        ret = BAD_FUNC_ARG;
1044
0
    if (ret == 0 && (len < 0 || len > HMAC_MAX_ID_LEN))
1045
0
        ret = BUFFER_E;
1046
1047
0
    if (ret == 0)
1048
0
        ret = wc_HmacInit(hmac, heap, devId);
1049
0
    if (ret == 0) {
1050
0
        XMEMCPY(hmac->id, id, len);
1051
0
        hmac->idLen = len;
1052
0
    }
1053
1054
0
    return ret;
1055
0
}
1056
1057
int wc_HmacInit_Label(Hmac* hmac, const char* label, void* heap, int devId)
1058
0
{
1059
0
    int ret = 0;
1060
0
    int labelLen = 0;
1061
1062
0
    if (hmac == NULL || label == NULL)
1063
0
        ret = BAD_FUNC_ARG;
1064
0
    if (ret == 0) {
1065
0
        labelLen = (int)XSTRLEN(label);
1066
0
        if (labelLen == 0 || labelLen > HMAC_MAX_LABEL_LEN)
1067
0
            ret = BUFFER_E;
1068
0
    }
1069
1070
0
    if (ret == 0)
1071
0
        ret  = wc_HmacInit(hmac, heap, devId);
1072
0
    if (ret == 0) {
1073
0
        XMEMCPY(hmac->label, label, labelLen);
1074
0
        hmac->labelLen = labelLen;
1075
0
    }
1076
1077
0
    return ret;
1078
0
}
1079
#endif /* WOLF_PRIVATE_KEY_ID */
1080
1081
/* Free Hmac from use with async device */
1082
void wc_HmacFree(Hmac* hmac)
1083
336
{
1084
336
    if (hmac == NULL)
1085
0
        return;
1086
1087
336
#ifdef WOLF_CRYPTO_CB
1088
    /* handle cleanup case where final is not called */
1089
336
    if (hmac->devId != INVALID_DEVID && hmac->devCtx != NULL) {
1090
0
        int  ret;
1091
0
        byte finalHash[WC_HMAC_BLOCK_SIZE];
1092
0
        ret = wc_CryptoCb_Hmac(hmac, hmac->macType, NULL, 0, finalHash);
1093
0
        (void)ret; /* must ignore return code here */
1094
0
        (void)finalHash;
1095
0
    }
1096
336
#endif
1097
1098
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
1099
    wolfAsync_DevCtxFree(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC);
1100
#endif /* WOLFSSL_ASYNC_CRYPT */
1101
1102
336
    switch (hmac->macType) {
1103
0
    #ifndef NO_MD5
1104
0
        case WC_MD5:
1105
0
            wc_Md5Free(&hmac->hash.md5);
1106
0
            break;
1107
0
    #endif /* !NO_MD5 */
1108
1109
0
    #ifndef NO_SHA
1110
0
        case WC_SHA:
1111
0
            wc_ShaFree(&hmac->hash.sha);
1112
0
            break;
1113
0
    #endif /* !NO_SHA */
1114
1115
0
    #ifdef WOLFSSL_SHA224
1116
0
        case WC_SHA224:
1117
0
            wc_Sha224Free(&hmac->hash.sha224);
1118
0
            break;
1119
0
    #endif /* WOLFSSL_SHA224 */
1120
0
    #ifndef NO_SHA256
1121
336
        case WC_SHA256:
1122
336
            wc_Sha256Free(&hmac->hash.sha256);
1123
336
            break;
1124
0
    #endif /* !NO_SHA256 */
1125
1126
0
    #ifdef WOLFSSL_SHA384
1127
0
        case WC_SHA384:
1128
0
            wc_Sha384Free(&hmac->hash.sha384);
1129
0
            break;
1130
0
    #endif /* WOLFSSL_SHA384 */
1131
0
    #ifdef WOLFSSL_SHA512
1132
0
        case WC_SHA512:
1133
0
            wc_Sha512Free(&hmac->hash.sha512);
1134
0
            break;
1135
0
    #endif /* WOLFSSL_SHA512 */
1136
1137
0
    #ifdef WOLFSSL_SHA3
1138
0
    #ifndef WOLFSSL_NOSHA3_224
1139
0
        case WC_SHA3_224:
1140
0
            wc_Sha3_224_Free(&hmac->hash.sha3);
1141
0
            break;
1142
0
    #endif
1143
0
    #ifndef WOLFSSL_NOSHA3_256
1144
0
        case WC_SHA3_256:
1145
0
            wc_Sha3_256_Free(&hmac->hash.sha3);
1146
0
            break;
1147
0
    #endif
1148
0
    #ifndef WOLFSSL_NOSHA3_384
1149
0
        case WC_SHA3_384:
1150
0
            wc_Sha3_384_Free(&hmac->hash.sha3);
1151
0
            break;
1152
0
    #endif
1153
0
    #ifndef WOLFSSL_NOSHA3_512
1154
0
        case WC_SHA3_512:
1155
0
            wc_Sha3_512_Free(&hmac->hash.sha3);
1156
0
            break;
1157
0
    #endif
1158
0
    #endif /* WOLFSSL_SHA3 */
1159
1160
0
        default:
1161
0
            break;
1162
336
    }
1163
336
}
1164
#endif /* WOLFSSL_KCAPI_HMAC */
1165
1166
int wolfSSL_GetHmacMaxSize(void)
1167
0
{
1168
0
    return WC_MAX_DIGEST_SIZE;
1169
0
}
1170
1171
#ifdef HAVE_HKDF
1172
    /* HMAC-KDF-Extract.
1173
     * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
1174
     *
1175
     * type     The hash algorithm type.
1176
     * salt     The optional salt value.
1177
     * saltSz   The size of the salt.
1178
     * inKey    The input keying material.
1179
     * inKeySz  The size of the input keying material.
1180
     * out      The pseudorandom key with the length that of the hash.
1181
     * returns 0 on success, otherwise failure.
1182
     */
1183
    int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz,
1184
                        const byte* inKey, word32 inKeySz, byte* out)
1185
84
    {
1186
84
        byte   tmp[WC_MAX_DIGEST_SIZE]; /* localSalt helper */
1187
84
        Hmac   myHmac;
1188
84
        int    ret;
1189
84
        const  byte* localSalt;  /* either points to user input or tmp */
1190
84
        int    hashSz;
1191
1192
84
        ret = wc_HmacSizeByType(type);
1193
84
        if (ret < 0)
1194
0
            return ret;
1195
1196
84
        hashSz = ret;
1197
84
        localSalt = salt;
1198
84
        if (localSalt == NULL) {
1199
84
            XMEMSET(tmp, 0, hashSz);
1200
84
            localSalt = tmp;
1201
84
            saltSz    = hashSz;
1202
84
        }
1203
1204
84
        ret = wc_HmacInit(&myHmac, NULL, INVALID_DEVID);
1205
84
        if (ret == 0) {
1206
84
            ret = wc_HmacSetKey(&myHmac, type, localSalt, saltSz);
1207
84
            if (ret == 0)
1208
84
                ret = wc_HmacUpdate(&myHmac, inKey, inKeySz);
1209
84
            if (ret == 0)
1210
84
                ret = wc_HmacFinal(&myHmac,  out);
1211
84
            wc_HmacFree(&myHmac);
1212
84
        }
1213
1214
84
        return ret;
1215
84
    }
1216
1217
    /* HMAC-KDF-Expand.
1218
     * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
1219
     *
1220
     * type     The hash algorithm type.
1221
     * inKey    The input key.
1222
     * inKeySz  The size of the input key.
1223
     * info     The application specific information.
1224
     * infoSz   The size of the application specific information.
1225
     * out      The output keying material.
1226
     * returns 0 on success, otherwise failure.
1227
     */
1228
    int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz,
1229
                       const byte* info, word32 infoSz, byte* out, word32 outSz)
1230
84
    {
1231
84
        byte   tmp[WC_MAX_DIGEST_SIZE];
1232
84
        Hmac   myHmac;
1233
84
        int    ret = 0;
1234
84
        word32 outIdx = 0;
1235
84
        word32 hashSz = wc_HmacSizeByType(type);
1236
84
        byte   n = 0x1;
1237
1238
        /* RFC 5869 states that the length of output keying material in
1239
           octets must be L <= 255*HashLen or N = ceil(L/HashLen) */
1240
1241
84
        if (out == NULL || ((outSz/hashSz) + ((outSz % hashSz) != 0)) > 255)
1242
0
            return BAD_FUNC_ARG;
1243
1244
84
        ret = wc_HmacInit(&myHmac, NULL, INVALID_DEVID);
1245
84
        if (ret != 0)
1246
0
            return ret;
1247
1248
1249
252
        while (outIdx < outSz) {
1250
168
            int    tmpSz = (n == 1) ? 0 : hashSz;
1251
168
            word32 left = outSz - outIdx;
1252
1253
168
            ret = wc_HmacSetKey(&myHmac, type, inKey, inKeySz);
1254
168
            if (ret != 0)
1255
0
                break;
1256
168
            ret = wc_HmacUpdate(&myHmac, tmp, tmpSz);
1257
168
            if (ret != 0)
1258
0
                break;
1259
168
            ret = wc_HmacUpdate(&myHmac, info, infoSz);
1260
168
            if (ret != 0)
1261
0
                break;
1262
168
            ret = wc_HmacUpdate(&myHmac, &n, 1);
1263
168
            if (ret != 0)
1264
0
                break;
1265
168
            ret = wc_HmacFinal(&myHmac, tmp);
1266
168
            if (ret != 0)
1267
0
                break;
1268
1269
168
            left = min(left, hashSz);
1270
168
            XMEMCPY(out+outIdx, tmp, left);
1271
1272
168
            outIdx += hashSz;
1273
168
            n++;
1274
168
        }
1275
1276
84
        wc_HmacFree(&myHmac);
1277
1278
84
        return ret;
1279
84
    }
1280
1281
    /* HMAC-KDF.
1282
     * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
1283
     *
1284
     * type     The hash algorithm type.
1285
     * inKey    The input keying material.
1286
     * inKeySz  The size of the input keying material.
1287
     * salt     The optional salt value.
1288
     * saltSz   The size of the salt.
1289
     * info     The application specific information.
1290
     * infoSz   The size of the application specific information.
1291
     * out      The output keying material.
1292
     * returns 0 on success, otherwise failure.
1293
     */
1294
    int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
1295
                       const byte* salt,  word32 saltSz,
1296
                       const byte* info,  word32 infoSz,
1297
                       byte* out,         word32 outSz)
1298
84
    {
1299
84
        byte   prk[WC_MAX_DIGEST_SIZE];
1300
84
        int    hashSz = wc_HmacSizeByType(type);
1301
84
        int    ret;
1302
1303
84
        if (hashSz < 0)
1304
0
            return BAD_FUNC_ARG;
1305
1306
84
        ret = wc_HKDF_Extract(type, salt, saltSz, inKey, inKeySz, prk);
1307
84
        if (ret != 0)
1308
0
            return ret;
1309
1310
84
        return wc_HKDF_Expand(type, prk, hashSz, info, infoSz, out, outSz);
1311
84
    }
1312
1313
#endif /* HAVE_HKDF */
1314
1315
#endif /* HAVE_FIPS */
1316
#endif /* NO_HMAC */