📄 md5.c
字号:
ii(A, B, C, D, 4, is1, Uns(4149444226)); ii(D, A, B, C, 11, is2, Uns(3174756917)); ii(C, D, A, B, 2, is3, Uns(718787259)); ii(B, C, D, A, 9, is4, Uns(3951481745)); MDp->buffer[0] += A; MDp->buffer[1] += B; MDp->buffer[2] += C; MDp->buffer[3] += D;#ifdef WORDS_BIGENDIAN MDreverse(X);#endif}/* * MDupdate(MDp,X,count) * ** Input: MDp -- an MDptr * ** X -- a pointer to an array of unsigned characters. * ** count -- the number of bits of X to use. * ** (if not a multiple of 8, uses high bits of last byte.) * ** Update MDp using the number of bits of X given by count. * ** This is the basic input routine for an MD5 user. * ** The routine completes the MD computation when count < 512, so * ** every MD computation should end with one call to MDupdate with a * ** count less than 512. A call with count 0 will be ignored if the * ** MD has already been terminated (done != 0), so an extra call with count * ** 0 can be given as a ``courtesy close'' to force termination if desired. * ** Returns : 0 if processing succeeds or was already done; * ** -1 if processing was already done * ** -2 if count was too large */intMDupdate(MDptr MDp, unsigned char *X, unsigned int count){ unsigned int i, tmp, bit, byte, mask; unsigned char XX[64]; unsigned char *p; /* * return with no error if this is a courtesy close with count * ** zero and MDp->done is true. */ if (count == 0 && MDp->done) return 0; /* * check to see if MD is already done and report error */ if (MDp->done) { return -1; } /* * if (MDp->done) { fprintf(stderr,"\nError: MDupdate MD already done."); return; } */ /* * Add count to MDp->count */ tmp = count; p = MDp->count; while (tmp) { tmp += *p; *p++ = tmp; tmp = tmp >> 8; } /* * Process data */ if (count == 512) { /* Full block of data to handle */ MDblock(MDp, (unsigned int *) X); } else if (count > 512) /* Check for count too large */ return -2; /* * { fprintf(stderr,"\nError: MDupdate called with illegal count value %d.",count); * return; * } */ else { /* partial block -- must be last block so finish up */ /* * Find out how many bytes and residual bits there are */ int copycount; byte = count >> 3; bit = count & 7; copycount = byte; if (bit) copycount++; /* * Copy X into XX since we need to modify it */ memset(XX, 0, sizeof(XX)); memcpy(XX, X, copycount); /* * Add padding '1' bit and low-order zeros in last byte */ mask = ((unsigned long) 1) << (7 - bit); XX[byte] = (XX[byte] | mask) & ~(mask - 1); /* * If room for bit count, finish up with this block */ if (byte <= 55) { for (i = 0; i < 8; i++) XX[56 + i] = MDp->count[i]; MDblock(MDp, (unsigned int *) XX); } else { /* need to do two blocks to finish up */ MDblock(MDp, (unsigned int *) XX); for (i = 0; i < 56; i++) XX[i] = 0; for (i = 0; i < 8; i++) XX[56 + i] = MDp->count[i]; MDblock(MDp, (unsigned int *) XX); } /* * Set flag saying we're done with MD computation */ MDp->done = 1; } return 0;}/* * MDchecksum(data, len, MD5): do a checksum on an arbirtrary amount of data */intMDchecksum(u_char * data, size_t len, u_char * mac, size_t maclen){ MDstruct md; MDstruct *MD = &md; int rc = 0; MDbegin(MD); while (len >= 64) { rc = MDupdate(MD, data, 64 * 8); if (rc) goto check_end; data += 64; len -= 64; } rc = MDupdate(MD, data, len * 8); if (rc) goto check_end; /* * copy the checksum to the outgoing data (all of it that is requested). */ MDget(MD, mac, maclen); check_end: memset(&md, 0, sizeof(md)); return rc;}/* * MDsign(data, len, MD5): do a checksum on an arbirtrary amount * of data, and prepended with a secret in the standard fashion */intMDsign(u_char * data, size_t len, u_char * mac, size_t maclen, u_char * secret, size_t secretlen){#define HASHKEYLEN 64 MDstruct MD; u_char K1[HASHKEYLEN]; u_char K2[HASHKEYLEN]; u_char extendedAuthKey[HASHKEYLEN]; u_char buf[HASHKEYLEN]; size_t i; u_char *cp, *newdata = 0; int rc = 0; /* * memset(K1,0,HASHKEYLEN); * memset(K2,0,HASHKEYLEN); * memset(buf,0,HASHKEYLEN); * memset(extendedAuthKey,0,HASHKEYLEN); */ if (secretlen != 16 || secret == NULL || mac == NULL || data == NULL || len <= 0 || maclen <= 0) { /* * DEBUGMSGTL(("md5","MD5 signing not properly initialized")); */ return -1; } memset(extendedAuthKey, 0, HASHKEYLEN); memcpy(extendedAuthKey, secret, secretlen); for (i = 0; i < HASHKEYLEN; i++) { K1[i] = extendedAuthKey[i] ^ 0x36; K2[i] = extendedAuthKey[i] ^ 0x5c; } MDbegin(&MD); rc = MDupdate(&MD, K1, HASHKEYLEN * 8); if (rc) goto update_end; i = len; if (((unsigned int) data) % 32 != 0) { /* * this relies on the ability to use integer math and thus we * must rely on data that aligns on 32-bit-word-boundries */ memdup(&newdata, data, len); cp = newdata; } else { cp = data; } while (i >= 64) { rc = MDupdate(&MD, cp, 64 * 8); if (rc) goto update_end; cp += 64; i -= 64; } rc = MDupdate(&MD, cp, i * 8); if (rc) goto update_end; memset(buf, 0, HASHKEYLEN); MDget(&MD, buf, HASHKEYLEN); MDbegin(&MD); rc = MDupdate(&MD, K2, HASHKEYLEN * 8); if (rc) goto update_end; rc = MDupdate(&MD, buf, 16 * 8); if (rc) goto update_end; /* * copy the sign checksum to the outgoing pointer */ MDget(&MD, mac, maclen); update_end: memset(buf, 0, HASHKEYLEN); memset(K1, 0, HASHKEYLEN); memset(K2, 0, HASHKEYLEN); memset(extendedAuthKey, 0, HASHKEYLEN); memset(&MD, 0, sizeof(MD)); if (newdata) free(newdata); return rc;}voidMDget(MDstruct * MD, u_char * buf, size_t buflen){ int i, j; /* * copy the checksum to the outgoing data (all of it that is requested). */ for (i = 0; i < 4 && i * 4 < (int) buflen; i++) for (j = 0; j < 4 && i * 4 + j < (int) buflen; j++) buf[i * 4 + j] = (MD->buffer[i] >> j * 8) & 0xff;}/* * ** End of md5.c * ****************************(cut)**************************************** */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -