"Fossies" - the Fresh Open Source Software Archive

Member "Digest-SHA1-2.13/SHA1.xs" (3 Jul 2010, 17400 Bytes) of package /linux/privat/old/Digest-SHA1-2.13.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #ifdef __cplusplus
    2 extern "C" {
    3 #endif
    4 #define PERL_NO_GET_CONTEXT     /* we want efficiency */
    5 #include "EXTERN.h"
    6 #include "perl.h"
    7 #include "XSUB.h"
    8 #ifdef __cplusplus
    9 }
   10 #endif
   11 
   12 #ifndef PERL_VERSION
   13 #    include <patchlevel.h>
   14 #    if !(defined(PERL_VERSION) || (SUBVERSION > 0 && defined(PATCHLEVEL)))
   15 #        include <could_not_find_Perl_patchlevel.h>
   16 #    endif
   17 #    define PERL_REVISION       5
   18 #    define PERL_VERSION        PATCHLEVEL
   19 #    define PERL_SUBVERSION     SUBVERSION
   20 #endif
   21 
   22 #if PERL_VERSION <= 4 && !defined(PL_dowarn)
   23    #define PL_dowarn dowarn
   24 #endif
   25 
   26 #ifdef G_WARN_ON
   27    #define DOWARN (PL_dowarn & G_WARN_ON)
   28 #else
   29    #define DOWARN PL_dowarn
   30 #endif
   31 
   32 #ifdef SvPVbyte
   33    #if PERL_REVISION == 5 && PERL_VERSION < 7
   34        /* SvPVbyte does not work in perl-5.6.1, borrowed version for 5.7.3 */
   35        #undef SvPVbyte
   36        #define SvPVbyte(sv, lp) \
   37           ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \
   38            ? ((lp = SvCUR(sv)), SvPVX(sv)) : my_sv_2pvbyte(aTHX_ sv, &lp))
   39 
   40        static char *
   41        my_sv_2pvbyte(pTHX_ register SV *sv, STRLEN *lp)
   42        {
   43            sv_utf8_downgrade(sv,0);
   44            return SvPV(sv,*lp);
   45        }
   46    #endif
   47 #else
   48    #define SvPVbyte SvPV
   49 #endif
   50 
   51 #ifndef dTHX
   52    #define pTHX_
   53    #define aTHX_
   54 #endif
   55 
   56 /* NIST Secure Hash Algorithm */
   57 /* heavily modified by Uwe Hollerbach <uh@alumni.caltech edu> */
   58 /* from Peter C. Gutmann's implementation as found in */
   59 /* Applied Cryptography by Bruce Schneier */
   60 /* Further modifications to include the "UNRAVEL" stuff, below */
   61 
   62 /* This code is in the public domain */
   63 
   64 /* Useful defines & typedefs */
   65 
   66 #if defined(U64TYPE) && (defined(USE_64_BIT_INT) || ((BYTEORDER != 0x1234) && (BYTEORDER != 0x4321)))
   67 typedef U64TYPE ULONGx;
   68 # if BYTEORDER == 0x1234
   69 #   undef BYTEORDER
   70 #   define BYTEORDER 0x12345678
   71 # elif BYTEORDER == 0x4321
   72 #   undef BYTEORDER
   73 #   define BYTEORDER 0x87654321   
   74 # endif
   75 #else
   76 typedef unsigned long ULONGx;     /* 32-or-more-bit quantity */
   77 #endif
   78 
   79 #define SHA_BLOCKSIZE       64
   80 #define SHA_DIGESTSIZE      20
   81 
   82 typedef struct {
   83     ULONGx digest[5];       /* message digest */
   84     ULONGx count_lo, count_hi;  /* 64-bit bit count */
   85     U8 data[SHA_BLOCKSIZE]; /* SHA data buffer */
   86     int local;          /* unprocessed amount in data */
   87 } SHA_INFO;
   88 
   89 
   90 /* UNRAVEL should be fastest & biggest */
   91 /* UNROLL_LOOPS should be just as big, but slightly slower */
   92 /* both undefined should be smallest and slowest */
   93 
   94 #define SHA_VERSION 1
   95 #define UNRAVEL
   96 /* #define UNROLL_LOOPS */
   97 
   98 /* SHA f()-functions */
   99 #define f1(x,y,z)   ((x & y) | (~x & z))
  100 #define f2(x,y,z)   (x ^ y ^ z)
  101 #define f3(x,y,z)   ((x & y) | (x & z) | (y & z))
  102 #define f4(x,y,z)   (x ^ y ^ z)
  103 
  104 /* SHA constants */
  105 #define CONST1      0x5a827999L
  106 #define CONST2      0x6ed9eba1L
  107 #define CONST3      0x8f1bbcdcL
  108 #define CONST4      0xca62c1d6L
  109 
  110 /* truncate to 32 bits -- should be a null op on 32-bit machines */
  111 #define T32(x)  ((x) & 0xffffffffL)
  112 
  113 /* 32-bit rotate */
  114 #define R32(x,n)    T32(((x << n) | (x >> (32 - n))))
  115 
  116 /* the generic case, for when the overall rotation is not unraveled */
  117 #define FG(n)   \
  118     T = T32(R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n); \
  119     E = D; D = C; C = R32(B,30); B = A; A = T
  120 
  121 /* specific cases, for when the overall rotation is unraveled */
  122 #define FA(n)   \
  123     T = T32(R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n); B = R32(B,30)
  124 
  125 #define FB(n)   \
  126     E = T32(R32(T,5) + f##n(A,B,C) + D + *WP++ + CONST##n); A = R32(A,30)
  127 
  128 #define FC(n)   \
  129     D = T32(R32(E,5) + f##n(T,A,B) + C + *WP++ + CONST##n); T = R32(T,30)
  130 
  131 #define FD(n)   \
  132     C = T32(R32(D,5) + f##n(E,T,A) + B + *WP++ + CONST##n); E = R32(E,30)
  133 
  134 #define FE(n)   \
  135     B = T32(R32(C,5) + f##n(D,E,T) + A + *WP++ + CONST##n); D = R32(D,30)
  136 
  137 #define FT(n)   \
  138     A = T32(R32(B,5) + f##n(C,D,E) + T + *WP++ + CONST##n); C = R32(C,30)
  139 
  140 
  141 static void sha_transform(SHA_INFO *sha_info)
  142 {
  143     int i;
  144     U8 *dp;
  145     ULONGx T, A, B, C, D, E, W[80], *WP;
  146 
  147     dp = sha_info->data;
  148 
  149 /*
  150 the following makes sure that at least one code block below is
  151 traversed or an error is reported, without the necessity for nested
  152 preprocessor if/else/endif blocks, which are a great pain in the
  153 nether regions of the anatomy...
  154 */
  155 #undef SWAP_DONE
  156 
  157 #if BYTEORDER == 0x1234
  158 #define SWAP_DONE
  159     /* assert(sizeof(ULONGx) == 4); */
  160     for (i = 0; i < 16; ++i) {
  161     T = *((ULONGx *) dp);
  162     dp += 4;
  163     W[i] =  ((T << 24) & 0xff000000) | ((T <<  8) & 0x00ff0000) |
  164         ((T >>  8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
  165     }
  166 #endif
  167 
  168 #if BYTEORDER == 0x4321
  169 #define SWAP_DONE
  170     /* assert(sizeof(ULONGx) == 4); */
  171     for (i = 0; i < 16; ++i) {
  172     T = *((ULONGx *) dp);
  173     dp += 4;
  174     W[i] = T32(T);
  175     }
  176 #endif
  177 
  178 #if BYTEORDER == 0x12345678
  179 #define SWAP_DONE
  180     /* assert(sizeof(ULONGx) == 8); */
  181     for (i = 0; i < 16; i += 2) {
  182     T = *((ULONGx *) dp);
  183     dp += 8;
  184     W[i] =  ((T << 24) & 0xff000000) | ((T <<  8) & 0x00ff0000) |
  185         ((T >>  8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
  186     T >>= 32;
  187     W[i+1] = ((T << 24) & 0xff000000) | ((T <<  8) & 0x00ff0000) |
  188          ((T >>  8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
  189     }
  190 #endif
  191 
  192 #if BYTEORDER == 0x87654321
  193 #define SWAP_DONE
  194     /* assert(sizeof(ULONGx) == 8); */
  195     for (i = 0; i < 16; i += 2) {
  196     T = *((ULONGx *) dp);
  197     dp += 8;
  198     W[i] = T32(T >> 32);
  199     W[i+1] = T32(T);
  200     }
  201 #endif
  202 
  203 #ifndef SWAP_DONE
  204 #error Unknown byte order -- you need to add code here
  205 #endif /* SWAP_DONE */
  206 
  207     for (i = 16; i < 80; ++i) {
  208     W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
  209 #if (SHA_VERSION == 1)
  210     W[i] = R32(W[i], 1);
  211 #endif /* SHA_VERSION */
  212     }
  213     A = sha_info->digest[0];
  214     B = sha_info->digest[1];
  215     C = sha_info->digest[2];
  216     D = sha_info->digest[3];
  217     E = sha_info->digest[4];
  218     WP = W;
  219 #ifdef UNRAVEL
  220     FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1);
  221     FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1);
  222     FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2);
  223     FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2);
  224     FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3);
  225     FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3);
  226     FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4);
  227     FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4);
  228     sha_info->digest[0] = T32(sha_info->digest[0] + E);
  229     sha_info->digest[1] = T32(sha_info->digest[1] + T);
  230     sha_info->digest[2] = T32(sha_info->digest[2] + A);
  231     sha_info->digest[3] = T32(sha_info->digest[3] + B);
  232     sha_info->digest[4] = T32(sha_info->digest[4] + C);
  233 #else /* !UNRAVEL */
  234 #ifdef UNROLL_LOOPS
  235     FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
  236     FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
  237     FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
  238     FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
  239     FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
  240     FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
  241     FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
  242     FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
  243 #else /* !UNROLL_LOOPS */
  244     for (i =  0; i < 20; ++i) { FG(1); }
  245     for (i = 20; i < 40; ++i) { FG(2); }
  246     for (i = 40; i < 60; ++i) { FG(3); }
  247     for (i = 60; i < 80; ++i) { FG(4); }
  248 #endif /* !UNROLL_LOOPS */
  249     sha_info->digest[0] = T32(sha_info->digest[0] + A);
  250     sha_info->digest[1] = T32(sha_info->digest[1] + B);
  251     sha_info->digest[2] = T32(sha_info->digest[2] + C);
  252     sha_info->digest[3] = T32(sha_info->digest[3] + D);
  253     sha_info->digest[4] = T32(sha_info->digest[4] + E);
  254 #endif /* !UNRAVEL */
  255 }
  256 
  257 /* initialize the SHA digest */
  258 
  259 static void sha_init(SHA_INFO *sha_info)
  260 {
  261     sha_info->digest[0] = 0x67452301L;
  262     sha_info->digest[1] = 0xefcdab89L;
  263     sha_info->digest[2] = 0x98badcfeL;
  264     sha_info->digest[3] = 0x10325476L;
  265     sha_info->digest[4] = 0xc3d2e1f0L;
  266     sha_info->count_lo = 0L;
  267     sha_info->count_hi = 0L;
  268     sha_info->local = 0;
  269 }
  270 
  271 /* update the SHA digest */
  272 
  273 static void sha_update(SHA_INFO *sha_info, U8 *buffer, int count)
  274 {
  275     int i;
  276     ULONGx clo;
  277 
  278     clo = T32(sha_info->count_lo + ((ULONGx) count << 3));
  279     if (clo < sha_info->count_lo) {
  280     ++sha_info->count_hi;
  281     }
  282     sha_info->count_lo = clo;
  283     sha_info->count_hi += (ULONGx) count >> 29;
  284     if (sha_info->local) {
  285     i = SHA_BLOCKSIZE - sha_info->local;
  286     if (i > count) {
  287         i = count;
  288     }
  289     memcpy(((U8 *) sha_info->data) + sha_info->local, buffer, i);
  290     count -= i;
  291     buffer += i;
  292     sha_info->local += i;
  293     if (sha_info->local == SHA_BLOCKSIZE) {
  294         sha_transform(sha_info);
  295     } else {
  296         return;
  297     }
  298     }
  299     while (count >= SHA_BLOCKSIZE) {
  300     memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
  301     buffer += SHA_BLOCKSIZE;
  302     count -= SHA_BLOCKSIZE;
  303     sha_transform(sha_info);
  304     }
  305     memcpy(sha_info->data, buffer, count);
  306     sha_info->local = count;
  307 }
  308 
  309 
  310 static void sha_transform_and_copy(unsigned char digest[20], SHA_INFO *sha_info)
  311 {
  312     sha_transform(sha_info);
  313     digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
  314     digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
  315     digest[ 2] = (unsigned char) ((sha_info->digest[0] >>  8) & 0xff);
  316     digest[ 3] = (unsigned char) ((sha_info->digest[0]      ) & 0xff);
  317     digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
  318     digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
  319     digest[ 6] = (unsigned char) ((sha_info->digest[1] >>  8) & 0xff);
  320     digest[ 7] = (unsigned char) ((sha_info->digest[1]      ) & 0xff);
  321     digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
  322     digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
  323     digest[10] = (unsigned char) ((sha_info->digest[2] >>  8) & 0xff);
  324     digest[11] = (unsigned char) ((sha_info->digest[2]      ) & 0xff);
  325     digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
  326     digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
  327     digest[14] = (unsigned char) ((sha_info->digest[3] >>  8) & 0xff);
  328     digest[15] = (unsigned char) ((sha_info->digest[3]      ) & 0xff);
  329     digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
  330     digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
  331     digest[18] = (unsigned char) ((sha_info->digest[4] >>  8) & 0xff);
  332     digest[19] = (unsigned char) ((sha_info->digest[4]      ) & 0xff);
  333 }
  334 
  335 /* finish computing the SHA digest */
  336 static void sha_final(unsigned char digest[20], SHA_INFO *sha_info)
  337 {
  338     int count;
  339     ULONGx lo_bit_count, hi_bit_count;
  340 
  341     lo_bit_count = sha_info->count_lo;
  342     hi_bit_count = sha_info->count_hi;
  343     count = (int) ((lo_bit_count >> 3) & 0x3f);
  344     ((U8 *) sha_info->data)[count++] = 0x80;
  345     if (count > SHA_BLOCKSIZE - 8) {
  346     memset(((U8 *) sha_info->data) + count, 0, SHA_BLOCKSIZE - count);
  347     sha_transform(sha_info);
  348     memset((U8 *) sha_info->data, 0, SHA_BLOCKSIZE - 8);
  349     } else {
  350     memset(((U8 *) sha_info->data) + count, 0,
  351         SHA_BLOCKSIZE - 8 - count);
  352     }
  353     sha_info->data[56] = (U8)((hi_bit_count >> 24) & 0xff);
  354     sha_info->data[57] = (U8)((hi_bit_count >> 16) & 0xff);
  355     sha_info->data[58] = (U8)((hi_bit_count >>  8) & 0xff);
  356     sha_info->data[59] = (U8)((hi_bit_count >>  0) & 0xff);
  357     sha_info->data[60] = (U8)((lo_bit_count >> 24) & 0xff);
  358     sha_info->data[61] = (U8)((lo_bit_count >> 16) & 0xff);
  359     sha_info->data[62] = (U8)((lo_bit_count >>  8) & 0xff);
  360     sha_info->data[63] = (U8)((lo_bit_count >>  0) & 0xff);
  361     sha_transform_and_copy(digest, sha_info);
  362 }
  363 
  364 
  365 
  366 
  367 
  368 /*----------------------------------------------------------------*/
  369 #ifndef INT2PTR
  370 #define INT2PTR(any,d)  (any)(d)
  371 #endif
  372 
  373 static SHA_INFO* get_sha_info(pTHX_ SV* sv)
  374 {
  375     if (sv_derived_from(sv, "Digest::SHA1"))
  376     return INT2PTR(SHA_INFO*, SvIV(SvRV(sv)));
  377     croak("Not a reference to a Digest::SHA1 object");
  378     return (SHA_INFO*)0; /* some compilers insist on a return value */
  379 }
  380 
  381 
  382 static char* hex_20(const unsigned char* from, char* to)
  383 {
  384     static const char *hexdigits = "0123456789abcdef";
  385     const unsigned char *end = from + 20;
  386     char *d = to;
  387 
  388     while (from < end) {
  389     *d++ = hexdigits[(*from >> 4)];
  390     *d++ = hexdigits[(*from & 0x0F)];
  391     from++;
  392     }
  393     *d = '\0';
  394     return to;
  395 }
  396 
  397 static char* base64_20(const unsigned char* from, char* to)
  398 {
  399     static const char* base64 =
  400     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  401     const unsigned char *end = from + 20;
  402     unsigned char c1, c2, c3;
  403     char *d = to;
  404 
  405     while (1) {
  406     c1 = *from++;
  407     c2 = *from++;
  408     *d++ = base64[c1>>2];
  409     *d++ = base64[((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)];
  410     if (from == end) {
  411         *d++ = base64[(c2 & 0xF) << 2];
  412         break;
  413     }
  414     c3 = *from++;
  415     *d++ = base64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
  416     *d++ = base64[c3 & 0x3F];
  417     }
  418     *d = '\0';
  419     return to;
  420 }
  421 
  422 /* Formats */
  423 #define F_BIN 0
  424 #define F_HEX 1
  425 #define F_B64 2
  426 
  427 static SV* make_mortal_sv(pTHX_ const unsigned char *src, int type)
  428 {
  429     STRLEN len;
  430     char result[41];
  431     char *ret;
  432     
  433     switch (type) {
  434     case F_BIN:
  435     ret = (char*)src;
  436     len = 20;
  437     break;
  438     case F_HEX:
  439     ret = hex_20(src, result);
  440     len = 40;
  441     break;
  442     case F_B64:
  443     ret = base64_20(src, result);
  444     len = 27;
  445     break;
  446     default:
  447     croak("Bad convertion type (%d)", type);
  448     break;
  449     }
  450     return sv_2mortal(newSVpv(ret,len));
  451 }
  452 
  453 
  454 /********************************************************************/
  455 
  456 typedef PerlIO* InputStream;
  457 
  458 MODULE = Digest::SHA1       PACKAGE = Digest::SHA1
  459 
  460 PROTOTYPES: DISABLE
  461 
  462 void
  463 new(xclass)
  464     SV* xclass
  465     PREINIT:
  466     SHA_INFO* context;
  467     PPCODE:
  468     if (!SvROK(xclass)) {
  469         STRLEN my_na;
  470         char *sclass = SvPV(xclass, my_na);
  471         New(55, context, 1, SHA_INFO);
  472         ST(0) = sv_newmortal();
  473         sv_setref_pv(ST(0), sclass, (void*)context);
  474         SvREADONLY_on(SvRV(ST(0)));
  475     } else {
  476         context = get_sha_info(aTHX_ xclass);
  477     }
  478     sha_init(context);
  479     XSRETURN(1);
  480 
  481 void
  482 clone(self)
  483         SV* self
  484     PREINIT:
  485         SHA_INFO* cont = get_sha_info(aTHX_ self);
  486         const char *myname = sv_reftype(SvRV(self),TRUE);
  487         SHA_INFO* context;
  488     PPCODE:
  489         New(55, context, 1, SHA_INFO);
  490         ST(0) = sv_newmortal();
  491         sv_setref_pv(ST(0), myname , (void*)context);
  492         SvREADONLY_on(SvRV(ST(0)));
  493         memcpy(context,cont,sizeof(SHA_INFO));
  494         XSRETURN(1);
  495 
  496 void
  497 DESTROY(context)
  498     SHA_INFO* context
  499     CODE:
  500         Safefree(context);
  501 
  502 void
  503 add(self, ...)
  504     SV* self
  505     PREINIT:
  506     SHA_INFO* context = get_sha_info(aTHX_ self);
  507     int i;
  508     unsigned char *data;
  509     STRLEN len;
  510     PPCODE:
  511     for (i = 1; i < items; i++) {
  512         data = (unsigned char *)(SvPVbyte(ST(i), len));
  513         sha_update(context, data, len);
  514     }
  515     XSRETURN(1);  /* self */
  516 
  517 void
  518 addfile(self, fh)
  519     SV* self
  520     InputStream fh
  521     PREINIT:
  522     SHA_INFO* context = get_sha_info(aTHX_ self);
  523     unsigned char buffer[4096];
  524     int  n;
  525     CODE:
  526         if (fh) {
  527         /* Process blocks until EOF or error */
  528             while ( (n = PerlIO_read(fh, buffer, sizeof(buffer))) > 0) {
  529         sha_update(context, buffer, n);
  530         }
  531         if (PerlIO_error(fh)) {
  532         croak("Reading from filehandle failed");
  533         }
  534         }
  535         else {
  536         croak("No filehandle passed");
  537         }
  538  
  539     XSRETURN(1);  /* self */
  540 
  541 void
  542 digest(context)
  543     SHA_INFO* context
  544     ALIAS:
  545     Digest::SHA1::digest    = F_BIN
  546     Digest::SHA1::hexdigest = F_HEX
  547     Digest::SHA1::b64digest = F_B64
  548     PREINIT:
  549     unsigned char digeststr[20];
  550     PPCODE:
  551         sha_final(digeststr, context);
  552     sha_init(context);  /* In case it is reused */
  553         ST(0) = make_mortal_sv(aTHX_ digeststr, ix);
  554         XSRETURN(1);
  555 
  556 void
  557 sha1(...)
  558     ALIAS:
  559     Digest::SHA1::sha1        = F_BIN
  560     Digest::SHA1::sha1_hex    = F_HEX
  561     Digest::SHA1::sha1_base64 = F_B64
  562     PREINIT:
  563     SHA_INFO ctx;
  564     int i;
  565     unsigned char *data;
  566         STRLEN len;
  567     unsigned char digeststr[20];
  568     PPCODE:
  569     sha_init(&ctx);
  570 
  571     if (DOWARN) {
  572             const char *msg = 0;
  573         if (items == 1) {
  574         if (SvROK(ST(0))) {
  575                     SV* sv = SvRV(ST(0));
  576             if (SvOBJECT(sv) && strEQ(HvNAME(SvSTASH(sv)), "Digest::SHA1"))
  577                 msg = "probably called as method";
  578             else
  579             msg = "called with reference argument";
  580         }
  581         }
  582         else if (items > 1) {
  583         data = (unsigned char *)SvPVbyte(ST(0), len);
  584         if (len == 12 && memEQ("Digest::SHA1", data, 12)) {
  585             msg = "probably called as class method";
  586         }
  587         }
  588         if (msg) {
  589         const char *f = (ix == F_BIN) ? "sha1" :
  590                                 (ix == F_HEX) ? "sha1_hex" : "sha1_base64";
  591             warn("&Digest::SHA1::%s function %s", f, msg);
  592         }
  593     }
  594 
  595     for (i = 0; i < items; i++) {
  596         data = (unsigned char *)(SvPVbyte(ST(i), len));
  597         sha_update(&ctx, data, len);
  598     }
  599     sha_final(digeststr, &ctx);
  600         ST(0) = make_mortal_sv(aTHX_ digeststr, ix);
  601         XSRETURN(1);
  602 
  603 void
  604 sha1_transform(data)
  605     SV* data
  606     PREINIT:
  607         SHA_INFO ctx;
  608         unsigned char *data_pv;
  609         unsigned char test[64];
  610         STRLEN len;
  611         unsigned char digeststr[20];
  612     PPCODE:
  613         sha_init(&ctx);
  614         
  615         memset (test, 0, 64);
  616         data_pv = (unsigned char *)(SvPVbyte(data, len));
  617         memcpy (test, data_pv, len);
  618     memcpy ((&ctx)->data, test, 64);
  619         sha_transform_and_copy(digeststr, &ctx);
  620         ST(0) = sv_2mortal(newSVpv((char*)digeststr, 20));
  621         XSRETURN(1);
  622