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