/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 */ |