source: asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/hmac.c@ 352

Last change on this file since 352 was 352, checked in by coas-nagasima, 6 years ago

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 26.9 KB
Line 
1/* hmac.h
2 *
3 * Copyright (C) 2006-2017 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/settings.h>
28#include <wolfssl/wolfcrypt/error-crypt.h>
29
30#ifndef NO_HMAC
31
32#include <wolfssl/wolfcrypt/hmac.h>
33
34#ifdef NO_INLINE
35 #include <wolfssl/wolfcrypt/misc.h>
36#else
37 #define WOLFSSL_MISC_INCLUDED
38 #include <wolfcrypt/src/misc.c>
39#endif
40
41
42/* fips wrapper calls, user can call direct */
43#ifdef HAVE_FIPS
44 /* does init */
45 int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 keySz)
46 {
47 if (hmac == NULL || (key == NULL && keySz != 0) ||
48 !(type == WC_MD5 || type == WC_SHA || type == WC_SHA256 ||
49 type == WC_SHA384 || type == WC_SHA512 || type == BLAKE2B_ID)) {
50 return BAD_FUNC_ARG;
51 }
52
53 return HmacSetKey_fips(hmac, type, key, keySz);
54 }
55 int wc_HmacUpdate(Hmac* hmac, const byte* in, word32 sz)
56 {
57 if (hmac == NULL || (in == NULL && sz > 0)) {
58 return BAD_FUNC_ARG;
59 }
60
61 return HmacUpdate_fips(hmac, in, sz);
62 }
63 int wc_HmacFinal(Hmac* hmac, byte* out)
64 {
65 if (hmac == NULL) {
66 return BAD_FUNC_ARG;
67 }
68
69 return HmacFinal_fips(hmac, out);
70 }
71 int wolfSSL_GetHmacMaxSize(void)
72 {
73 return CyaSSL_GetHmacMaxSize();
74 }
75
76 int wc_HmacInit(Hmac* hmac, void* heap, int devId)
77 {
78 (void)hmac;
79 (void)heap;
80 (void)devId;
81 /* FIPS doesn't support:
82 return HmacInit(hmac, heap, devId); */
83 return 0;
84 }
85 void wc_HmacFree(Hmac* hmac)
86 {
87 (void)hmac;
88 /* FIPS doesn't support:
89 HmacFree(hmac); */
90 }
91
92 #ifdef HAVE_HKDF
93 int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
94 const byte* salt, word32 saltSz,
95 const byte* info, word32 infoSz,
96 byte* out, word32 outSz)
97 {
98 return HKDF(type, inKey, inKeySz, salt, saltSz,
99 info, infoSz, out, outSz);
100 }
101 #endif /* HAVE_HKDF */
102
103#else /* else build without fips */
104
105
106#include <wolfssl/wolfcrypt/error-crypt.h>
107
108
109int wc_HmacSizeByType(int type)
110{
111 int ret;
112
113 if (!(type == WC_MD5 || type == WC_SHA || type == WC_SHA224 ||
114 type == WC_SHA256 || type == WC_SHA384 || type == WC_SHA512 ||
115 type == BLAKE2B_ID)) {
116 return BAD_FUNC_ARG;
117 }
118
119 switch (type) {
120 #ifndef NO_MD5
121 case WC_MD5:
122 ret = WC_MD5_DIGEST_SIZE;
123 break;
124 #endif /* !NO_MD5 */
125
126 #ifndef NO_SHA
127 case WC_SHA:
128 ret = WC_SHA_DIGEST_SIZE;
129 break;
130 #endif /* !NO_SHA */
131
132 #ifdef WOLFSSL_SHA224
133 case WC_SHA224:
134 ret = WC_SHA224_DIGEST_SIZE;
135 break;
136 #endif /* WOLFSSL_SHA224 */
137
138 #ifndef NO_SHA256
139 case WC_SHA256:
140 ret = WC_SHA256_DIGEST_SIZE;
141 break;
142 #endif /* !NO_SHA256 */
143
144 #ifdef WOLFSSL_SHA512
145 #ifdef WOLFSSL_SHA384
146 case WC_SHA384:
147 ret = WC_SHA384_DIGEST_SIZE;
148 break;
149 #endif /* WOLFSSL_SHA384 */
150 case WC_SHA512:
151 ret = WC_SHA512_DIGEST_SIZE;
152 break;
153 #endif /* WOLFSSL_SHA512 */
154
155 #ifdef HAVE_BLAKE2
156 case BLAKE2B_ID:
157 ret = BLAKE2B_OUTBYTES;
158 break;
159 #endif /* HAVE_BLAKE2 */
160
161 default:
162 ret = BAD_FUNC_ARG;
163 break;
164 }
165
166 return ret;
167}
168
169static int _InitHmac(Hmac* hmac, int type, void* heap)
170{
171 int ret = 0;
172
173 switch (type) {
174 #ifndef NO_MD5
175 case WC_MD5:
176 ret = wc_InitMd5(&hmac->hash.md5);
177 break;
178 #endif /* !NO_MD5 */
179
180 #ifndef NO_SHA
181 case WC_SHA:
182 ret = wc_InitSha(&hmac->hash.sha);
183 break;
184 #endif /* !NO_SHA */
185
186 #ifdef WOLFSSL_SHA224
187 case WC_SHA224:
188 ret = wc_InitSha224(&hmac->hash.sha224);
189 break;
190 #endif /* WOLFSSL_SHA224 */
191
192 #ifndef NO_SHA256
193 case WC_SHA256:
194 ret = wc_InitSha256(&hmac->hash.sha256);
195 break;
196 #endif /* !NO_SHA256 */
197
198 #ifdef WOLFSSL_SHA512
199 #ifdef WOLFSSL_SHA384
200 case WC_SHA384:
201 ret = wc_InitSha384(&hmac->hash.sha384);
202 break;
203 #endif /* WOLFSSL_SHA384 */
204 case WC_SHA512:
205 ret = wc_InitSha512(&hmac->hash.sha512);
206 break;
207 #endif /* WOLFSSL_SHA512 */
208
209 #ifdef HAVE_BLAKE2
210 case BLAKE2B_ID:
211 ret = wc_InitBlake2b(&hmac->hash.blake2b, BLAKE2B_256);
212 break;
213 #endif /* HAVE_BLAKE2 */
214
215 default:
216 ret = BAD_FUNC_ARG;
217 break;
218 }
219
220 /* default to NULL heap hint or test value */
221#ifdef WOLFSSL_HEAP_TEST
222 hmac->heap = (void)WOLFSSL_HEAP_TEST;
223#else
224 hmac->heap = heap;
225#endif /* WOLFSSL_HEAP_TEST */
226
227 return ret;
228}
229
230
231int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
232{
233 byte* ip;
234 byte* op;
235 word32 i, hmac_block_size = 0;
236 int ret = 0;
237 void* heap = NULL;
238
239 if (hmac == NULL || (key == NULL && length != 0) ||
240 !(type == WC_MD5 || type == WC_SHA || type == WC_SHA224 ||
241 type == WC_SHA256 || type == WC_SHA384 || type == WC_SHA512 ||
242 type == BLAKE2B_ID)) {
243 return BAD_FUNC_ARG;
244 }
245
246 hmac->innerHashKeyed = 0;
247 hmac->macType = (byte)type;
248
249#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
250 if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
251 #if defined(HAVE_CAVIUM)
252 if (length > HMAC_BLOCK_SIZE) {
253 return WC_KEY_SIZE_E;
254 }
255
256 if (key != NULL) {
257 XMEMCPY(hmac->ipad, key, length);
258 }
259 hmac->keyLen = (word16)length;
260
261 return 0; /* nothing to do here */
262 #endif /* HAVE_CAVIUM */
263 }
264#endif /* WOLFSSL_ASYNC_CRYPT */
265
266 ret = _InitHmac(hmac, type, heap);
267 if (ret != 0)
268 return ret;
269
270#ifdef HAVE_FIPS
271 if (length < HMAC_FIPS_MIN_KEY)
272 return HMAC_MIN_KEYLEN_E;
273#endif
274
275 ip = (byte*)hmac->ipad;
276 op = (byte*)hmac->opad;
277
278 switch (hmac->macType) {
279 #ifndef NO_MD5
280 case WC_MD5:
281 hmac_block_size = WC_MD5_BLOCK_SIZE;
282 if (length <= WC_MD5_BLOCK_SIZE) {
283 if (key != NULL) {
284 XMEMCPY(ip, key, length);
285 }
286 }
287 else {
288 ret = wc_Md5Update(&hmac->hash.md5, key, length);
289 if (ret != 0)
290 break;
291 ret = wc_Md5Final(&hmac->hash.md5, ip);
292 if (ret != 0)
293 break;
294 length = WC_MD5_DIGEST_SIZE;
295 }
296 break;
297 #endif /* !NO_MD5 */
298
299 #ifndef NO_SHA
300 case WC_SHA:
301 hmac_block_size = WC_SHA_BLOCK_SIZE;
302 if (length <= WC_SHA_BLOCK_SIZE) {
303 if (key != NULL) {
304 XMEMCPY(ip, key, length);
305 }
306 }
307 else {
308 ret = wc_ShaUpdate(&hmac->hash.sha, key, length);
309 if (ret != 0)
310 break;
311 ret = wc_ShaFinal(&hmac->hash.sha, ip);
312 if (ret != 0)
313 break;
314
315 length = WC_SHA_DIGEST_SIZE;
316 }
317 break;
318 #endif /* !NO_SHA */
319
320 #ifdef WOLFSSL_SHA224
321 case WC_SHA224:
322 {
323 hmac_block_size = WC_SHA224_BLOCK_SIZE;
324 if (length <= WC_SHA224_BLOCK_SIZE) {
325 if (key != NULL) {
326 XMEMCPY(ip, key, length);
327 }
328 }
329 else {
330 ret = wc_Sha224Update(&hmac->hash.sha224, key, length);
331 if (ret != 0)
332 break;
333 ret = wc_Sha224Final(&hmac->hash.sha224, ip);
334 if (ret != 0)
335 break;
336
337 length = WC_SHA224_DIGEST_SIZE;
338 }
339 }
340 break;
341 #endif /* WOLFSSL_SHA224 */
342
343 #ifndef NO_SHA256
344 case WC_SHA256:
345 hmac_block_size = WC_SHA256_BLOCK_SIZE;
346 if (length <= WC_SHA256_BLOCK_SIZE) {
347 if (key != NULL) {
348 XMEMCPY(ip, key, length);
349 }
350 }
351 else {
352 ret = wc_Sha256Update(&hmac->hash.sha256, key, length);
353 if (ret != 0)
354 break;
355 ret = wc_Sha256Final(&hmac->hash.sha256, ip);
356 if (ret != 0)
357 break;
358
359 length = WC_SHA256_DIGEST_SIZE;
360 }
361 break;
362 #endif /* !NO_SHA256 */
363
364 #ifdef WOLFSSL_SHA512
365 #ifdef WOLFSSL_SHA384
366 case WC_SHA384:
367 hmac_block_size = WC_SHA384_BLOCK_SIZE;
368 if (length <= WC_SHA384_BLOCK_SIZE) {
369 if (key != NULL) {
370 XMEMCPY(ip, key, length);
371 }
372 }
373 else {
374 ret = wc_Sha384Update(&hmac->hash.sha384, key, length);
375 if (ret != 0)
376 break;
377 ret = wc_Sha384Final(&hmac->hash.sha384, ip);
378 if (ret != 0)
379 break;
380
381 length = WC_SHA384_DIGEST_SIZE;
382 }
383 break;
384 #endif /* WOLFSSL_SHA384 */
385 case WC_SHA512:
386 hmac_block_size = WC_SHA512_BLOCK_SIZE;
387 if (length <= WC_SHA512_BLOCK_SIZE) {
388 if (key != NULL) {
389 XMEMCPY(ip, key, length);
390 }
391 }
392 else {
393 ret = wc_Sha512Update(&hmac->hash.sha512, key, length);
394 if (ret != 0)
395 break;
396 ret = wc_Sha512Final(&hmac->hash.sha512, ip);
397 if (ret != 0)
398 break;
399
400 length = WC_SHA512_DIGEST_SIZE;
401 }
402 break;
403 #endif /* WOLFSSL_SHA512 */
404
405 #ifdef HAVE_BLAKE2
406 case BLAKE2B_ID:
407 hmac_block_size = BLAKE2B_BLOCKBYTES;
408 if (length <= BLAKE2B_BLOCKBYTES) {
409 if (key != NULL) {
410 XMEMCPY(ip, key, length);
411 }
412 }
413 else {
414 ret = wc_Blake2bUpdate(&hmac->hash.blake2b, key, length);
415 if (ret != 0)
416 break;
417 ret = wc_Blake2bFinal(&hmac->hash.blake2b, ip, BLAKE2B_256);
418 if (ret != 0)
419 break;
420
421 length = BLAKE2B_256;
422 }
423 break;
424 #endif /* HAVE_BLAKE2 */
425
426 default:
427 return BAD_FUNC_ARG;
428 }
429
430#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
431 if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
432 #if defined(HAVE_INTEL_QA)
433 if (length > hmac_block_size)
434 length = hmac_block_size;
435 /* update key length */
436 hmac->keyLen = (word16)length;
437
438 return ret;
439 /* no need to pad below */
440 #endif
441 }
442#endif
443
444 if (ret == 0) {
445 if (length < hmac_block_size)
446 XMEMSET(ip + length, 0, hmac_block_size - length);
447
448 for(i = 0; i < hmac_block_size; i++) {
449 op[i] = ip[i] ^ OPAD;
450 ip[i] ^= IPAD;
451 }
452 }
453
454 return ret;
455}
456
457
458static int HmacKeyInnerHash(Hmac* hmac)
459{
460 int ret = 0;
461
462 switch (hmac->macType) {
463 #ifndef NO_MD5
464 case WC_MD5:
465 ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->ipad,
466 WC_MD5_BLOCK_SIZE);
467 break;
468 #endif /* !NO_MD5 */
469
470 #ifndef NO_SHA
471 case WC_SHA:
472 ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->ipad,
473 WC_SHA_BLOCK_SIZE);
474 break;
475 #endif /* !NO_SHA */
476
477 #ifdef WOLFSSL_SHA224
478 case WC_SHA224:
479 ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->ipad,
480 WC_SHA224_BLOCK_SIZE);
481 break;
482 #endif /* WOLFSSL_SHA224 */
483
484 #ifndef NO_SHA256
485 case WC_SHA256:
486 ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->ipad,
487 WC_SHA256_BLOCK_SIZE);
488 break;
489 #endif /* !NO_SHA256 */
490
491 #ifdef WOLFSSL_SHA512
492 #ifdef WOLFSSL_SHA384
493 case WC_SHA384:
494 ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->ipad,
495 WC_SHA384_BLOCK_SIZE);
496 break;
497 #endif /* WOLFSSL_SHA384 */
498 case WC_SHA512:
499 ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->ipad,
500 WC_SHA512_BLOCK_SIZE);
501 break;
502 #endif /* WOLFSSL_SHA512 */
503
504 #ifdef HAVE_BLAKE2
505 case BLAKE2B_ID:
506 ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*)hmac->ipad,
507 BLAKE2B_BLOCKBYTES);
508 break;
509 #endif /* HAVE_BLAKE2 */
510
511 default:
512 break;
513 }
514
515 if (ret == 0)
516 hmac->innerHashKeyed = 1;
517
518 return ret;
519}
520
521
522int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length)
523{
524 int ret = 0;
525
526 if (hmac == NULL || (msg == NULL && length > 0)) {
527 return BAD_FUNC_ARG;
528 }
529
530#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
531 if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
532 #if defined(HAVE_CAVIUM)
533 return NitroxHmacUpdate(hmac, msg, length);
534 #elif defined(HAVE_INTEL_QA)
535 return IntelQaHmac(&hmac->asyncDev, hmac->macType,
536 (byte*)hmac->ipad, hmac->keyLen, NULL, msg, length);
537 #endif
538 }
539#endif /* WOLFSSL_ASYNC_CRYPT */
540
541 if (!hmac->innerHashKeyed) {
542 ret = HmacKeyInnerHash(hmac);
543 if (ret != 0)
544 return ret;
545 }
546
547 switch (hmac->macType) {
548 #ifndef NO_MD5
549 case WC_MD5:
550 ret = wc_Md5Update(&hmac->hash.md5, msg, length);
551 break;
552 #endif /* !NO_MD5 */
553
554 #ifndef NO_SHA
555 case WC_SHA:
556 ret = wc_ShaUpdate(&hmac->hash.sha, msg, length);
557 break;
558 #endif /* !NO_SHA */
559
560 #ifdef WOLFSSL_SHA224
561 case WC_SHA224:
562 ret = wc_Sha224Update(&hmac->hash.sha224, msg, length);
563 break;
564 #endif /* WOLFSSL_SHA224 */
565
566 #ifndef NO_SHA256
567 case WC_SHA256:
568 ret = wc_Sha256Update(&hmac->hash.sha256, msg, length);
569 break;
570 #endif /* !NO_SHA256 */
571
572 #ifdef WOLFSSL_SHA512
573 #ifdef WOLFSSL_SHA384
574 case WC_SHA384:
575 ret = wc_Sha384Update(&hmac->hash.sha384, msg, length);
576 break;
577 #endif /* WOLFSSL_SHA384 */
578 case WC_SHA512:
579 ret = wc_Sha512Update(&hmac->hash.sha512, msg, length);
580 break;
581 #endif /* WOLFSSL_SHA512 */
582
583 #ifdef HAVE_BLAKE2
584 case BLAKE2B_ID:
585 ret = wc_Blake2bUpdate(&hmac->hash.blake2b, msg, length);
586 break;
587 #endif /* HAVE_BLAKE2 */
588
589 default:
590 break;
591 }
592
593 return ret;
594}
595
596
597int wc_HmacFinal(Hmac* hmac, byte* hash)
598{
599 int ret;
600
601 if (hmac == NULL || hash == NULL) {
602 return BAD_FUNC_ARG;
603 }
604
605#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
606 if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
607 int hashLen = wc_HmacSizeByType(hmac->macType);
608 if (hashLen <= 0)
609 return hashLen;
610
611 #if defined(HAVE_CAVIUM)
612 return NitroxHmacFinal(hmac, hmac->macType, hash, hashLen);
613 #elif defined(HAVE_INTEL_QA)
614 return IntelQaHmac(&hmac->asyncDev, hmac->macType,
615 (byte*)hmac->ipad, hmac->keyLen, hash, NULL, hashLen);
616 #endif
617 }
618#endif /* WOLFSSL_ASYNC_CRYPT */
619
620 if (!hmac->innerHashKeyed) {
621 ret = HmacKeyInnerHash(hmac);
622 if (ret != 0)
623 return ret;
624 }
625
626 switch (hmac->macType) {
627 #ifndef NO_MD5
628 case WC_MD5:
629 ret = wc_Md5Final(&hmac->hash.md5, (byte*)hmac->innerHash);
630 if (ret != 0)
631 break;
632 ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->opad,
633 WC_MD5_BLOCK_SIZE);
634 if (ret != 0)
635 break;
636 ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->innerHash,
637 WC_MD5_DIGEST_SIZE);
638 if (ret != 0)
639 break;
640 ret = wc_Md5Final(&hmac->hash.md5, hash);
641 break;
642 #endif /* !NO_MD5 */
643
644 #ifndef NO_SHA
645 case WC_SHA:
646 ret = wc_ShaFinal(&hmac->hash.sha, (byte*)hmac->innerHash);
647 if (ret != 0)
648 break;
649 ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->opad,
650 WC_SHA_BLOCK_SIZE);
651 if (ret != 0)
652 break;
653 ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->innerHash,
654 WC_SHA_DIGEST_SIZE);
655 if (ret != 0)
656 break;
657 ret = wc_ShaFinal(&hmac->hash.sha, hash);
658 break;
659 #endif /* !NO_SHA */
660
661 #ifdef WOLFSSL_SHA224
662 case WC_SHA224:
663 {
664 ret = wc_Sha224Final(&hmac->hash.sha224, (byte*)hmac->innerHash);
665 if (ret != 0)
666 break;
667 ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->opad,
668 WC_SHA224_BLOCK_SIZE);
669 if (ret != 0)
670 break;
671 ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->innerHash,
672 WC_SHA224_DIGEST_SIZE);
673 if (ret != 0)
674 break;
675 ret = wc_Sha224Final(&hmac->hash.sha224, hash);
676 if (ret != 0)
677 break;
678 }
679 break;
680 #endif /* WOLFSSL_SHA224 */
681
682 #ifndef NO_SHA256
683 case WC_SHA256:
684 ret = wc_Sha256Final(&hmac->hash.sha256, (byte*)hmac->innerHash);
685 if (ret != 0)
686 break;
687 ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->opad,
688 WC_SHA256_BLOCK_SIZE);
689 if (ret != 0)
690 break;
691 ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->innerHash,
692 WC_SHA256_DIGEST_SIZE);
693 if (ret != 0)
694 break;
695 ret = wc_Sha256Final(&hmac->hash.sha256, hash);
696 break;
697 #endif /* !NO_SHA256 */
698
699 #ifdef WOLFSSL_SHA512
700 #ifdef WOLFSSL_SHA384
701 case WC_SHA384:
702 ret = wc_Sha384Final(&hmac->hash.sha384, (byte*)hmac->innerHash);
703 if (ret != 0)
704 break;
705 ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->opad,
706 WC_SHA384_BLOCK_SIZE);
707 if (ret != 0)
708 break;
709 ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->innerHash,
710 WC_SHA384_DIGEST_SIZE);
711 if (ret != 0)
712 break;
713 ret = wc_Sha384Final(&hmac->hash.sha384, hash);
714 break;
715 #endif /* WOLFSSL_SHA384 */
716 case WC_SHA512:
717 ret = wc_Sha512Final(&hmac->hash.sha512, (byte*)hmac->innerHash);
718 if (ret != 0)
719 break;
720 ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->opad,
721 WC_SHA512_BLOCK_SIZE);
722 if (ret != 0)
723 break;
724 ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->innerHash,
725 WC_SHA512_DIGEST_SIZE);
726 if (ret != 0)
727 break;
728 ret = wc_Sha512Final(&hmac->hash.sha512, hash);
729 break;
730 #endif /* WOLFSSL_SHA512 */
731
732 #ifdef HAVE_BLAKE2
733 case BLAKE2B_ID:
734 ret = wc_Blake2bFinal(&hmac->hash.blake2b, (byte*)hmac->innerHash,
735 BLAKE2B_256);
736 if (ret != 0)
737 break;
738 ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*)hmac->opad,
739 BLAKE2B_BLOCKBYTES);
740 if (ret != 0)
741 break;
742 ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*)hmac->innerHash,
743 BLAKE2B_256);
744 if (ret != 0)
745 break;
746 ret = wc_Blake2bFinal(&hmac->hash.blake2b, hash, BLAKE2B_256);
747 break;
748 #endif /* HAVE_BLAKE2 */
749
750 default:
751 ret = BAD_FUNC_ARG;
752 break;
753 }
754
755 if (ret == 0) {
756 hmac->innerHashKeyed = 0;
757 }
758
759 return ret;
760}
761
762
763/* Initialize Hmac for use with async device */
764int wc_HmacInit(Hmac* hmac, void* heap, int devId)
765{
766 int ret = 0;
767
768 if (hmac == NULL)
769 return BAD_FUNC_ARG;
770
771 XMEMSET(hmac, 0, sizeof(Hmac));
772 hmac->heap = heap;
773
774#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
775 hmac->keyLen = 0;
776 #ifdef HAVE_CAVIUM
777 hmac->dataLen = 0;
778 hmac->data = NULL; /* buffered input data */
779 #endif /* HAVE_CAVIUM */
780
781 ret = wolfAsync_DevCtxInit(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC,
782 hmac->heap, devId);
783#else
784 (void)devId;
785#endif /* WOLFSSL_ASYNC_CRYPT */
786
787 return ret;
788}
789
790/* Free Hmac from use with async device */
791void wc_HmacFree(Hmac* hmac)
792{
793 if (hmac == NULL)
794 return;
795
796#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
797 wolfAsync_DevCtxFree(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC);
798
799#ifdef HAVE_CAVIUM
800 XFREE(hmac->data, hmac->heap, DYNAMIC_TYPE_HMAC);
801 hmac->data = NULL;
802#endif /* HAVE_CAVIUM */
803#endif /* WOLFSSL_ASYNC_CRYPT */
804}
805
806int wolfSSL_GetHmacMaxSize(void)
807{
808 return MAX_DIGEST_SIZE;
809}
810
811#ifdef HAVE_HKDF
812 /* HMAC-KDF-Extract.
813 * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
814 *
815 * type The hash algorithm type.
816 * salt The optional salt value.
817 * saltSz The size of the salt.
818 * inKey The input keying material.
819 * inKeySz The size of the input keying material.
820 * out The pseudorandom key with the length that of the hash.
821 * returns 0 on success, otherwise failure.
822 */
823 int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz,
824 const byte* inKey, word32 inKeySz, byte* out)
825 {
826 byte tmp[MAX_DIGEST_SIZE]; /* localSalt helper */
827 Hmac myHmac;
828 int ret;
829 const byte* localSalt; /* either points to user input or tmp */
830 int hashSz;
831
832 ret = wc_HmacSizeByType(type);
833 if (ret < 0)
834 return ret;
835
836 hashSz = ret;
837 localSalt = salt;
838 if (localSalt == NULL) {
839 XMEMSET(tmp, 0, hashSz);
840 localSalt = tmp;
841 saltSz = hashSz;
842 }
843
844 ret = wc_HmacInit(&myHmac, NULL, INVALID_DEVID);
845 if (ret == 0) {
846 ret = wc_HmacSetKey(&myHmac, type, localSalt, saltSz);
847 if (ret == 0)
848 ret = wc_HmacUpdate(&myHmac, inKey, inKeySz);
849 if (ret == 0)
850 ret = wc_HmacFinal(&myHmac, out);
851 wc_HmacFree(&myHmac);
852 }
853
854 return ret;
855 }
856
857 /* HMAC-KDF-Expand.
858 * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
859 *
860 * type The hash algorithm type.
861 * inKey The input key.
862 * inKeySz The size of the input key.
863 * info The application specific information.
864 * infoSz The size of the application specific information.
865 * out The output keying material.
866 * returns 0 on success, otherwise failure.
867 */
868 int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz,
869 const byte* info, word32 infoSz, byte* out, word32 outSz)
870 {
871 byte tmp[MAX_DIGEST_SIZE];
872 Hmac myHmac;
873 int ret = 0;
874 word32 outIdx = 0;
875 word32 hashSz = wc_HmacSizeByType(type);
876 byte n = 0x1;
877
878 ret = wc_HmacInit(&myHmac, NULL, INVALID_DEVID);
879 if (ret != 0)
880 return ret;
881
882 while (outIdx < outSz) {
883 int tmpSz = (n == 1) ? 0 : hashSz;
884 word32 left = outSz - outIdx;
885
886 ret = wc_HmacSetKey(&myHmac, type, inKey, inKeySz);
887 if (ret != 0)
888 break;
889 ret = wc_HmacUpdate(&myHmac, tmp, tmpSz);
890 if (ret != 0)
891 break;
892 ret = wc_HmacUpdate(&myHmac, info, infoSz);
893 if (ret != 0)
894 break;
895 ret = wc_HmacUpdate(&myHmac, &n, 1);
896 if (ret != 0)
897 break;
898 ret = wc_HmacFinal(&myHmac, tmp);
899 if (ret != 0)
900 break;
901
902 left = min(left, hashSz);
903 XMEMCPY(out+outIdx, tmp, left);
904
905 outIdx += hashSz;
906 n++;
907 }
908
909 wc_HmacFree(&myHmac);
910
911 return ret;
912 }
913
914 /* HMAC-KDF.
915 * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
916 *
917 * type The hash algorithm type.
918 * inKey The input keying material.
919 * inKeySz The size of the input keying material.
920 * salt The optional salt value.
921 * saltSz The size of the salt.
922 * info The application specific information.
923 * infoSz The size of the application specific information.
924 * out The output keying material.
925 * returns 0 on success, otherwise failure.
926 */
927 int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
928 const byte* salt, word32 saltSz,
929 const byte* info, word32 infoSz,
930 byte* out, word32 outSz)
931 {
932 byte prk[MAX_DIGEST_SIZE];
933 int hashSz = wc_HmacSizeByType(type);
934 int ret;
935
936 if (hashSz < 0)
937 return BAD_FUNC_ARG;
938
939 ret = wc_HKDF_Extract(type, salt, saltSz, inKey, inKeySz, prk);
940 if (ret != 0)
941 return ret;
942
943 return wc_HKDF_Expand(type, prk, hashSz, info, infoSz, out, outSz);
944 }
945
946#endif /* HAVE_HKDF */
947
948#endif /* HAVE_FIPS */
949#endif /* NO_HMAC */
Note: See TracBrowser for help on using the repository browser.