00001
00010 #define DKUTIL_C_MD5_C
00011
00012 #ifndef DKINGYOUTILITY3_EXPORTS
00013 #include "md5.h"
00014 #endif
00015
00016 #include "md_misc.h"
00017 #ifdef _MSC_VER
00018 # include "md5_vc_mmx.h"
00019 #endif
00020
00021 #include "dkcMD5.h"
00022 #include "dkcStdio.h"
00023
00024
00025
00026
00027 DKC_MD5 *WINAPI dkcAllocMD5(){
00028 DKC_MD5 *p = dkcAllocate(sizeof(DKC_MD5));
00029 if(NULL==p) return NULL;
00030 dkcMD5Init(p);
00031 return p;
00032 }
00033
00034
00035 int WINAPI dkcFreeMD5(DKC_MD5 **pp){
00036
00037 if(NULL==pp || NULL==*pp){
00038 return edk_FAILED;
00039 }
00040 return dkcFree((void **)pp);
00041 }
00042
00043 void WINAPI dkcMD5Init(DKC_MD5 *p){
00044 p->count[0] = p->count[1] = 0;
00045 p->abcd[0] = 0x67452301;
00046 p->abcd[1] = 0xefcdab89;
00047 p->abcd[2] = 0x98badcfe;
00048 p->abcd[3] = 0x10325476;
00049 memset(p->a8,0,sizeof(p->a8));
00050 p->flags = edkcMD_Optimize;
00051
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061 #define F1(x, y, z) (z ^ (x & (y ^ z)))
00062 #define F2(x, y, z) F1(z, x, y)
00063 #define F3(x, y, z) (x ^ y ^ z)
00064 #define F4(x, y, z) (y ^ (x | ~z))
00065
00066
00067 #define MD5STEP(f, w, x, y, z, data, s) \
00068 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
00069
00070
00071
00072
00073
00074
00075 static DKC_INLINE void
00076 MD5Transform(uint32 buf[4], uint32 const in[16])
00077 {
00078 #ifdef _DEBUG
00079 uint32 a, b, c, d;
00080 #else
00081 register uint32 a, b, c, d;
00082 #endif
00083 a = buf[0];
00084 b = buf[1];
00085 c = buf[2];
00086 d = buf[3];
00087
00088 MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
00089 MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
00090 MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
00091 MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
00092 MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
00093 MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
00094 MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
00095 MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
00096 MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
00097 MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
00098 MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
00099 MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
00100 MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
00101 MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
00102 MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
00103 MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
00104
00105 MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
00106 MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
00107 MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
00108 MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
00109 MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
00110 MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
00111 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
00112 MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
00113 MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
00114 MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
00115 MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
00116 MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
00117 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
00118 MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
00119 MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
00120 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
00121
00122 MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
00123 MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
00124 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
00125 MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
00126 MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
00127 MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
00128 MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
00129 MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
00130 MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
00131 MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
00132 MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
00133 MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
00134 MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
00135 MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
00136 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
00137 MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
00138
00139 MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
00140 MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
00141 MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
00142 MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
00143 MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
00144 MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
00145 MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
00146 MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
00147 MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
00148 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
00149 MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
00150 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
00151 MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
00152 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
00153 MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
00154 MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
00155
00156 buf[0] += a;
00157 buf[1] += b;
00158 buf[2] += c;
00159 buf[3] += d;
00160 }
00161
00162 static DKC_INLINE uint8 double_md5_update_begin(DKC_MD5 *p,uint8 const *buf,uint32 len,uint32 *pt)
00163 {
00164 uint32 t;
00165
00166
00167
00168
00169 t = p->count[0];
00170 if ((p->count[0] = t + ((uint32) len << 3)) < t)
00171 p->count[1]++;
00172 p->count[1] += len >> 29;
00173
00174 t = (t >> 3) & 0x3f;
00175
00176
00177
00178 if (t)
00179 {
00180
00181 uint8 *pc = (uint8 *)&(p->a8[t]);
00182 t = 64 - t;
00183 if (len < t)
00184 {
00185 memmove(pc, buf, len);
00186 return FALSE;
00187 }
00188 memmove(pc, buf, t);
00189
00190 if ((p->flags) & edkcMD_ByteReverse)
00191 {
00192 dkcMD_ByteReverse(p->a8 ,16);
00193 }
00194 }
00195 *pt = t;
00196 return TRUE;
00197 }
00198
00199
00200 void WINAPI dkcMD5LoadDouble(
00201 DKC_MD5 *p,uint8 const *buf, uint32 len,
00202 DKC_MD5 *p2,uint8 const *buf2, uint32 len2)
00203 {
00204 #ifdef _MSC_VER
00205 uint32 t = 0;
00206 uint32 t2 =0;
00207 uint8 w,e;
00208 w = double_md5_update_begin(p,buf,len,&t);
00209 e = double_md5_update_begin(p2,buf2,len2,&t2);
00210 dkcmNOT_ASSERT(w != e);
00211 if(FALSE==w){
00212 return;
00213 }
00214
00215 dkcmFORCE_NOT_ASSERT(len != len2);
00216 dkcmNOT_ASSERT((!t) != (!t2));
00217 if(t && t2){
00218 md5_mmx_double_update(p->abcd,p2->abcd,
00219 (const uint32 *)p->a8,(const uint32 *)p2->a8);
00220
00221 buf += t;
00222 len -= t;
00223
00224 buf2 += t2;
00225 len2 -= t2;
00226 }else{
00227 dkcmNOT_ASSERT(t && !t2);
00228 }
00229
00230 dkcmNOT_ASSERT(len != len2);
00231
00232
00233
00234 while (len >= 64)
00235 {
00236 memmove(p->a8, buf, 64);
00237 memmove(p2->a8, buf2, 64);
00238
00239 if ((p->flags) & edkcMD_ByteReverse)
00240 {
00241 dkcMD_ByteReverse(p->a8, 16);
00242 }
00243 if ((p2->flags) & edkcMD_ByteReverse)
00244 {
00245 dkcMD_ByteReverse(p2->a8, 16);
00246 }
00247
00248
00249 md5_mmx_double_update(p->abcd,p2->abcd,
00250 (uint32 *)p->a8,(uint32 *)p2->a8);
00251 buf += 64;
00252 len -= 64;
00253
00254 buf2 += 64;
00255 len2 -= 64;
00256 }
00257
00258
00259
00260 memmove(p->a8, buf, len);
00261 memmove(p2->a8, buf2, len2);
00262 #else
00263 dkcMD5Load(p,buf,len);
00264 dkcMD5Load(p2,buf2,len2);
00265 #endif
00266 }
00267 #if 0
00268 static DKC_INLINE void double_MD5Final( DKC_MD5 *ctx)
00269 {
00270 uint32 count;
00271 uint8 *p;
00272
00273
00274 count = (ctx->count[0] >> 3) & 0x3F;
00275
00276
00277
00278 p = ctx->a8 + count;
00279 *p++ = 0x80;
00280
00281
00282 count = 64 - 1 - count;
00283
00284
00285 if (count < 8)
00286 {
00287
00288 memset(p, 0, count);
00289 if ((ctx->flags) & edkcMD_ByteReverse)
00290 dkcMD_ByteReverse(ctx->a8, 16);
00291 MD5Transform(ctx->abcd, (uint32 *) ctx->a8);
00292
00293
00294 memset(ctx->a8, 0, 56);
00295 }
00296 else
00297 {
00298
00299 memset(p, 0, count - 8);
00300 }
00301 if ((ctx->flags) & edkcMD_ByteReverse)
00302 dkcMD_ByteReverse(ctx->a8, 14);
00303
00304
00305 ((uint32 *) ctx->a8)[14] = ctx->count[0];
00306 ((uint32 *) ctx->a8)[15] = ctx->count[1];
00307
00308 MD5Transform(ctx->abcd, (uint32 *) ctx->a8);
00309 if ((ctx->flags) & edkcMD_ByteReverse)
00310 dkcMD_ByteReverse((uint8 *) ctx->abcd, 4);
00311 }
00312 #endif
00313
00314 void WINAPI dkcMD5Load(DKC_MD5 *p,const BYTE *pBuffer,DWORD dwSize){
00315 if(p->flags & edkcMD_Finalized){
00316 return;
00317 }
00318 dkcMD_Update(p,pBuffer,dwSize,MD5Transform);
00319 }
00320
00321
00322
00323 void WINAPI dkcMD5Final(DKC_MD5 *p){
00324
00325 if(p->flags & edkcMD_Finalized){
00326 return;
00327 }
00328
00329 dkcMD_Final(p,MD5Transform);
00330
00331 p->flags |= edkcMD_Finalized;
00332 }
00333
00334 int WINAPI dkcMD5Digest(DKC_MD5 *p,BYTE *buff,size_t size){
00335
00336 if(size < MD5_BIN_BUFFER_SIZE){
00337 return edk_BufferOverFlow;
00338 }
00339 return dkc_memcpy(buff,size,p->abcd,sizeof(p->abcd));
00340 }
00341
00342 int WINAPI dkcMD5DigestStr(DKC_MD5 *p,char *buff,size_t size){
00343 register int i;
00344 uint8 temp[MD5_BIN_BUFFER_SIZE];
00345 if(size < MD5_STR_BUFFER_SIZE){
00346 return edk_BufferOverFlow;
00347 }
00348 i = dkcMD5Digest(p,temp,sizeof(temp));
00349 if(DKUTIL_FAILED(i)){
00350 return i;
00351 }
00352 for (i=0; i<16; i++){
00353 sprintf(buff+i*2,"%02x", temp[i]);
00354 }
00355 buff[32]='\0';
00356 return edk_SUCCEEDED;
00357 }
00358
00359 int WINAPI dkcMD5FinalDigestStr(DKC_MD5 *p,char *buff,size_t size){
00360 dkcMD5Final(p);
00361 return dkcMD5DigestStr(p,buff,size);
00362 }
00363
00364 int WINAPI dkcMD5FinalDigest(DKC_MD5 *p,BYTE *buff,size_t size){
00365 dkcMD5Final(p);
00366 return dkcMD5Digest(p,buff,size);
00367
00368 }
00369
00370
00371
00372
00373
00374 #ifndef DKINGYOUTILITY3_EXPORTS
00375
00376
00377
00378
00379 DKC_MD5_ADAPTER *WINAPI dkcAllocMD5Adapter(uint32 initflag)
00380 {
00381 DKC_MD5_ADAPTER *p = (DKC_MD5_ADAPTER *)dkcAllocate(sizeof(DKC_MD5_ADAPTER));
00382 if(NULL==p){
00383 return NULL;
00384 }
00385 switch(initflag){
00386 case edkcMD5_Default:
00387 case edkcMD5_Aladdin:
00388 default:
00389 p->mpObj = dkcAllocate(sizeof(md5_state_t));
00390 };
00391 if(NULL==p->mpObj)
00392 {
00393 dkcFree(&p);
00394 return NULL;
00395 }
00396 p->mObjFlag = initflag;
00397 dkcMD5AdapterInit(p);
00398 return p;
00399 }
00400
00401 int WINAPI dkcFreeMD5Adapter(DKC_MD5_ADAPTER **pp){
00402 DKC_MD5_ADAPTER *p = *pp;
00403 if(NULL==pp || NULL==p){
00404 return edk_FAILED;
00405 }
00406 if(!p->mpObj) return edk_FAILED;
00407 switch(p->mObjFlag){
00408 case edkcMD5_Default:
00409 case edkcMD5_Aladdin:
00410 default:
00411 dkcFree(&(p->mpObj));
00412 }
00413 return dkcFree((void **)p);
00414 }
00415
00416 void WINAPI dkcMD5AdapterInit(DKC_MD5_ADAPTER *p){
00417 switch(p->mObjFlag){
00418 case edkcMD5_Default:
00419 case edkcMD5_Aladdin:
00420 default:
00421 md5_init((md5_state_t *)p->mpObj);
00422 }
00423 p->mFinalized = FALSE;
00424 }
00425
00426 int WINAPI dkcMD5AdapterLoad(DKC_MD5_ADAPTER *p,const BYTE *pBuffer,DWORD dwSize){
00427 switch(p->mObjFlag){
00428 case edkcMD5_Default:
00429 case edkcMD5_Aladdin:
00430 default:
00431 if(dwSize > INT_MAX){
00432 return edk_FAILED;
00433 }
00434 };
00435
00436 dkcMD5AdapterLoadStandard(p,pBuffer,dwSize);
00437 return edk_SUCCEEDED;
00438 }
00439
00440 void WINAPI dkcMD5AdapterLoadStandard(DKC_MD5_ADAPTER *p,const BYTE *pBuffer,DWORD dwSize){
00441 if(p->mFinalized){
00442 return;
00443 }
00444 switch(p->mObjFlag){
00445 case edkcMD5_Default:
00446 case edkcMD5_Aladdin:
00447 default:
00448 md5_append((md5_state_t *)p->mpObj,pBuffer,(int)dwSize);
00449 };
00450 }
00451
00452
00453
00454 void WINAPI dkcMD5AdapterFinal(DKC_MD5_ADAPTER *p){
00455 if(p->mFinalized){
00456 return;
00457 }
00458 switch(p->mObjFlag){
00459 case edkcMD5_Default:
00460 case edkcMD5_Aladdin:
00461 default:
00462 md5_finalize((md5_state_t *)p->mpObj);
00463 }
00464 p->mFinalized = TRUE;
00465 }
00466
00467 int WINAPI dkcMD5AdapterDigest(DKC_MD5_ADAPTER *p,BYTE *buff,size_t size){
00468
00469 if(size < MD5_BIN_BUFFER_SIZE){
00470 return edk_BufferOverFlow;
00471 }
00472 switch(p->mObjFlag){
00473 case edkcMD5_Default:
00474 case edkcMD5_Aladdin:
00475 default:
00476
00477 md5_get_digest((md5_state_t *)p->mpObj,(BYTE *)buff);
00478 }
00479 return edk_SUCCEEDED;
00480 }
00481
00482 int WINAPI dkcMD5AdapterDigestStr(DKC_MD5_ADAPTER *p,char *buff,size_t size){
00483
00484 if(size < MD5_STR_BUFFER_SIZE){
00485 return edk_BufferOverFlow;
00486 }
00487 switch(p->mObjFlag){
00488 case edkcMD5_Default:
00489 case edkcMD5_Aladdin:
00490 default:
00491 md5_get_str_digest((md5_state_t *)p->mpObj,(char *)buff);
00492 }
00493 return edk_SUCCEEDED;
00494 }
00495
00496 int WINAPI dkcMD5AdapterFinalDigestStr(DKC_MD5_ADAPTER *p,char *buff,size_t size){
00497 dkcMD5AdapterFinal(p);
00498 return dkcMD5AdapterDigestStr(p,buff,size);
00499 }
00500
00501 int WINAPI dkcMD5AdapterFinalDigest(DKC_MD5_ADAPTER *p,BYTE *buff,size_t size){
00502 dkcMD5AdapterFinal(p);
00503 return dkcMD5AdapterDigest(p,buff,size);
00504
00505 }
00506 #endif
00507