Annotation of parser3/src/lib/md5/pa_sha1.C, revision 1.1

1.1     ! moko        1: /** @file
        !             2:        Parser: SHA-1 implementation based on the reference code published in RFC 3174.
        !             3:        http://www.rfc-editor.org/rfc/rfc3174
        !             4: */
        !             5: 
        !             6: #include "pa_sha1.h"
        !             7: #include "pa_exception.h"
        !             8: 
        !             9: volatile const char * IDENT_PA_SHA1_C="$Id$" IDENT_PA_SHA1_H;
        !            10: 
        !            11: #define SHA1CircularShift(bits,word) ((((word) << (bits)) & 0xFFFFFFFF)|((word) >> (32-(bits))))
        !            12: static void SHA1ProcessMessageBlock(PA_SHA1_CTX *);
        !            13: static void SHA1PadMessage(PA_SHA1_CTX *);
        !            14: void pa_SHA1Reset(PA_SHA1_CTX *context) {
        !            15:        context->Length_Low = context->Length_High = context->Message_Block_Index = 0;
        !            16:        context->Message_Digest[0]      = 0x67452301;
        !            17:        context->Message_Digest[1]      = 0xEFCDAB89;
        !            18:        context->Message_Digest[2]      = 0x98BADCFE;
        !            19:        context->Message_Digest[3]      = 0x10325476;
        !            20:        context->Message_Digest[4]      = 0xC3D2E1F0;
        !            21:        context->Computed = context->Corrupted  = 0;
        !            22: }
        !            23: 
        !            24: static int SHA1Result(PA_SHA1_CTX *context) {
        !            25:        if (context->Corrupted)
        !            26:                return 0;
        !            27:        if (!context->Computed) {
        !            28:                SHA1PadMessage(context);
        !            29:                context->Computed = 1;
        !            30:        }
        !            31:        return 1;
        !            32: }
        !            33: 
        !            34: void pa_SHA1Input(PA_SHA1_CTX *context, const unsigned char *message_array, unsigned length) {
        !            35:        if (!length)
        !            36:                return;
        !            37:        if (context->Computed || context->Corrupted) {
        !            38:                context->Corrupted = 1;
        !            39:                return;
        !            40:        }
        !            41: 
        !            42:        while(length-- && !context->Corrupted) {
        !            43:                context->Message_Block[context->Message_Block_Index++] = (*message_array & 0xFF);
        !            44:                context->Length_Low += 8;
        !            45:                context->Length_Low &= 0xFFFFFFFF;
        !            46:                if (!context->Length_Low && !(context->Length_High=((1+context->Length_High)&0xFFFFFFFF)))
        !            47:                        context->Corrupted = 1; // too long message
        !            48:                if (context->Message_Block_Index == 64)
        !            49:                        SHA1ProcessMessageBlock(context);
        !            50:                message_array++;
        !            51:        }
        !            52: }
        !            53: 
        !            54: static void SHA1ProcessMessageBlock(PA_SHA1_CTX *context) {
        !            55:        const unsigned K[] = {0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 };
        !            56:        int t;
        !            57:        unsigned    temp, W[80], buf[5];
        !            58:        unsigned &A=buf[0], &B=buf[1], &C=buf[2], &D=buf[3], &E=buf[4];
        !            59: 
        !            60:        for(t = 0; t < 16; t++)
        !            61:                W[t] = (((unsigned) context->Message_Block[t * 4]) << 24) | (((unsigned) context->Message_Block[t * 4 + 1]) << 16) | (((unsigned) context->Message_Block[t * 4 + 2]) << 8) | ((unsigned) context->Message_Block[t * 4 + 3]);
        !            62: 
        !            63:        for(t = 16; t < 80; t++)
        !            64:                W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
        !            65: 
        !            66:        memcpy (buf, context->Message_Digest, sizeof(buf));
        !            67:        for(t = 0; t < 20; t++) {
        !            68:                temp =  (SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0]) & 0xFFFFFFFF;
        !            69:                E = D; D = C;
        !            70:                C = SHA1CircularShift(30,B);
        !            71:                B = A; A = temp;
        !            72:        }
        !            73: 
        !            74:        for(t = 20; t < 40; t++) {
        !            75:                temp = (SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]) & 0xFFFFFFFF;
        !            76:                E = D; D = C;
        !            77:                C = SHA1CircularShift(30,B);
        !            78:                B = A; A = temp;
        !            79:        }
        !            80: 
        !            81:        for(t = 40; t < 60; t++) {
        !            82:                temp = (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]) & 0xFFFFFFFF;
        !            83:                E = D; D = C;
        !            84:                C = SHA1CircularShift(30,B);
        !            85:                B = A; A = temp;
        !            86:        }
        !            87: 
        !            88:        for(t = 60; t < 80; t++) {
        !            89:                temp = (SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]) & 0xFFFFFFFF;
        !            90:                E = D; D = C;
        !            91:                C = SHA1CircularShift(30,B);
        !            92:                B = A; A = temp;
        !            93:        }
        !            94: 
        !            95:        for (t = 0; t < 5; t++)
        !            96:                context->Message_Digest[t] = (context->Message_Digest[t] + buf[t]) & 0xFFFFFFFF;
        !            97: 
        !            98:        context->Message_Block_Index = 0;
        !            99: }
        !           100: 
        !           101: static void SHA1PadMessage(PA_SHA1_CTX *context) {
        !           102:        context->Message_Block[context->Message_Block_Index++] = 0x80;
        !           103:        if (context->Message_Block_Index > 56) {
        !           104:                //was 55, one shift
        !           105:                while(context->Message_Block_Index < 64)
        !           106:                        context->Message_Block[context->Message_Block_Index++] = 0;
        !           107:                SHA1ProcessMessageBlock(context);
        !           108:                while(context->Message_Block_Index < 56)
        !           109:                        context->Message_Block[context->Message_Block_Index++] = 0;
        !           110:        } else
        !           111:                while(context->Message_Block_Index < 56)
        !           112:                        context->Message_Block[context->Message_Block_Index++] = 0;
        !           113:        context->Message_Block[56] = (context->Length_High >> 24) & 0xFF;
        !           114:        context->Message_Block[57] = (context->Length_High >> 16) & 0xFF;
        !           115:        context->Message_Block[58] = (context->Length_High >> 8) & 0xFF;
        !           116:        context->Message_Block[59] = (context->Length_High) & 0xFF;
        !           117:        context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF;
        !           118:        context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF;
        !           119:        context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF;
        !           120:        context->Message_Block[63] = (context->Length_Low) & 0xFF;
        !           121:        SHA1ProcessMessageBlock(context);
        !           122: }
        !           123: 
        !           124: #ifdef PA_BIG_ENDIAN
        !           125: #define SWAP(n) (n)
        !           126: #else
        !           127: #define SWAP(n) (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
        !           128: #endif
        !           129: 
        !           130: void pa_SHA1ReadDigest(void *buf, PA_SHA1_CTX *c)
        !           131: {
        !           132:        if(!SHA1Result(c))
        !           133:                throw Exception (PARSER_RUNTIME, 0, "Cannot compute SHA1");
        !           134: 
        !           135:        ((uint32_t *)buf)[0] = SWAP(c->Message_Digest[0]);
        !           136:        ((uint32_t *)buf)[1] = SWAP(c->Message_Digest[1]);
        !           137:        ((uint32_t *)buf)[2] = SWAP(c->Message_Digest[2]);
        !           138:        ((uint32_t *)buf)[3] = SWAP(c->Message_Digest[3]);
        !           139:        ((uint32_t *)buf)[4] = SWAP(c->Message_Digest[4]);
        !           140: }

E-mail: