This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Upgrade to Digest-SHA-5.44.
[perl5.git] / ext / Digest / SHA / SHA.xs
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #include <src/sha.c>
6 #include <src/hmac.c>
7
8 static int ix2alg[] =
9         {1,1,1,224,224,224,256,256,256,384,384,384,512,512,512};
10
11 MODULE = Digest::SHA            PACKAGE = Digest::SHA           
12
13 PROTOTYPES: ENABLE
14
15 #include <src/sha.h>
16 #include <src/hmac.h>
17
18 int
19 shaclose(s)
20         SHA *   s
21
22 int
23 shadump(file, s)
24         char *  file
25         SHA *   s
26
27 SHA *
28 shadup(s)
29         SHA *   s
30
31 SHA *
32 shaload(file)
33         char *  file
34
35 SHA *
36 shaopen(alg)
37         int     alg
38
39 void
40 sharewind(s)
41         SHA *   s
42
43 unsigned long
44 shawrite(bitstr, bitcnt, s)
45         unsigned char * bitstr
46         unsigned long   bitcnt
47         SHA *   s
48
49 void
50 sha1(...)
51 ALIAS:
52         Digest::SHA::sha1 = 0
53         Digest::SHA::sha1_hex = 1
54         Digest::SHA::sha1_base64 = 2
55         Digest::SHA::sha224 = 3
56         Digest::SHA::sha224_hex = 4
57         Digest::SHA::sha224_base64 = 5
58         Digest::SHA::sha256 = 6
59         Digest::SHA::sha256_hex = 7
60         Digest::SHA::sha256_base64 = 8
61         Digest::SHA::sha384 = 9
62         Digest::SHA::sha384_hex = 10
63         Digest::SHA::sha384_base64 = 11
64         Digest::SHA::sha512 = 12
65         Digest::SHA::sha512_hex = 13
66         Digest::SHA::sha512_base64 = 14
67 PREINIT:
68         int i;
69         unsigned char *data;
70         STRLEN len;
71         SHA *state;
72         char *result;
73 PPCODE:
74         if ((state = shaopen(ix2alg[ix])) == NULL)
75                 XSRETURN_UNDEF;
76         for (i = 0; i < items; i++) {
77                 data = (unsigned char *) (SvPV(ST(i), len));
78                 shawrite(data, len << 3, state);
79         }
80         shafinish(state);
81         len = 0;
82         if (ix % 3 == 0) {
83                 result = (char *) shadigest(state);
84                 len = shadsize(state);
85         }
86         else if (ix % 3 == 1)
87                 result = shahex(state);
88         else
89                 result = shabase64(state);
90         ST(0) = sv_2mortal(newSVpv(result, len));
91         shaclose(state);
92         XSRETURN(1);
93
94 void
95 hmac_sha1(...)
96 ALIAS:
97         Digest::SHA::hmac_sha1 = 0
98         Digest::SHA::hmac_sha1_hex = 1
99         Digest::SHA::hmac_sha1_base64 = 2
100         Digest::SHA::hmac_sha224 = 3
101         Digest::SHA::hmac_sha224_hex = 4
102         Digest::SHA::hmac_sha224_base64 = 5
103         Digest::SHA::hmac_sha256 = 6
104         Digest::SHA::hmac_sha256_hex = 7
105         Digest::SHA::hmac_sha256_base64 = 8
106         Digest::SHA::hmac_sha384 = 9
107         Digest::SHA::hmac_sha384_hex = 10
108         Digest::SHA::hmac_sha384_base64 = 11
109         Digest::SHA::hmac_sha512 = 12
110         Digest::SHA::hmac_sha512_hex = 13
111         Digest::SHA::hmac_sha512_base64 = 14
112 PREINIT:
113         int i;
114         unsigned char *key;
115         unsigned char *data;
116         STRLEN len;
117         HMAC *state;
118         char *result;
119 PPCODE:
120         key = (unsigned char *) (SvPV(ST(items-1), len));
121         if ((state = hmacopen(ix2alg[ix], key, len)) == NULL)
122                 XSRETURN_UNDEF;
123         for (i = 0; i < items - 1; i++) {
124                 data = (unsigned char *) (SvPV(ST(i), len));
125                 hmacwrite(data, len << 3, state);
126         }
127         hmacfinish(state);
128         len = 0;
129         if (ix % 3 == 0) {
130                 result = (char *) hmacdigest(state);
131                 len = shadsize(state->osha);
132         }
133         else if (ix % 3 == 1)
134                 result = hmachex(state);
135         else
136                 result = hmacbase64(state);
137         ST(0) = sv_2mortal(newSVpv(result, len));
138         hmacclose(state);
139         XSRETURN(1);
140
141 void
142 hashsize(self)
143         SV *    self
144 ALIAS:
145         Digest::SHA::hashsize = 0
146         Digest::SHA::algorithm = 1
147 PREINIT:
148         SHA *state;
149         int result;
150 PPCODE:
151         state = INT2PTR(SHA *, SvIV(SvRV(SvRV(self))));
152         result = shadsize(state) << 3;
153         if (ix == 1 && result == 160)
154                 result = 1;
155         ST(0) = sv_2mortal(newSViv(result));
156         XSRETURN(1);
157
158 void
159 add(self, ...)
160         SV *    self
161 PREINIT:
162         int i;
163         unsigned char *data;
164         STRLEN len;
165         SHA *state;
166 PPCODE:
167         state = INT2PTR(SHA *, SvIV(SvRV(SvRV(self))));
168         for (i = 1; i < items; i++) {
169                 data = (unsigned char *) (SvPV(ST(i), len));
170                 shawrite(data, len << 3, state);
171         }
172         XSRETURN(1);
173
174 void
175 digest(self)
176         SV *    self
177 ALIAS:
178         Digest::SHA::digest = 0
179         Digest::SHA::Hexdigest = 1
180         Digest::SHA::B64digest = 2
181 PREINIT:
182         STRLEN len;
183         SHA *state;
184         char *result;
185 PPCODE:
186         state = INT2PTR(SHA *, SvIV(SvRV(SvRV(self))));
187         shafinish(state);
188         len = 0;
189         if (ix == 0) {
190                 result = (char *) shadigest(state);
191                 len = shadsize(state);
192         }
193         else if (ix == 1)
194                 result = shahex(state);
195         else
196                 result = shabase64(state);
197         ST(0) = sv_2mortal(newSVpv(result, len));
198         sharewind(state);
199         XSRETURN(1);