This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
95d5c396ba8a5ddc7172d899e7f1ddc8910bda63
[perl5.git] / ext / 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-2006 Mark Shelor, All Rights Reserved
7  *
8  * Version: 5.43
9  * Sat Aug  5 02:36:18 MST 2006
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(alg, key, keylen)
21 int alg;
22 unsigned char *key;
23 unsigned int keylen;
24 {
25         unsigned int i;
26         HMAC *h;
27
28         SHA_newz(0, h, 1, HMAC);
29         if (h == NULL)
30                 return(NULL);
31         if ((h->isha = shaopen(alg)) == NULL) {
32                 SHA_free(h);
33                 return(NULL);
34         }
35         if ((h->osha = shaopen(alg)) == NULL) {
36                 shaclose(h->isha);
37                 SHA_free(h);
38                 return(NULL);
39         }
40         if (keylen <= h->osha->blocksize / 8)
41                 memcpy(h->key, key, keylen);
42         else {
43                 if ((h->ksha = shaopen(alg)) == NULL) {
44                         shaclose(h->isha);
45                         shaclose(h->osha);
46                         SHA_free(h);
47                         return(NULL);
48                 }
49                 shawrite(key, keylen * 8, h->ksha);
50                 shafinish(h->ksha);
51                 memcpy(h->key, shadigest(h->ksha), h->ksha->digestlen);
52                 shaclose(h->ksha);
53         }
54         for (i = 0; i < h->osha->blocksize / 8; i++)
55                 h->key[i] ^= 0x5c;
56         shawrite(h->key, h->osha->blocksize, h->osha);
57         for (i = 0; i < h->isha->blocksize / 8; i++)
58                 h->key[i] ^= (0x5c ^ 0x36);
59         shawrite(h->key, h->isha->blocksize, h->isha);
60         memset(h->key, 0, sizeof(h->key));
61         return(h);
62 }
63
64 /* hmacwrite: triggers a state update using data in bitstr/bitcnt */
65 unsigned long hmacwrite(bitstr, bitcnt, h)
66 unsigned char *bitstr;
67 unsigned long bitcnt;
68 HMAC *h;
69 {
70         return(shawrite(bitstr, bitcnt, h->isha));
71 }
72
73 /* hmacfinish: computes final digest state */
74 void hmacfinish(h)
75 HMAC *h;
76 {
77         shafinish(h->isha);
78         shawrite(shadigest(h->isha), h->isha->digestlen * 8, h->osha);
79         shaclose(h->isha);
80         shafinish(h->osha);
81 }
82
83 /* hmacdigest: returns pointer to digest (binary) */
84 unsigned char *hmacdigest(h)
85 HMAC *h;
86 {
87         return(shadigest(h->osha));
88 }
89
90 /* hmachex: returns pointer to digest (hexadecimal) */
91 char *hmachex(h)
92 HMAC *h;
93 {
94         return(shahex(h->osha));
95 }
96
97 /* hmacbase64: returns pointer to digest (Base 64) */
98 char *hmacbase64(h)
99 HMAC *h;
100 {
101         return(shabase64(h->osha));
102 }
103
104 /* hmacclose: de-allocates digest object */
105 int hmacclose(h)
106 HMAC *h;
107 {
108         shaclose(h->osha);
109         memset(h, 0, sizeof(HMAC));
110         SHA_free(h);
111         return(0);
112 }