"Fossies" - the Fresh Open Source Software Archive

Member "unrar/sha1.cpp" (4 May 2022, 6323 Bytes) of package /linux/misc/unrarsrc-6.1.7.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 "sha1.cpp" see the Fossies "Dox" file reference documentation.

    1 #include "rar.hpp"
    2 
    3 /*
    4 SHA-1 in C
    5 By Steve Reid <steve@edmweb.com>
    6 100% Public Domain
    7 */
    8 
    9 #ifndef SFX_MODULE
   10 #define SHA1_UNROLL
   11 #endif
   12 
   13 /* blk0() and blk() perform the initial expand. */
   14 /* I got the idea of expanding during the round function from SSLeay */
   15 #ifdef LITTLE_ENDIAN
   16 #define blk0(i) (block->l[i] = ByteSwap32(block->l[i]))
   17 #else
   18 #define blk0(i) block->l[i]
   19 #endif
   20 #define blk(i) (block->l[i&15] = rotl32(block->l[(i+13)&15]^block->l[(i+8)&15] \
   21     ^block->l[(i+2)&15]^block->l[i&15],1))
   22 
   23 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
   24 #define R0(v,w,x,y,z,i) {z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rotl32(v,5);w=rotl32(w,30);}
   25 #define R1(v,w,x,y,z,i) {z+=((w&(x^y))^y)+blk(i)+0x5A827999+rotl32(v,5);w=rotl32(w,30);}
   26 #define R2(v,w,x,y,z,i) {z+=(w^x^y)+blk(i)+0x6ED9EBA1+rotl32(v,5);w=rotl32(w,30);}
   27 #define R3(v,w,x,y,z,i) {z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rotl32(v,5);w=rotl32(w,30);}
   28 #define R4(v,w,x,y,z,i) {z+=(w^x^y)+blk(i)+0xCA62C1D6+rotl32(v,5);w=rotl32(w,30);}
   29 
   30 /* Hash a single 512-bit block. This is the core of the algorithm. */
   31 void SHA1Transform(uint32 state[5], uint32 workspace[16], const byte buffer[64], bool inplace)
   32 {
   33   uint32 a, b, c, d, e;
   34 
   35   union CHAR64LONG16
   36   {
   37     unsigned char c[64];
   38     uint32 l[16];
   39   } *block;
   40 
   41   if (inplace)
   42     block = (CHAR64LONG16*)buffer;
   43   else
   44   {
   45     block = (CHAR64LONG16*)workspace;
   46     memcpy(block, buffer, 64);
   47   }
   48 
   49   /* Copy context->state[] to working vars */
   50   a = state[0];
   51   b = state[1];
   52   c = state[2];
   53   d = state[3];
   54   e = state[4];
   55 
   56 #ifdef SHA1_UNROLL
   57   /* 4 rounds of 20 operations each. Loop unrolled. */
   58   R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
   59   R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
   60   R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
   61   R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
   62   R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
   63   R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
   64   R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
   65   R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
   66   R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
   67   R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
   68   R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
   69   R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
   70   R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
   71   R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
   72   R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
   73   R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
   74   R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
   75   R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
   76   R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
   77   R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
   78 #else
   79   for (uint I=0;;I+=5)
   80   {
   81     R0(a,b,c,d,e, I+0); if (I==15) break;
   82     R0(e,a,b,c,d, I+1); R0(d,e,a,b,c, I+2);
   83     R0(c,d,e,a,b, I+3); R0(b,c,d,e,a, I+4);
   84   }
   85   R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
   86   for (uint I=20;I<=35;I+=5)
   87   {
   88     R2(a,b,c,d,e,I+0); R2(e,a,b,c,d,I+1); R2(d,e,a,b,c,I+2);
   89     R2(c,d,e,a,b,I+3); R2(b,c,d,e,a,I+4);
   90   }
   91   for (uint I=40;I<=55;I+=5)
   92   {
   93     R3(a,b,c,d,e,I+0); R3(e,a,b,c,d,I+1); R3(d,e,a,b,c,I+2);
   94     R3(c,d,e,a,b,I+3); R3(b,c,d,e,a,I+4);
   95   }
   96   for (uint I=60;I<=75;I+=5)
   97   {
   98     R4(a,b,c,d,e,I+0); R4(e,a,b,c,d,I+1); R4(d,e,a,b,c,I+2);
   99     R4(c,d,e,a,b,I+3); R4(b,c,d,e,a,I+4);
  100   }
  101 #endif
  102   /* Add the working vars back into context.state[] */
  103   state[0] += a;
  104   state[1] += b;
  105   state[2] += c;
  106   state[3] += d;
  107   state[4] += e;
  108 }
  109 
  110 
  111 /* Initialize new context */
  112 void sha1_init(sha1_context* context)
  113 {
  114   context->count = 0;
  115   /* SHA1 initialization constants */
  116   context->state[0] = 0x67452301;
  117   context->state[1] = 0xEFCDAB89;
  118   context->state[2] = 0x98BADCFE;
  119   context->state[3] = 0x10325476;
  120   context->state[4] = 0xC3D2E1F0;
  121 }
  122 
  123 
  124 /* Run your data through this. */
  125 void sha1_process( sha1_context * context, const unsigned char * data, size_t len)
  126 {
  127   size_t i, j = (size_t)(context->count & 63);
  128   context->count += len;
  129 
  130   if ((j + len) > 63)
  131   {
  132     memcpy(context->buffer+j, data, (i = 64-j));
  133     uint32 workspace[16];
  134     SHA1Transform(context->state, workspace, context->buffer, true);
  135     for ( ; i + 63 < len; i += 64)
  136       SHA1Transform(context->state, workspace, data+i, false);
  137     j = 0;
  138   }
  139   else
  140     i = 0;
  141   if (len > i)
  142     memcpy(context->buffer+j, data+i, len - i);
  143 }
  144 
  145 
  146 void sha1_process_rar29(sha1_context *context, const unsigned char *data, size_t len)
  147 {
  148   size_t i, j = (size_t)(context->count & 63);
  149   context->count += len;
  150 
  151   if ((j + len) > 63)
  152   {
  153     memcpy(context->buffer+j, data, (i = 64-j));
  154     uint32 workspace[16];
  155     SHA1Transform(context->state, workspace, context->buffer, true);
  156     for ( ; i + 63 < len; i += 64)
  157     {
  158       SHA1Transform(context->state, workspace, data+i, false);
  159       for (uint k = 0; k < 16; k++)
  160         RawPut4(workspace[k],(void*)(data+i+k*4));
  161     }
  162     j = 0;
  163   }
  164   else
  165     i = 0;
  166   if (len > i)
  167     memcpy(context->buffer+j, data+i, len - i);
  168 }
  169 
  170 
  171 /* Add padding and return the message digest. */
  172 void sha1_done( sha1_context* context, uint32 digest[5])
  173 {
  174   uint32 workspace[16];
  175   uint64 BitLength = context->count * 8;
  176   uint BufPos = (uint)context->count & 0x3f;
  177   context->buffer[BufPos++] = 0x80; // Padding the message with "1" bit.
  178 
  179   if (BufPos!=56) // We need 56 bytes block followed by 8 byte length.
  180   {
  181     if (BufPos>56)
  182     {
  183       while (BufPos<64)
  184         context->buffer[BufPos++] = 0;
  185       BufPos=0;
  186     }
  187     if (BufPos==0)
  188       SHA1Transform(context->state, workspace, context->buffer, true);
  189     memset(context->buffer+BufPos,0,56-BufPos);
  190   }
  191 
  192   RawPutBE4((uint32)(BitLength>>32), context->buffer + 56);
  193   RawPutBE4((uint32)(BitLength), context->buffer + 60);
  194 
  195   SHA1Transform(context->state, workspace, context->buffer, true);
  196 
  197   for (uint i = 0; i < 5; i++)
  198     digest[i] = context->state[i];
  199 
  200   /* Wipe variables */
  201   sha1_init(context);
  202 }
  203 
  204