Annotation of qemu/roms/ipxe/src/crypto/axtls/sha1.c, revision 1.1.1.1

1.1       root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.