Home | History | Annotate | Download | only in axtls
      1 /*
      2  *  Copyright(C) 2006 Cameron Rich
      3  *
      4  *  This library is free software; you can redistribute it and/or modify
      5  *  it under the terms of the GNU Lesser General Public License as published by
      6  *  the Free Software Foundation; either version 2.1 of the License, or
      7  *  (at your option) any later version.
      8  *
      9  *  This library is distributed in the hope that it will be useful,
     10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12  *  GNU Lesser General Public License for more details.
     13  *
     14  *  You should have received a copy of the GNU Lesser General Public License
     15  *  along with this library; if not, write to the Free Software
     16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     17  */
     18 
     19 /**
     20  * SHA1 implementation - as defined in FIPS PUB 180-1 published April 17, 1995.
     21  * This code was originally taken from RFC3174
     22  */
     23 
     24 #include <string.h>
     25 #include "crypto.h"
     26 
     27 /*
     28  *  Define the SHA1 circular left shift macro
     29  */
     30 #define SHA1CircularShift(bits,word) \
     31                 (((word) << (bits)) | ((word) >> (32-(bits))))
     32 
     33 /* ----- static functions ----- */
     34 static void SHA1PadMessage(SHA1_CTX *ctx);
     35 static void SHA1ProcessMessageBlock(SHA1_CTX *ctx);
     36 
     37 /**
     38  * Initialize the SHA1 context
     39  */
     40 void SHA1Init(SHA1_CTX *ctx)
     41 {
     42     ctx->Length_Low             = 0;
     43     ctx->Length_High            = 0;
     44     ctx->Message_Block_Index    = 0;
     45     ctx->Intermediate_Hash[0]   = 0x67452301;
     46     ctx->Intermediate_Hash[1]   = 0xEFCDAB89;
     47     ctx->Intermediate_Hash[2]   = 0x98BADCFE;
     48     ctx->Intermediate_Hash[3]   = 0x10325476;
     49     ctx->Intermediate_Hash[4]   = 0xC3D2E1F0;
     50 }
     51 
     52 /**
     53  * Accepts an array of octets as the next portion of the message.
     54  */
     55 void SHA1Update(SHA1_CTX *ctx, const uint8_t *msg, int len)
     56 {
     57     while (len--)
     58     {
     59         ctx->Message_Block[ctx->Message_Block_Index++] = (*msg & 0xFF);
     60 
     61         ctx->Length_Low += 8;
     62         if (ctx->Length_Low == 0)
     63         {
     64             ctx->Length_High++;
     65         }
     66 
     67         if (ctx->Message_Block_Index == 64)
     68         {
     69             SHA1ProcessMessageBlock(ctx);
     70         }
     71 
     72         msg++;
     73     }
     74 }
     75 
     76 /**
     77  * Return the 160-bit message digest into the user's array
     78  */
     79 void SHA1Final(SHA1_CTX *ctx, uint8_t *digest)
     80 {
     81     int i;
     82 
     83     SHA1PadMessage(ctx);
     84     memset(ctx->Message_Block, 0, 64);
     85     ctx->Length_Low = 0;    /* and clear length */
     86     ctx->Length_High = 0;
     87 
     88     for  (i = 0; i < SHA1_SIZE; i++)
     89     {
     90         digest[i] = ctx->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) );
     91     }
     92 }
     93 
     94 /**
     95  * Process the next 512 bits of the message stored in the array.
     96  */
     97 static void SHA1ProcessMessageBlock(SHA1_CTX *ctx)
     98 {
     99     const uint32_t K[] =    {       /* Constants defined in SHA-1   */
    100                             0x5A827999,
    101                             0x6ED9EBA1,
    102                             0x8F1BBCDC,
    103                             0xCA62C1D6
    104                             };
    105     int        t;                 /* Loop counter                */
    106     uint32_t      temp;              /* Temporary word value        */
    107     uint32_t      W[80];             /* Word sequence               */
    108     uint32_t      A, B, C, D, E;     /* Word buffers                */
    109 
    110     /*
    111      *  Initialize the first 16 words in the array W
    112      */
    113     for  (t = 0; t < 16; t++)
    114     {
    115         W[t] = ctx->Message_Block[t * 4] << 24;
    116         W[t] |= ctx->Message_Block[t * 4 + 1] << 16;
    117         W[t] |= ctx->Message_Block[t * 4 + 2] << 8;
    118         W[t] |= ctx->Message_Block[t * 4 + 3];
    119     }
    120 
    121     for (t = 16; t < 80; t++)
    122     {
    123        W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
    124     }
    125 
    126     A = ctx->Intermediate_Hash[0];
    127     B = ctx->Intermediate_Hash[1];
    128     C = ctx->Intermediate_Hash[2];
    129     D = ctx->Intermediate_Hash[3];
    130     E = ctx->Intermediate_Hash[4];
    131 
    132     for (t = 0; t < 20; t++)
    133     {
    134         temp =  SHA1CircularShift(5,A) +
    135                 ((B & C) | ((~B) & D)) + E + W[t] + K[0];
    136         E = D;
    137         D = C;
    138         C = SHA1CircularShift(30,B);
    139 
    140         B = A;
    141         A = temp;
    142     }
    143 
    144     for (t = 20; t < 40; t++)
    145     {
    146         temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
    147         E = D;
    148         D = C;
    149         C = SHA1CircularShift(30,B);
    150         B = A;
    151         A = temp;
    152     }
    153 
    154     for (t = 40; t < 60; t++)
    155     {
    156         temp = SHA1CircularShift(5,A) +
    157                ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
    158         E = D;
    159         D = C;
    160         C = SHA1CircularShift(30,B);
    161         B = A;
    162         A = temp;
    163     }
    164 
    165     for (t = 60; t < 80; t++)
    166     {
    167         temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
    168         E = D;
    169         D = C;
    170         C = SHA1CircularShift(30,B);
    171         B = A;
    172         A = temp;
    173     }
    174 
    175     ctx->Intermediate_Hash[0] += A;
    176     ctx->Intermediate_Hash[1] += B;
    177     ctx->Intermediate_Hash[2] += C;
    178     ctx->Intermediate_Hash[3] += D;
    179     ctx->Intermediate_Hash[4] += E;
    180     ctx->Message_Block_Index = 0;
    181 }
    182 
    183 /*
    184  * According to the standard, the message must be padded to an even
    185  * 512 bits.  The first padding bit must be a '1'.  The last 64
    186  * bits represent the length of the original message.  All bits in
    187  * between should be 0.  This function will pad the message
    188  * according to those rules by filling the Message_Block array
    189  * accordingly.  It will also call the ProcessMessageBlock function
    190  * provided appropriately.  When it returns, it can be assumed that
    191  * the message digest has been computed.
    192  *
    193  * @param ctx [in, out] The SHA1 context
    194  */
    195 static void SHA1PadMessage(SHA1_CTX *ctx)
    196 {
    197     /*
    198      *  Check to see if the current message block is too small to hold
    199      *  the initial padding bits and length.  If so, we will pad the
    200      *  block, process it, and then continue padding into a second
    201      *  block.
    202      */
    203     if (ctx->Message_Block_Index > 55)
    204     {
    205         ctx->Message_Block[ctx->Message_Block_Index++] = 0x80;
    206         while(ctx->Message_Block_Index < 64)
    207         {
    208             ctx->Message_Block[ctx->Message_Block_Index++] = 0;
    209         }
    210 
    211         SHA1ProcessMessageBlock(ctx);
    212 
    213         while (ctx->Message_Block_Index < 56)
    214         {
    215             ctx->Message_Block[ctx->Message_Block_Index++] = 0;
    216         }
    217     }
    218     else
    219     {
    220         ctx->Message_Block[ctx->Message_Block_Index++] = 0x80;
    221         while(ctx->Message_Block_Index < 56)
    222         {
    223 
    224             ctx->Message_Block[ctx->Message_Block_Index++] = 0;
    225         }
    226     }
    227 
    228     /*
    229      *  Store the message length as the last 8 octets
    230      */
    231     ctx->Message_Block[56] = ctx->Length_High >> 24;
    232     ctx->Message_Block[57] = ctx->Length_High >> 16;
    233     ctx->Message_Block[58] = ctx->Length_High >> 8;
    234     ctx->Message_Block[59] = ctx->Length_High;
    235     ctx->Message_Block[60] = ctx->Length_Low >> 24;
    236     ctx->Message_Block[61] = ctx->Length_Low >> 16;
    237     ctx->Message_Block[62] = ctx->Length_Low >> 8;
    238     ctx->Message_Block[63] = ctx->Length_Low;
    239     SHA1ProcessMessageBlock(ctx);
    240 }
    241