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: