1 #define PERL_NO_GET_CONTEXT 2 #include "EXTERN.h" 3 #include "perl.h" 4 #include "XSUB.h" 5 6 #ifdef SvPVbyte 7 #if PERL_REVISION == 5 && PERL_VERSION < 8 8 #undef SvPVbyte 9 #define SvPVbyte(sv, lp) \ 10 (sv_utf8_downgrade((sv), 0), SvPV((sv), (lp))) 11 #endif 12 #else 13 #define SvPVbyte SvPV 14 #endif 15 16 #ifndef dTHX 17 #define pTHX_ 18 #define aTHX_ 19 #endif 20 21 #ifndef PerlIO 22 #define PerlIO FILE 23 #define PerlIO_read(f, buf, count) fread(buf, 1, count, f) 24 #endif 25 26 #ifndef sv_derived_from 27 #include "src/sdf.c" 28 #endif 29 30 #ifndef Newx 31 #define Newx(ptr, num, type) New(0, ptr, num, type) 32 #define Newxz(ptr, num, type) Newz(0, ptr, num, type) 33 #endif 34 35 #include "src/sha.c" 36 37 static const int ix2alg[] = 38 {1,1,1,224,224,224,256,256,256,384,384,384,512,512,512, 39 512224,512224,512224,512256,512256,512256}; 40 41 #ifndef INT2PTR 42 #define INT2PTR(p, i) (p) (i) 43 #endif 44 45 #define MAX_WRITE_SIZE 16384 46 #define IO_BUFFER_SIZE 4096 47 48 static SHA *getSHA(pTHX_ SV *self) 49 { 50 if (!sv_isobject(self) || !sv_derived_from(self, "Digest::SHA")) 51 return(NULL); 52 return INT2PTR(SHA *, SvIV(SvRV(self))); 53 } 54 55 MODULE = Digest::SHA PACKAGE = Digest::SHA 56 57 PROTOTYPES: ENABLE 58 59 int 60 shainit(s, alg) 61 SHA * s 62 int alg 63 64 void 65 sharewind(s) 66 SHA * s 67 68 unsigned long 69 shawrite(bitstr, bitcnt, s) 70 unsigned char * bitstr 71 unsigned long bitcnt 72 SHA * s 73 74 SV * 75 newSHA(classname, alg) 76 char * classname 77 int alg 78 PREINIT: 79 SHA *state; 80 CODE: 81 Newxz(state, 1, SHA); 82 if (!shainit(state, alg)) { 83 Safefree(state); 84 XSRETURN_UNDEF; 85 } 86 RETVAL = newSV(0); 87 sv_setref_pv(RETVAL, classname, (void *) state); 88 SvREADONLY_on(SvRV(RETVAL)); 89 OUTPUT: 90 RETVAL 91 92 SV * 93 clone(self) 94 SV * self 95 PREINIT: 96 SHA *state; 97 SHA *clone; 98 CODE: 99 if ((state = getSHA(aTHX_ self)) == NULL) 100 XSRETURN_UNDEF; 101 Newx(clone, 1, SHA); 102 RETVAL = newSV(0); 103 sv_setref_pv(RETVAL, sv_reftype(SvRV(self), 1), (void *) clone); 104 SvREADONLY_on(SvRV(RETVAL)); 105 Copy(state, clone, 1, SHA); 106 OUTPUT: 107 RETVAL 108 109 void 110 DESTROY(s) 111 SHA * s 112 CODE: 113 Safefree(s); 114 115 SV * 116 sha1(...) 117 ALIAS: 118 Digest::SHA::sha1 = 0 119 Digest::SHA::sha1_hex = 1 120 Digest::SHA::sha1_base64 = 2 121 Digest::SHA::sha224 = 3 122 Digest::SHA::sha224_hex = 4 123 Digest::SHA::sha224_base64 = 5 124 Digest::SHA::sha256 = 6 125 Digest::SHA::sha256_hex = 7 126 Digest::SHA::sha256_base64 = 8 127 Digest::SHA::sha384 = 9 128 Digest::SHA::sha384_hex = 10 129 Digest::SHA::sha384_base64 = 11 130 Digest::SHA::sha512 = 12 131 Digest::SHA::sha512_hex = 13 132 Digest::SHA::sha512_base64 = 14 133 Digest::SHA::sha512224 = 15 134 Digest::SHA::sha512224_hex = 16 135 Digest::SHA::sha512224_base64 = 17 136 Digest::SHA::sha512256 = 18 137 Digest::SHA::sha512256_hex = 19 138 Digest::SHA::sha512256_base64 = 20 139 PREINIT: 140 int i; 141 UCHR *data; 142 STRLEN len; 143 SHA sha; 144 char *result; 145 CODE: 146 if (!shainit(&sha, ix2alg[ix])) 147 XSRETURN_UNDEF; 148 for (i = 0; i < items; i++) { 149 data = (UCHR *) (SvPVbyte(ST(i), len)); 150 while (len > MAX_WRITE_SIZE) { 151 shawrite(data, MAX_WRITE_SIZE << 3, &sha); 152 data += MAX_WRITE_SIZE; 153 len -= MAX_WRITE_SIZE; 154 } 155 shawrite(data, (ULNG) len << 3, &sha); 156 } 157 shafinish(&sha); 158 len = 0; 159 if (ix % 3 == 0) { 160 result = (char *) shadigest(&sha); 161 len = sha.digestlen; 162 } 163 else if (ix % 3 == 1) 164 result = shahex(&sha); 165 else 166 result = shabase64(&sha); 167 RETVAL = newSVpv(result, len); 168 OUTPUT: 169 RETVAL 170 171 SV * 172 hmac_sha1(...) 173 ALIAS: 174 Digest::SHA::hmac_sha1 = 0 175 Digest::SHA::hmac_sha1_hex = 1 176 Digest::SHA::hmac_sha1_base64 = 2 177 Digest::SHA::hmac_sha224 = 3 178 Digest::SHA::hmac_sha224_hex = 4 179 Digest::SHA::hmac_sha224_base64 = 5 180 Digest::SHA::hmac_sha256 = 6 181 Digest::SHA::hmac_sha256_hex = 7 182 Digest::SHA::hmac_sha256_base64 = 8 183 Digest::SHA::hmac_sha384 = 9 184 Digest::SHA::hmac_sha384_hex = 10 185 Digest::SHA::hmac_sha384_base64 = 11 186 Digest::SHA::hmac_sha512 = 12 187 Digest::SHA::hmac_sha512_hex = 13 188 Digest::SHA::hmac_sha512_base64 = 14 189 Digest::SHA::hmac_sha512224 = 15 190 Digest::SHA::hmac_sha512224_hex = 16 191 Digest::SHA::hmac_sha512224_base64 = 17 192 Digest::SHA::hmac_sha512256 = 18 193 Digest::SHA::hmac_sha512256_hex = 19 194 Digest::SHA::hmac_sha512256_base64 = 20 195 PREINIT: 196 int i; 197 UCHR *key = (UCHR *) ""; 198 UCHR *data; 199 STRLEN len = 0; 200 HMAC hmac; 201 char *result; 202 CODE: 203 if (items > 0) { 204 key = (UCHR *) (SvPVbyte(ST(items-1), len)); 205 } 206 if (hmacinit(&hmac, ix2alg[ix], key, (UINT) len) == NULL) 207 XSRETURN_UNDEF; 208 for (i = 0; i < items - 1; i++) { 209 data = (UCHR *) (SvPVbyte(ST(i), len)); 210 while (len > MAX_WRITE_SIZE) { 211 hmacwrite(data, MAX_WRITE_SIZE << 3, &hmac); 212 data += MAX_WRITE_SIZE; 213 len -= MAX_WRITE_SIZE; 214 } 215 hmacwrite(data, (ULNG) len << 3, &hmac); 216 } 217 hmacfinish(&hmac); 218 len = 0; 219 if (ix % 3 == 0) { 220 result = (char *) hmacdigest(&hmac); 221 len = hmac.digestlen; 222 } 223 else if (ix % 3 == 1) 224 result = hmachex(&hmac); 225 else 226 result = hmacbase64(&hmac); 227 RETVAL = newSVpv(result, len); 228 OUTPUT: 229 RETVAL 230 231 int 232 hashsize(self) 233 SV * self 234 ALIAS: 235 Digest::SHA::hashsize = 0 236 Digest::SHA::algorithm = 1 237 PREINIT: 238 SHA *state; 239 CODE: 240 if ((state = getSHA(aTHX_ self)) == NULL) 241 XSRETURN_UNDEF; 242 RETVAL = ix ? state->alg : (int) (state->digestlen << 3); 243 OUTPUT: 244 RETVAL 245 246 void 247 add(self, ...) 248 SV * self 249 PREINIT: 250 int i; 251 UCHR *data; 252 STRLEN len; 253 SHA *state; 254 PPCODE: 255 if ((state = getSHA(aTHX_ self)) == NULL) 256 XSRETURN_UNDEF; 257 for (i = 1; i < items; i++) { 258 data = (UCHR *) (SvPVbyte(ST(i), len)); 259 while (len > MAX_WRITE_SIZE) { 260 shawrite(data, MAX_WRITE_SIZE << 3, state); 261 data += MAX_WRITE_SIZE; 262 len -= MAX_WRITE_SIZE; 263 } 264 shawrite(data, (ULNG) len << 3, state); 265 } 266 XSRETURN(1); 267 268 SV * 269 digest(self) 270 SV * self 271 ALIAS: 272 Digest::SHA::digest = 0 273 Digest::SHA::hexdigest = 1 274 Digest::SHA::b64digest = 2 275 PREINIT: 276 STRLEN len; 277 SHA *state; 278 char *result; 279 CODE: 280 if ((state = getSHA(aTHX_ self)) == NULL) 281 XSRETURN_UNDEF; 282 shafinish(state); 283 len = 0; 284 if (ix == 0) { 285 result = (char *) shadigest(state); 286 len = state->digestlen; 287 } 288 else if (ix == 1) 289 result = shahex(state); 290 else 291 result = shabase64(state); 292 RETVAL = newSVpv(result, len); 293 sharewind(state); 294 OUTPUT: 295 RETVAL 296 297 SV * 298 _getstate(self) 299 SV * self 300 PREINIT: 301 SHA *state; 302 UCHR buf[256]; 303 UCHR *ptr = buf; 304 CODE: 305 if ((state = getSHA(aTHX_ self)) == NULL) 306 XSRETURN_UNDEF; 307 Copy(digcpy(state), ptr, state->alg <= SHA256 ? 32 : 64, UCHR); 308 ptr += state->alg <= SHA256 ? 32 : 64; 309 Copy(state->block, ptr, state->alg <= SHA256 ? 64 : 128, UCHR); 310 ptr += state->alg <= SHA256 ? 64 : 128; 311 ptr = w32mem(ptr, state->blockcnt); 312 ptr = w32mem(ptr, state->lenhh); 313 ptr = w32mem(ptr, state->lenhl); 314 ptr = w32mem(ptr, state->lenlh); 315 ptr = w32mem(ptr, state->lenll); 316 RETVAL = newSVpv((char *) buf, (STRLEN) (ptr - buf)); 317 OUTPUT: 318 RETVAL 319 320 void 321 _putstate(self, packed_state) 322 SV * self 323 SV * packed_state 324 PREINIT: 325 UINT bc; 326 STRLEN len; 327 SHA *state; 328 UCHR *data; 329 PPCODE: 330 if ((state = getSHA(aTHX_ self)) == NULL) 331 XSRETURN_UNDEF; 332 data = (UCHR *) SvPV(packed_state, len); 333 if (len != (state->alg <= SHA256 ? 116U : 212U)) 334 XSRETURN_UNDEF; 335 data = statecpy(state, data); 336 Copy(data, state->block, state->blocksize >> 3, UCHR); 337 data += (state->blocksize >> 3); 338 bc = memw32(data), data += 4; 339 if (bc >= (state->alg <= SHA256 ? 512U : 1024U)) 340 XSRETURN_UNDEF; 341 state->blockcnt = bc; 342 state->lenhh = memw32(data), data += 4; 343 state->lenhl = memw32(data), data += 4; 344 state->lenlh = memw32(data), data += 4; 345 state->lenll = memw32(data); 346 XSRETURN(1); 347 348 void 349 _addfilebin(self, f) 350 SV * self 351 PerlIO * f 352 PREINIT: 353 SHA *state; 354 int n; 355 UCHR in[IO_BUFFER_SIZE]; 356 PPCODE: 357 if (!f || (state = getSHA(aTHX_ self)) == NULL) 358 XSRETURN_UNDEF; 359 while ((n = (int) PerlIO_read(f, in, sizeof(in))) > 0) 360 shawrite(in, (ULNG) n << 3, state); 361 XSRETURN(1); 362 363 void 364 _addfileuniv(self, f) 365 SV * self 366 PerlIO * f 367 PREINIT: 368 UCHR c; 369 int n; 370 int cr = 0; 371 UCHR *src, *dst; 372 UCHR in[IO_BUFFER_SIZE+1]; 373 SHA *state; 374 PPCODE: 375 if (!f || (state = getSHA(aTHX_ self)) == NULL) 376 XSRETURN_UNDEF; 377 while ((n = (int) PerlIO_read(f, in+1, IO_BUFFER_SIZE)) > 0) { 378 for (dst = in, src = in + 1; n; n--) { 379 c = *src++; 380 if (!cr) { 381 if (c == '\015') 382 cr = 1; 383 else 384 *dst++ = c; 385 } 386 else { 387 if (c == '\015') 388 *dst++ = '\012'; 389 else if (c == '\012') { 390 *dst++ = '\012'; 391 cr = 0; 392 } 393 else { 394 *dst++ = '\012'; 395 *dst++ = c; 396 cr = 0; 397 } 398 } 399 } 400 shawrite(in, (ULNG) (dst - in) << 3, state); 401 } 402 if (cr) { 403 in[0] = '\012'; 404 shawrite(in, 1UL << 3, state); 405 } 406 XSRETURN(1); 407