This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
12ca2a80ae6eb7c1670a6ca7d6d6df7355e0941e
[perl5.git] / cpan / Digest-SHA / src / hmac.c
1 /*
2  * hmac.c: routines to compute HMAC-SHA-1/224/256/384/512 digests
3  *
4  * Ref: FIPS PUB 198 The Keyed-Hash Message Authentication Code
5  *
6  * Copyright (C) 2003-2011 Mark Shelor, All Rights Reserved
7  *
8  * Version: 5.61
9  * Wed Mar  9 05:26:36 MST 2011
10  *
11  */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include "hmac.h"
17 #include "sha.h"
18
19 /* hmacopen: creates a new HMAC-SHA digest object */
20 HMAC *hmacopen(int alg, unsigned char *key, unsigned int keylen)
21 {
22         unsigned int i;
23         HMAC *h;
24
25         SHA_newz(0, h, 1, HMAC);
26         if (h == NULL)
27                 return(NULL);
28         if ((h->isha = shaopen(alg)) == NULL) {
29                 SHA_free(h);
30                 return(NULL);
31         }
32         if ((h->osha = shaopen(alg)) == NULL) {
33                 shaclose(h->isha);
34                 SHA_free(h);
35                 return(NULL);
36         }
37         if (keylen <= h->osha->blocksize / 8)
38                 memcpy(h->key, key, keylen);
39         else {
40                 if ((h->ksha = shaopen(alg)) == NULL) {
41                         shaclose(h->isha);
42                         shaclose(h->osha);
43                         SHA_free(h);
44                         return(NULL);
45                 }
46                 shawrite(key, keylen * 8, h->ksha);
47                 shafinish(h->ksha);
48                 memcpy(h->key, shadigest(h->ksha), h->ksha->digestlen);
49                 shaclose(h->ksha);
50         }
51         for (i = 0; i < h->osha->blocksize / 8; i++)
52                 h->key[i] ^= 0x5c;
53         shawrite(h->key, h->osha->blocksize, h->osha);
54         for (i = 0; i < h->isha->blocksize / 8; i++)
55                 h->key[i] ^= (0x5c ^ 0x36);
56         shawrite(h->key, h->isha->blocksize, h->isha);
57         memset(h->key, 0, sizeof(h->key));
58         return(h);
59 }
60
61 /* hmacwrite: triggers a state update using data in bitstr/bitcnt */
62 unsigned long hmacwrite(unsigned char *bitstr, unsigned long bitcnt, HMAC *h)
63 {
64         return(shawrite(bitstr, bitcnt, h->isha));
65 }
66
67 /* hmacfinish: computes final digest state */
68 void hmacfinish(HMAC *h)
69 {
70         shafinish(h->isha);
71         shawrite(shadigest(h->isha), h->isha->digestlen * 8, h->osha);
72         shaclose(h->isha);
73         shafinish(h->osha);
74 }
75
76 /* hmacdigest: returns pointer to digest (binary) */
77 unsigned char *hmacdigest(HMAC *h)
78 {
79         return(shadigest(h->osha));
80 }
81
82 /* hmachex: returns pointer to digest (hexadecimal) */
83 char *hmachex(HMAC *h)
84 {
85         return(shahex(h->osha));
86 }
87
88 /* hmacbase64: returns pointer to digest (Base 64) */
89 char *hmacbase64(HMAC *h)
90 {
91         return(shabase64(h->osha));
92 }
93
94 /* hmacclose: de-allocates digest object */
95 int hmacclose(HMAC *h)
96 {
97         if (h != NULL) {
98                 shaclose(h->osha);
99                 memset(h, 0, sizeof(HMAC));
100                 SHA_free(h);
101         }
102         return(0);
103 }