"Fossies" - the Fresh Open Source Software Archive

Member "zebedee-2.5.3/sha_func.c" (12 Apr 2001, 7422 Bytes) of package /linux/privat/old/zebedee-2.5.3.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. For more information about "sha_func.c" see the Fossies "Dox" file reference documentation.

    1 /* NIST Secure Hash Algorithm */
    2 /* heavily modified by Uwe Hollerbach <uh@alumni.caltech edu> */
    3 /* from Peter C. Gutmann's implementation as found in */
    4 /* Applied Cryptography by Bruce Schneier */
    5 /* Further modifications to include the "UNRAVEL" stuff, below */
    6 
    7 /* This code is in the public domain */
    8 
    9 /* Modifications to dynamically determine endianness by Neil Winton */
   10 /* $Id: sha_func.c,v 1.1.1.1 2001/04/12 18:07:04 ndwinton Exp $ */
   11 
   12 #include <string.h>
   13 #include "sha.h"
   14 
   15 /* UNRAVEL should be fastest & biggest */
   16 /* UNROLL_LOOPS should be just as big, but slightly slower */
   17 /* both undefined should be smallest and slowest */
   18 
   19 #define UNRAVEL
   20 /* #define UNROLL_LOOPS */
   21 
   22 /* NIST's proposed modification to SHA of 7/11/94 may be */
   23 /* activated by defining USE_MODIFIED_SHA; leave it off for now */
   24 #undef USE_MODIFIED_SHA
   25 
   26 /* SHA f()-functions */
   27 
   28 #define f1(x,y,z)   ((x & y) | (~x & z))
   29 #define f2(x,y,z)   (x ^ y ^ z)
   30 #define f3(x,y,z)   ((x & y) | (x & z) | (y & z))
   31 #define f4(x,y,z)   (x ^ y ^ z)
   32 
   33 /* SHA constants */
   34 
   35 #define CONST1      0x5a827999L
   36 #define CONST2      0x6ed9eba1L
   37 #define CONST3      0x8f1bbcdcL
   38 #define CONST4      0xca62c1d6L
   39 
   40 /* 32-bit rotate */
   41 
   42 #define ROT32(x,n)  ((x << n) | (x >> (32 - n)))
   43 
   44 /* the generic case, for when the overall rotation is not unraveled */
   45 
   46 #define FG(n)   \
   47     T = ROT32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n;    \
   48     E = D; D = C; C = ROT32(B,30); B = A; A = T
   49 
   50 /* specific cases, for when the overall rotation is unraveled */
   51 
   52 #define FA(n)   \
   53     T = ROT32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n; B = ROT32(B,30)
   54 
   55 #define FB(n)   \
   56     E = ROT32(T,5) + f##n(A,B,C) + D + *WP++ + CONST##n; A = ROT32(A,30)
   57 
   58 #define FC(n)   \
   59     D = ROT32(E,5) + f##n(T,A,B) + C + *WP++ + CONST##n; T = ROT32(T,30)
   60 
   61 #define FD(n)   \
   62     C = ROT32(D,5) + f##n(E,T,A) + B + *WP++ + CONST##n; E = ROT32(E,30)
   63 
   64 #define FE(n)   \
   65     B = ROT32(C,5) + f##n(D,E,T) + A + *WP++ + CONST##n; D = ROT32(D,30)
   66 
   67 #define FT(n)   \
   68     A = ROT32(B,5) + f##n(C,D,E) + T + *WP++ + CONST##n; C = ROT32(C,30)
   69 
   70 /* do SHA transformation */
   71 
   72 static void sha_transform(SHA_INFO *sha_info)
   73 {
   74     int i;
   75     SHA_LONG T, A, B, C, D, E, W[80], *WP;
   76 
   77     for (i = 0; i < 16; ++i) {
   78     W[i] = sha_info->data[i];
   79     }
   80     for (i = 16; i < 80; ++i) {
   81     W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
   82 #ifdef USE_MODIFIED_SHA
   83     W[i] = ROT32(W[i], 1);
   84 #endif /* USE_MODIFIED_SHA */
   85     }
   86     A = sha_info->digest[0];
   87     B = sha_info->digest[1];
   88     C = sha_info->digest[2];
   89     D = sha_info->digest[3];
   90     E = sha_info->digest[4];
   91     WP = W;
   92 #ifdef UNRAVEL
   93     FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1);
   94     FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1);
   95     FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2);
   96     FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2);
   97     FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3);
   98     FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3);
   99     FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4);
  100     FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4);
  101     sha_info->digest[0] += E;
  102     sha_info->digest[1] += T;
  103     sha_info->digest[2] += A;
  104     sha_info->digest[3] += B;
  105     sha_info->digest[4] += C;
  106 #else /* !UNRAVEL */
  107 #ifdef UNROLL_LOOPS
  108     FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
  109     FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
  110     FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
  111     FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
  112     FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
  113     FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
  114     FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
  115     FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
  116 #else /* !UNROLL_LOOPS */
  117     for (i =  0; i < 20; ++i) { FG(1); }
  118     for (i = 20; i < 40; ++i) { FG(2); }
  119     for (i = 40; i < 60; ++i) { FG(3); }
  120     for (i = 60; i < 80; ++i) { FG(4); }
  121 #endif /* !UNROLL_LOOPS */
  122     sha_info->digest[0] += A;
  123     sha_info->digest[1] += B;
  124     sha_info->digest[2] += C;
  125     sha_info->digest[3] += D;
  126     sha_info->digest[4] += E;
  127 #endif /* !UNRAVEL */
  128 }
  129 
  130 /* change endianness of data if necessary */
  131 
  132 static void maybe_byte_reverse(SHA_LONG *buffer, int count)
  133 {
  134     static int initialized = 0;
  135     static int is_little_endian = 0;
  136     int i;
  137     SHA_LONG in;
  138 
  139     if (!initialized)
  140     {
  141     union {
  142         unsigned char bytes[4];
  143         SHA_LONG integer;
  144     } u;
  145 
  146     /*
  147     ** First call -- figure out endianness.
  148     **
  149     ** In theory we ought to worry about thread safety but in practice
  150     ** even if two threads come in here simultaneously the worst
  151     ** that will happen is that they will both end up figuring out
  152     ** the endianness and will come to the same answer!
  153     */
  154 
  155     initialized++;
  156 
  157     u.integer = 0x12345678;
  158 
  159     is_little_endian = (u.bytes[0] == 0x78);
  160     }
  161 
  162     if (is_little_endian) {
  163     count /= sizeof(SHA_LONG);
  164     for (i = 0; i < count; ++i) {
  165         in = *buffer;
  166         *buffer++ = ((in << 24) & 0xff000000) | ((in <<  8) & 0x00ff0000) |
  167             ((in >>  8) & 0x0000ff00) | ((in >> 24) & 0x000000ff);
  168     }
  169     }
  170 }
  171 
  172 /* initialize the SHA digest */
  173 
  174 void sha_init(SHA_INFO *sha_info)
  175 {
  176     sha_info->digest[0] = 0x67452301L;
  177     sha_info->digest[1] = 0xefcdab89L;
  178     sha_info->digest[2] = 0x98badcfeL;
  179     sha_info->digest[3] = 0x10325476L;
  180     sha_info->digest[4] = 0xc3d2e1f0L;
  181     sha_info->count_lo = 0L;
  182     sha_info->count_hi = 0L;
  183     sha_info->local = 0;
  184 }
  185 
  186 /* update the SHA digest */
  187 
  188 void sha_update(SHA_INFO *sha_info, SHA_BYTE *buffer, int count)
  189 {
  190     int i;
  191 
  192     if ((sha_info->count_lo + ((SHA_LONG) count << 3)) < sha_info->count_lo) {
  193     ++sha_info->count_hi;
  194     }
  195     sha_info->count_lo += (SHA_LONG) count << 3;
  196     sha_info->count_hi += (SHA_LONG) count >> 29;
  197     if (sha_info->local) {
  198     i = SHA_BLOCKSIZE - sha_info->local;
  199     if (i > count) {
  200         i = count;
  201     }
  202     memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i);
  203     count -= i;
  204     buffer += i;
  205     sha_info->local += i;
  206     if (sha_info->local == SHA_BLOCKSIZE) {
  207         maybe_byte_reverse(sha_info->data, SHA_BLOCKSIZE);
  208         sha_transform(sha_info);
  209     } else {
  210         return;
  211     }
  212     }
  213     while (count >= SHA_BLOCKSIZE) {
  214     memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
  215     buffer += SHA_BLOCKSIZE;
  216     count -= SHA_BLOCKSIZE;
  217     maybe_byte_reverse(sha_info->data, SHA_BLOCKSIZE);
  218     sha_transform(sha_info);
  219     }
  220     memcpy(sha_info->data, buffer, count);
  221     sha_info->local = count;
  222 }
  223 
  224 /* finish computing the SHA digest */
  225 
  226 void sha_final(SHA_INFO *sha_info)
  227 {
  228     int count;
  229     SHA_LONG lo_bit_count, hi_bit_count;
  230 
  231     lo_bit_count = sha_info->count_lo;
  232     hi_bit_count = sha_info->count_hi;
  233     count = (int) ((lo_bit_count >> 3) & 0x3f);
  234     ((SHA_BYTE *) sha_info->data)[count++] = 0x80;
  235     if (count > SHA_BLOCKSIZE - 8) {
  236     memset(((SHA_BYTE *) sha_info->data) + count, 0, SHA_BLOCKSIZE - count);
  237     maybe_byte_reverse(sha_info->data, SHA_BLOCKSIZE);
  238     sha_transform(sha_info);
  239     memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 8);
  240     } else {
  241     memset(((SHA_BYTE *) sha_info->data) + count, 0,
  242         SHA_BLOCKSIZE - 8 - count);
  243     }
  244     maybe_byte_reverse(sha_info->data, SHA_BLOCKSIZE);
  245     sha_info->data[14] = hi_bit_count;
  246     sha_info->data[15] = lo_bit_count;
  247     sha_transform(sha_info);
  248 }