mcabber/libjabber/sha.c
changeset 25 bf3d6e241714
child 414 ec86d759ed54
equal deleted inserted replaced
24:e88b15cbf2de 25:bf3d6e241714
       
     1 /* 
       
     2  * The contents of this file are subject to the Mozilla Public
       
     3  * License Version 1.1 (the "License"); you may not use this file
       
     4  * except in compliance with the License. You may obtain a copy of
       
     5  * the License at http://www.mozilla.org/MPL/
       
     6  * 
       
     7  * Software distributed under the License is distributed on an "AS
       
     8  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
       
     9  * implied. See the License for the specific language governing
       
    10  * rights and limitations under the License.
       
    11  * 
       
    12  * The Original Code is SHA 180-1 Reference Implementation (Compact version)
       
    13  * 
       
    14  * The Initial Developer of the Original Code is Paul Kocher of
       
    15  * Cryptography Research.  Portions created by Paul Kocher are 
       
    16  * Copyright (C) 1995-9 by Cryptography Research, Inc.  All
       
    17  * Rights Reserved.
       
    18  * 
       
    19  * Contributor(s):
       
    20  *
       
    21  *     Paul Kocher
       
    22  * 
       
    23  * Alternatively, the contents of this file may be used under the
       
    24  * terms of the GNU General Public License Version 2 or later (the
       
    25  * "GPL"), in which case the provisions of the GPL are applicable 
       
    26  * instead of those above.  If you wish to allow use of your 
       
    27  * version of this file only under the terms of the GPL and not to
       
    28  * allow others to use your version of this file under the MPL,
       
    29  * indicate your decision by deleting the provisions above and
       
    30  * replace them with the notice and other provisions required by
       
    31  * the GPL.  If you do not delete the provisions above, a recipient
       
    32  * may use your version of this file under either the MPL or the
       
    33  * GPL.
       
    34  */
       
    35 
       
    36 #include "libxode.h"
       
    37 
       
    38 static void shaHashBlock(SHA_CTX *ctx);
       
    39 
       
    40 void shaInit(SHA_CTX *ctx) {
       
    41   int i;
       
    42 
       
    43   ctx->lenW = 0;
       
    44   ctx->sizeHi = ctx->sizeLo = 0;
       
    45 
       
    46   /* Initialize H with the magic constants (see FIPS180 for constants)
       
    47    */
       
    48   ctx->H[0] = 0x67452301L;
       
    49   ctx->H[1] = 0xefcdab89L;
       
    50   ctx->H[2] = 0x98badcfeL;
       
    51   ctx->H[3] = 0x10325476L;
       
    52   ctx->H[4] = 0xc3d2e1f0L;
       
    53 
       
    54   for (i = 0; i < 80; i++)
       
    55     ctx->W[i] = 0;
       
    56 }
       
    57 
       
    58 
       
    59 void shaUpdate(SHA_CTX *ctx, unsigned char *dataIn, int len) {
       
    60   int i;
       
    61 
       
    62   /* Read the data into W and process blocks as they get full
       
    63    */
       
    64   for (i = 0; i < len; i++) {
       
    65     ctx->W[ctx->lenW / 4] <<= 8;
       
    66     ctx->W[ctx->lenW / 4] |= (uint32_t)dataIn[i];
       
    67     if ((++ctx->lenW) % 64 == 0) {
       
    68       shaHashBlock(ctx);
       
    69       ctx->lenW = 0;
       
    70     }
       
    71     ctx->sizeLo += 8;
       
    72     ctx->sizeHi += (ctx->sizeLo < 8);
       
    73   }
       
    74 }
       
    75 
       
    76 
       
    77 void shaFinal(SHA_CTX *ctx, unsigned char hashout[20]) {
       
    78   unsigned char pad0x80 = 0x80;
       
    79   unsigned char pad0x00 = 0x00;
       
    80   unsigned char padlen[8];
       
    81   int i;
       
    82 
       
    83   /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length
       
    84    */
       
    85   padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255);
       
    86   padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255);
       
    87   padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255);
       
    88   padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255);
       
    89   padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255);
       
    90   padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255);
       
    91   padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255);
       
    92   padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255);
       
    93   shaUpdate(ctx, &pad0x80, 1);
       
    94   while (ctx->lenW != 56)
       
    95     shaUpdate(ctx, &pad0x00, 1);
       
    96   shaUpdate(ctx, padlen, 8);
       
    97 
       
    98   /* Output hash
       
    99    */
       
   100   for (i = 0; i < 20; i++) {
       
   101     hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24);
       
   102     ctx->H[i / 4] <<= 8;
       
   103   }
       
   104 
       
   105   /*
       
   106    *  Re-initialize the context (also zeroizes contents)
       
   107    */
       
   108   shaInit(ctx);
       
   109 }
       
   110 
       
   111 
       
   112 void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]) {
       
   113   SHA_CTX ctx;
       
   114 
       
   115   shaInit(&ctx);
       
   116   shaUpdate(&ctx, dataIn, len);
       
   117   shaFinal(&ctx, hashout);
       
   118 }
       
   119 
       
   120 
       
   121 #define SHA_ROTL(X,n) (((X) << (n)) | ((X) >> (32-(n))))
       
   122 
       
   123 static void shaHashBlock(SHA_CTX *ctx) {
       
   124   int t;
       
   125   uint32_t A,B,C,D,E,TEMP;
       
   126 
       
   127   for (t = 16; t <= 79; t++)
       
   128     ctx->W[t] =
       
   129       SHA_ROTL(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1);
       
   130 
       
   131   A = ctx->H[0];
       
   132   B = ctx->H[1];
       
   133   C = ctx->H[2];
       
   134   D = ctx->H[3];
       
   135   E = ctx->H[4];
       
   136 
       
   137   for (t = 0; t <= 19; t++) {
       
   138     TEMP = SHA_ROTL(A,5) + (((C^D)&B)^D)     + E + ctx->W[t] + 0x5a827999L;
       
   139     E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
       
   140   }
       
   141   for (t = 20; t <= 39; t++) {
       
   142     TEMP = SHA_ROTL(A,5) + (B^C^D)           + E + ctx->W[t] + 0x6ed9eba1L;
       
   143     E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
       
   144   }
       
   145   for (t = 40; t <= 59; t++) {
       
   146     TEMP = SHA_ROTL(A,5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdcL;
       
   147     E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
       
   148   }
       
   149   for (t = 60; t <= 79; t++) {
       
   150     TEMP = SHA_ROTL(A,5) + (B^C^D)           + E + ctx->W[t] + 0xca62c1d6L;
       
   151     E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
       
   152   }
       
   153 
       
   154   ctx->H[0] += A;
       
   155   ctx->H[1] += B;
       
   156   ctx->H[2] += C;
       
   157   ctx->H[3] += D;
       
   158   ctx->H[4] += E;
       
   159 }
       
   160 
       
   161 /*----------------------------------------------------------------------------
       
   162  *
       
   163  * This code added by Thomas "temas" Muldowney for Jabber compatability
       
   164  *
       
   165  *---------------------------------------------------------------------------*/
       
   166 char *shahash(char *str)
       
   167 {
       
   168     static char final[41];
       
   169     char *pos;
       
   170     unsigned char hashval[20];
       
   171     int x;
       
   172 
       
   173     if(!str || strlen(str) == 0)
       
   174         return NULL;
       
   175 
       
   176     shaBlock((unsigned char *)str, strlen(str), hashval);
       
   177 
       
   178     pos = final;
       
   179     for(x=0;x<20;x++)
       
   180     {
       
   181         snprintf(pos, 3, "%02x", hashval[x]);
       
   182         pos += 2;
       
   183     }
       
   184     return (char *)final;
       
   185 }
       
   186 
       
   187 void shahash_r(const char* str, char hashbuf[41])
       
   188 {
       
   189     int x;
       
   190     char *pos;
       
   191     unsigned char hashval[20];
       
   192     
       
   193     if(!str || strlen(str) == 0)
       
   194         return;
       
   195 
       
   196     shaBlock((unsigned char *)str, strlen(str), hashval);
       
   197 
       
   198     pos = hashbuf;
       
   199     for(x=0;x<20;x++)
       
   200     {
       
   201         snprintf(pos, 3, "%02x", hashval[x]);
       
   202         pos += 2;
       
   203     }
       
   204 
       
   205     return;
       
   206 }