File Coverage

inc/matrixssl-3-9-3-open/crypto/digest/hmac.c
Criterion Covered Total %
statement 90 205 43.9
branch 34 80 42.5
condition n/a
subroutine n/a
pod n/a
total 124 285 43.5


line stmt bran cond sub pod time code
1             /**
2             * @file hmac.c
3             * @version 950bba4 (HEAD -> master)
4             *
5             * HMAC implementation.
6             */
7             /*
8             * Copyright (c) 2013-2017 INSIDE Secure Corporation
9             * Copyright (c) PeerSec Networks, 2002-2011
10             * All Rights Reserved
11             *
12             * The latest version of this code is available at http://www.matrixssl.org
13             *
14             * This software is open source; you can redistribute it and/or modify
15             * it under the terms of the GNU General Public License as published by
16             * the Free Software Foundation; either version 2 of the License, or
17             * (at your option) any later version.
18             *
19             * This General Public License does NOT permit incorporating this software
20             * into proprietary programs. If you are unable to comply with the GPL, a
21             * commercial license for this software may be purchased from INSIDE at
22             * http://www.insidesecure.com/
23             *
24             * This program is distributed in WITHOUT ANY WARRANTY; without even the
25             * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26             * See the GNU General Public License for more details.
27             *
28             * You should have received a copy of the GNU General Public License
29             * along with this program; if not, write to the Free Software
30             * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31             * http://www.gnu.org/copyleft/gpl.html
32             */
33             /******************************************************************************/
34              
35             #include "../cryptoImpl.h"
36              
37 0           int32_t psHmacInit(psHmac_t *ctx, psCipherType_e type,
38             const unsigned char *key, psSize_t keyLen)
39             {
40 0           ctx->type = (uint8_t) type;
41 0           switch (type)
42             {
43             #ifdef USE_HMAC_MD5
44             case HMAC_MD5:
45 0           return psHmacMd5Init(&ctx->u.md5, key, keyLen);
46             #endif
47             #ifdef USE_HMAC_SHA1
48             case HMAC_SHA1:
49 0           return psHmacSha1Init(&ctx->u.sha1, key, keyLen);
50             #endif
51             #ifdef USE_HMAC_SHA256
52             case HMAC_SHA256:
53 0           return psHmacSha256Init(&ctx->u.sha256, key, keyLen);
54             #endif
55             #ifdef USE_HMAC_SHA384
56             case HMAC_SHA384:
57 0           return psHmacSha384Init(&ctx->u.sha384, key, keyLen);
58             #endif
59             default:
60 0           return PS_ARG_FAIL;
61             }
62             /* Redundant return */
63             return PS_ARG_FAIL;
64             }
65              
66 0           void psHmacUpdate(psHmac_t *ctx, const unsigned char *buf, uint32_t len)
67             {
68 0           switch ((psCipherType_e) ctx->type)
69             {
70             #ifdef USE_HMAC_MD5
71             case HMAC_MD5:
72 0           psHmacMd5Update(&ctx->u.md5, buf, len);
73 0           break;
74             #endif
75             #ifdef USE_HMAC_SHA1
76             case HMAC_SHA1:
77 0           psHmacSha1Update(&ctx->u.sha1, buf, len);
78 0           break;
79             #endif
80             #ifdef USE_HMAC_SHA256
81             case HMAC_SHA256:
82 0           psHmacSha256Update(&ctx->u.sha256, buf, len);
83 0           break;
84             #endif
85             #ifdef USE_HMAC_SHA384
86             case HMAC_SHA384:
87 0           psHmacSha384Update(&ctx->u.sha384, buf, len);
88 0           break;
89             #endif
90             default:
91 0           break;
92             }
93 0           }
94              
95 0           void psHmacFinal(psHmac_t *ctx, unsigned char hash[MAX_HASHLEN])
96             {
97 0           switch ((psCipherType_e) ctx->type)
98             {
99             #ifdef USE_HMAC_MD5
100             case HMAC_MD5:
101 0           psHmacMd5Final(&ctx->u.md5, hash);
102 0           break;
103             #endif
104             #ifdef USE_HMAC_SHA1
105             case HMAC_SHA1:
106 0           psHmacSha1Final(&ctx->u.sha1, hash);
107 0           break;
108             #endif
109             #ifdef USE_HMAC_SHA256
110             case HMAC_SHA256:
111 0           psHmacSha256Final(&ctx->u.sha256, hash);
112 0           break;
113             #endif
114             #ifdef USE_HMAC_SHA384
115             case HMAC_SHA384:
116 0           psHmacSha384Final(&ctx->u.sha384, hash);
117 0           break;
118             #endif
119             default:
120 0           break;
121             }
122 0           ctx->type = 0;
123 0           }
124              
125             #ifdef USE_MATRIX_HMAC_MD5
126             /******************************************************************************/
127             /*
128             HMAC-MD5
129             http://www.faqs.org/rfcs/rfc2104.html
130              
131             the HMAC_MD5 transform looks like:
132              
133             MD5(K XOR opad, MD5(K XOR ipad, text))
134              
135             where K is an n byte key
136             ipad is the byte 0x36 repeated 64 times
137              
138             opad is the byte 0x5c repeated 64 times
139             and text is the data being protected
140              
141             If the keyLen is > 64 bytes, we hash the key and use it instead
142             */
143             # if !defined(USE_MATRIX_MD5) && !defined(USE_CL_DIGESTS)
144             # error USE_MATRIX_MD5 or USE_CL_DIGESTS required
145             # endif
146 0           int32_t psHmacMd5(const unsigned char *key, psSize_t keyLen,
147             const unsigned char *buf, uint32_t len,
148             unsigned char hash[MD5_HASHLEN],
149             unsigned char *hmacKey, psSize_t *hmacKeyLen)
150             {
151             int32_t rc;
152              
153             union
154             {
155             psHmacMd5_t mac;
156             psMd5_t md;
157             } u;
158 0           psHmacMd5_t *mac = &u.mac;
159 0           psMd5_t *md = &u.md;
160             /*
161             Support for keys larger than 64 bytes. In this case, we take the
162             hash of the key itself and use that instead. Inform the caller by
163             updating the hmacKey and hmacKeyLen outputs
164             */
165 0 0         if (keyLen > 64)
166             {
167 0 0         if ((rc = psMd5Init(md)) < 0)
168             {
169 0           return rc;
170             }
171 0           psMd5Update(md, key, keyLen);
172 0           psMd5Final(md, hash);
173 0           *hmacKeyLen = MD5_HASHLEN;
174 0           memcpy(hmacKey, hash, *hmacKeyLen);
175             }
176             else
177             {
178 0           hmacKey = (unsigned char *) key; /* @note typecasting from const */
179 0           *hmacKeyLen = keyLen;
180             }
181 0 0         if ((rc = psHmacMd5Init(mac, hmacKey, *hmacKeyLen)) < 0)
182             {
183 0           return rc;
184             }
185 0           psHmacMd5Update(mac, buf, len);
186 0           psHmacMd5Final(mac, hash);
187 0           return PS_SUCCESS;
188             }
189              
190 0           int32_t psHmacMd5Init(psHmacMd5_t *ctx,
191             const unsigned char *key, psSize_t keyLen)
192             {
193             int32_t rc, i;
194              
195             # ifdef CRYPTO_ASSERT
196             psAssert(keyLen <= 64);
197             # endif
198 0 0         for (i = 0; (uint32) i < keyLen; i++)
199             {
200 0           ctx->pad[i] = key[i] ^ 0x36;
201             }
202 0 0         for (i = keyLen; i < 64; i++)
203             {
204 0           ctx->pad[i] = 0x36;
205             }
206 0 0         if ((rc = psMd5Init(&ctx->md5)) < 0)
207             {
208 0           return rc;
209             }
210 0           psMd5Update(&ctx->md5, ctx->pad, 64);
211 0 0         for (i = 0; (uint32) i < keyLen; i++)
212             {
213 0           ctx->pad[i] = key[i] ^ 0x5c;
214             }
215 0 0         for (i = keyLen; i < 64; i++)
216             {
217 0           ctx->pad[i] = 0x5c;
218             }
219 0           return PS_SUCCESS;
220             }
221              
222 0           void psHmacMd5Update(psHmacMd5_t *ctx,
223             const unsigned char *buf, uint32_t len)
224             {
225             # ifdef CRYPTO_ASSERT
226             psAssert(ctx != NULL && buf != NULL);
227             # endif
228 0           psMd5Update(&ctx->md5, buf, len);
229 0           }
230              
231 0           void psHmacMd5Final(psHmacMd5_t *ctx, unsigned char hash[MD5_HASHLEN])
232             {
233             int32_t rc;
234              
235             # ifdef CRYPTO_ASSERT
236             psAssert(ctx != NULL);
237             if (hash == NULL)
238             {
239             psTraceCrypto("NULL hash storage passed to psHmacMd5Final\n");
240             return;
241             }
242             # endif
243 0           psMd5Final(&ctx->md5, hash);
244              
245             /* This Init should succeed, even if it allocates memory since an
246             psMd5_t was just Finalized the line above */
247 0 0         if ((rc = psMd5Init(&ctx->md5)) < 0)
248             {
249 0 0         psAssert(rc >= 0);
250 0           return;
251             }
252 0           psMd5Update(&ctx->md5, ctx->pad, 64);
253 0           psMd5Update(&ctx->md5, hash, MD5_HASHLEN);
254 0           psMd5Final(&ctx->md5, hash);
255              
256 0           memset(ctx->pad, 0x0, sizeof(ctx->pad));
257             }
258              
259             #endif /* USE_MATRIX_HMAC_MD5 */
260              
261             #ifdef USE_MATRIX_HMAC_SHA1
262             /******************************************************************************/
263             /*
264             HMAC-SHA1
265             @see http://www.faqs.org/rfcs/rfc2104.html
266             */
267             # ifndef USE_SHA1
268             # error USE_SHA1 required
269             # endif
270              
271 0           int32_t psHmacSha1(const unsigned char *key, psSize_t keyLen,
272             const unsigned char *buf, uint32_t len,
273             unsigned char hash[SHA1_HASHLEN],
274             unsigned char *hmacKey, psSize_t *hmacKeyLen)
275             {
276             int32_t rc;
277              
278             union
279             {
280             psHmacSha1_t mac;
281             psSha1_t md;
282             } u;
283 0           psHmacSha1_t *mac = &u.mac;
284 0           psSha1_t *md = &u.md;
285             /*
286             Support for keys larger than 64 bytes. In this case, we take the
287             hash of the key itself and use that instead. Inform the caller by
288             updating the hmacKey and hmacKeyLen outputs
289             */
290 0 0         if (keyLen > 64)
291             {
292 0 0         if ((rc = psSha1Init(md)) < 0)
293             {
294 0           return rc;
295             }
296 0           psSha1Update(md, key, keyLen);
297 0           psSha1Final(md, hash);
298 0           *hmacKeyLen = SHA1_HASHLEN;
299 0           memcpy(hmacKey, hash, *hmacKeyLen);
300             }
301             else
302             {
303 0           hmacKey = (unsigned char *) key; /* @note typecasting from const */
304 0           *hmacKeyLen = keyLen;
305             }
306              
307 0 0         if ((rc = psHmacSha1Init(mac, hmacKey, *hmacKeyLen)) < 0)
308             {
309 0           return rc;
310             }
311 0           psHmacSha1Update(mac, buf, len);
312 0           psHmacSha1Final(mac, hash);
313 0           return PS_SUCCESS;
314             }
315              
316 16           int32_t psHmacSha1Init(psHmacSha1_t *ctx,
317             const unsigned char *key, psSize_t keyLen)
318             {
319             int32_t rc, i;
320              
321             # ifdef CRYPTO_ASSERT
322             psAssert(keyLen <= 64);
323             # endif
324 336 100         for (i = 0; (uint32) i < keyLen; i++)
325             {
326 320           ctx->pad[i] = key[i] ^ 0x36;
327             }
328 720 100         for (i = keyLen; (uint32) i < 64; i++)
329             {
330 704           ctx->pad[i] = 0x36;
331             }
332 16 50         if ((rc = psSha1Init(&ctx->sha1)) < 0)
333             {
334 0           return rc;
335             }
336 16           psSha1Update(&ctx->sha1, ctx->pad, 64);
337 336 100         for (i = 0; (uint32) i < keyLen; i++)
338             {
339 320           ctx->pad[i] = key[i] ^ 0x5c;
340             }
341 720 100         for (i = keyLen; i < 64; i++)
342             {
343 704           ctx->pad[i] = 0x5c;
344             }
345 16           return PS_SUCCESS;
346             }
347              
348 28           void psHmacSha1Update(psHmacSha1_t *ctx,
349             const unsigned char *buf, uint32_t len)
350             {
351             # ifdef CRYPTO_ASSERT
352             psAssert(ctx != NULL && buf != NULL);
353             # endif
354 28           psSha1Update(&ctx->sha1, buf, len);
355 28           }
356              
357 16           void psHmacSha1Final(psHmacSha1_t *ctx, unsigned char hash[SHA1_HASHLEN])
358             {
359             int32_t rc;
360              
361             # ifdef CRYPTO_ASSERT
362             psAssert(ctx != NULL);
363             if (hash == NULL)
364             {
365             psTraceCrypto("NULL hash storage passed to psHmacSha1Final\n");
366             return;
367             }
368             # endif
369 16           psSha1Final(&ctx->sha1, hash);
370              
371 16 50         if ((rc = psSha1Init(&ctx->sha1)) < 0)
372             {
373 0 0         psAssert(rc >= 0);
374 0           return;
375             }
376 16           psSha1Update(&ctx->sha1, ctx->pad, 64);
377 16           psSha1Update(&ctx->sha1, hash, SHA1_HASHLEN);
378 16           psSha1Final(&ctx->sha1, hash);
379              
380 16           memset(ctx->pad, 0x0, sizeof(ctx->pad));
381             }
382              
383             #endif /* USE_MATRIX_HMAC_SHA1 */
384              
385             #ifdef USE_MATRIX_HMAC_SHA256
386             /******************************************************************************/
387             /*
388             HMAC-SHA256
389             */
390 24           int32_t psHmacSha256(const unsigned char *key, psSize_t keyLen,
391             const unsigned char *buf, uint32_t len,
392             unsigned char hash[SHA256_HASHLEN], unsigned char *hmacKey,
393             psSize_t *hmacKeyLen)
394             {
395             int32 rc, padLen;
396              
397             union
398             {
399             psHmacSha256_t mac;
400             psSha256_t md;
401             } u;
402 24           psHmacSha256_t *mac = &u.mac;
403 24           psSha256_t *md = &u.md;
404              
405 24           padLen = 64;
406              
407             /*
408             Support for keys larger than hash block size. In this case, we take the
409             hash of the key itself and use that instead. Inform the caller by
410             updating the hmacKey and hmacKeyLen outputs
411             */
412 24 50         if (keyLen > (uint32) padLen)
413             {
414 0 0         if ((rc = psSha256Init(md)) < 0)
415             {
416 0           return rc;
417             }
418 0           psSha256Update(md, key, keyLen);
419 0           psSha256Final(md, hash);
420 0           memcpy(hmacKey, hash, SHA256_HASHLEN);
421 0           *hmacKeyLen = SHA256_HASHLEN;
422             }
423             else
424             {
425 24           hmacKey = (unsigned char *) key; /* @note typecasting from const */
426 24           *hmacKeyLen = keyLen;
427             }
428              
429 24 50         if ((rc = psHmacSha256Init(mac, hmacKey, *hmacKeyLen)) < 0)
430             {
431 0           return rc;
432             }
433 24           psHmacSha256Update(mac, buf, len);
434 24           psHmacSha256Final(mac, hash);
435 24           return PS_SUCCESS;
436             }
437              
438 48           int32_t psHmacSha256Init(psHmacSha256_t *ctx,
439             const unsigned char *key, psSize_t keyLen)
440             {
441 48           int32_t rc, i, padLen = 64;
442              
443             # ifdef CRYPTO_ASSERT
444             psAssert(keyLen <= (uint32) padLen);
445             # endif
446 2288 100         for (i = 0; (uint32) i < keyLen; i++)
447             {
448 2240           ctx->pad[i] = key[i] ^ 0x36;
449             }
450 880 100         for (i = keyLen; i < padLen; i++)
451             {
452 832           ctx->pad[i] = 0x36;
453             }
454 48 50         if ((rc = psSha256Init(&ctx->sha256)) < 0)
455             {
456 0           return rc;
457             }
458 48           psSha256Update(&ctx->sha256, ctx->pad, padLen);
459 2288 100         for (i = 0; (uint32) i < keyLen; i++)
460             {
461 2240           ctx->pad[i] = key[i] ^ 0x5c;
462             }
463 880 100         for (i = keyLen; i < padLen; i++)
464             {
465 832           ctx->pad[i] = 0x5c;
466             }
467 48           return PS_SUCCESS;
468             }
469              
470 72           void psHmacSha256Update(psHmacSha256_t *ctx,
471             const unsigned char *buf, uint32_t len)
472             {
473             # ifdef CRYPTO_ASSERT
474             psAssert(ctx != NULL && buf != NULL);
475             # endif
476 72           psSha256Update(&ctx->sha256, buf, len);
477 72           }
478              
479 48           void psHmacSha256Final(psHmacSha256_t *ctx,
480             unsigned char hash[SHA256_HASHLEN])
481             {
482             int32_t rc;
483              
484             # ifdef CRYPTO_ASSERT
485             psAssert(ctx != NULL);
486             if (hash == NULL)
487             {
488             psTraceCrypto("NULL hash storage passed to psHmacSha256Final\n");
489             return;
490             }
491             # endif
492              
493 48           psSha256Final(&ctx->sha256, hash);
494              
495 48 50         if ((rc = psSha256Init(&ctx->sha256)) < 0)
496             {
497 0 0         psAssert(rc >= 0);
498 0           return;
499             }
500 48           psSha256Update(&ctx->sha256, ctx->pad, 64);
501 48           psSha256Update(&ctx->sha256, hash, SHA256_HASHLEN);
502 48           psSha256Final(&ctx->sha256, hash);
503 48           memset(ctx->pad, 0x0, sizeof(ctx->pad));
504             }
505             #endif /* USE_MATRIX_HMAC_SHA256 */
506              
507             #ifdef USE_MATRIX_HMAC_SHA384
508             /******************************************************************************/
509             /*
510             HMAC-SHA384
511             */
512 10576           int32_t psHmacSha384(const unsigned char *key, psSize_t keyLen,
513             const unsigned char *buf, uint32_t len,
514             unsigned char hash[SHA384_HASHLEN],
515             unsigned char *hmacKey, psSize_t *hmacKeyLen)
516             {
517             int32 rc, padLen;
518              
519             union
520             {
521             psHmacSha384_t mac;
522             psSha384_t md;
523             } u;
524 10576           psHmacSha384_t *mac = &u.mac;
525 10576           psSha384_t *md = &u.md;
526              
527 10576           padLen = 128;
528              
529             /*
530             Support for keys larger than hash block size. In this case, we take the
531             hash of the key itself and use that instead. Inform the caller by
532             updating the hmacKey and hmacKeyLen outputs
533             */
534 10576 50         if (keyLen > (uint32) padLen)
535             {
536 0 0         if ((rc = psSha384Init(md)) < 0)
537             {
538 0           return rc;
539             }
540 0           psSha384Update(md, key, keyLen);
541 0           psSha384Final(md, hash);
542 0           memcpy(hmacKey, hash, SHA384_HASHLEN);
543 0           *hmacKeyLen = SHA384_HASHLEN;
544             }
545             else
546             {
547 10576           hmacKey = (unsigned char *) key; /* @note typecasting from const */
548 10576           *hmacKeyLen = keyLen;
549             }
550              
551 10576 50         if ((rc = psHmacSha384Init(mac, hmacKey, *hmacKeyLen)) < 0)
552             {
553 0           return rc;
554             }
555 10576           psHmacSha384Update(mac, buf, len);
556 10576           psHmacSha384Final(mac, hash);
557 10576           return PS_SUCCESS;
558             }
559              
560 21152           int32_t psHmacSha384Init(psHmacSha384_t *ctx,
561             const unsigned char *key, psSize_t keyLen)
562             {
563             int32_t rc, i, padLen;
564              
565 21152           padLen = 128;
566              
567             # ifdef CRYPTO_ASSERT
568             psAssert(keyLen <= (uint32) padLen);
569             # endif
570 1112480 100         for (i = 0; (uint32) i < keyLen; i++)
571             {
572 1091328           ctx->pad[i] = key[i] ^ 0x36;
573             }
574 1637280 100         for (i = keyLen; i < padLen; i++)
575             {
576 1616128           ctx->pad[i] = 0x36;
577             }
578 21152 50         if ((rc = psSha384Init(&ctx->sha384)) < 0)
579             {
580 0           return rc;
581             }
582 21152           psSha384Update(&ctx->sha384, ctx->pad, padLen);
583              
584 1112480 100         for (i = 0; (uint32) i < keyLen; i++)
585             {
586 1091328           ctx->pad[i] = key[i] ^ 0x5c;
587             }
588 1637280 100         for (i = keyLen; i < padLen; i++)
589             {
590 1616128           ctx->pad[i] = 0x5c;
591             }
592 21152           return PS_SUCCESS;
593             }
594              
595 31728           void psHmacSha384Update(psHmacSha384_t *ctx,
596             const unsigned char *buf, uint32_t len)
597             {
598             # ifdef CRYPTO_ASSERT
599             psAssert(ctx != NULL && buf != NULL);
600             # endif
601 31728           psSha384Update(&ctx->sha384, buf, len);
602 31728           }
603              
604 21152           void psHmacSha384Final(psHmacSha384_t *ctx,
605             unsigned char hash[SHA384_HASHLEN])
606             {
607             int32_t rc;
608              
609             # ifdef CRYPTO_ASSERT
610             psAssert(ctx != NULL);
611             if (hash == NULL)
612             {
613             psTraceCrypto("NULL hash storage passed to psHmacSha256Final\n");
614             return;
615             }
616             # endif
617              
618 21152           psSha384Final(&ctx->sha384, hash);
619              
620 21152 50         if ((rc = psSha384Init(&ctx->sha384)) < 0)
621             {
622 0 0         psAssert(rc >= 0);
623 0           return;
624             }
625 21152           psSha384Update(&ctx->sha384, ctx->pad, 128);
626 21152           psSha384Update(&ctx->sha384, hash, SHA384_HASHLEN);
627 21152           psSha384Final(&ctx->sha384, hash);
628              
629 21152           memset(ctx->pad, 0x0, sizeof(ctx->pad));
630             }
631             #endif /* USE_MATRIX_HMAC_SHA384 */
632              
633             /******************************************************************************/
634