Quantcast
Channel: Cool Software Blog
Viewing all articles
Browse latest Browse all 78

[Delphi XE2] MD4/MD5 Bug on x64

$
0
0
В библиотеке Indy, которая поставляется с  Delphi XE2 под 64-битной платформой, имеется баг в вычислении MD4/MD5 (компоненты TIdHashMessageDigest4, TIdHashMessageDigest5 соответственно).

Вот код для вычисления MD5:

varmd5indy:TIdHashMessageDigest5;sMD5:String;beginmd5indy:=TIdHashMessageDigest5.Create;sMD5:=md5indy.HashStringAsHex('123456');md5indy.Free;end;

Под Win32 результат будет: 'e10adc3949ba59abbe56e057f20f883e' (правильно)
Под Win64 результат будет: '6e692400e5c684b74314252e341b92c7' (ошибка)

Этот баг был исправлен в более поздних версиях версиях Indy/Delphi (не скажу точно, в какой именно, в Delphi 10.2 Tokyo его нет).

Баг в asm-функциях ROL и ROR в модуле IdGlobalProtocols. Вот как они выглядят в XE2:

// Arg1=EAX, Arg2=DL functionROL(constAVal:LongWord;AShift:Byte):LongWord;assembler;asm mov cl, dl rol eax, cl end;functionROR(constAVal:LongWord;AShift:Byte):LongWord;assembler;asm mov cl, dl ror eax, cl end;{$ENDIF}

А вот так это выглядит в Delpgi 10.2 Tokyo:

// 32-bit: Arg1=EAX, Arg2=DL // 64-bit: Arg1=ECX, Arg2=DL functionROL(constAVal:UInt32;AShift:Byte):UInt32;assembler;asm{$IFDEF CPU64} mov eax, ecx {$ENDIF} mov cl, dl rol eax, cl end;functionROR(constAVal:UInt32;AShift:Byte):UInt32;assembler;asm{$IFDEF CPU64} mov eax, ecx {$ENDIF} mov cl, dl ror eax, cl end;

Чтобы можно было генерировать MD4/MD5 в XE2 под Win64 без установки новой версии Indy, я сделал модуль IdHashMessageDigestEx с "исправленными" классами TIdHashMessageDigest4Ex и TIdHashMessageDigest5Ex, которыми следует пользоваться вместо TIdHashMessageDigest4 и TIdHashMessageDigest5 соответственно. Замечу, что в XE2 не работает макрос CPU64 (как в более поздних версиях Delphi), а работает CPUX64.

unitIdHashMessageDigestEx;interfaceusesIdFIPS,IdHashMessageDigest;type{$IFDEF VER230}//XE2 TIdHashMessageDigest4Ex=class(TIdHashMessageDigest4)protectedprocedureMDCoder;override;end;TIdHashMessageDigest5Ex=class(TIdHashMessageDigest4Ex)protectedprocedureMDCoder;override;functionInitHash:TIdHashIntCtx;override;publicclassfunctionIsIntfAvailable:Boolean;override;end;{$ELSE}TIdHashMessageDigest4Ex=TIdHashMessageDigest4;TIdHashMessageDigest5Ex=TIdHashMessageDigest5;{$ENDIF}implementation{$IFDEF VER230}//XE2 {$IFDEF NO_NATIVE_ASM)}//XE2 usesIdGlobalProtocols;{$ELSE}// 32-bit: Arg1=EAX, Arg2=DL // 64-bit: Arg1=ECX, Arg2=DL functionROL(constAVal:LongWord;AShift:LongWord):LongWord;assembler;asm{$IFDEF CPUX64} mov eax, ecx {$ENDIF} mov cl, dl rol eax, cl end;{$ENDIF}{ TIdHashMessageDigest4Ex }{$Q-}// Arithmetic operations performed modulo $100000000 procedureTIdHashMessageDigest4Ex.MDCoder;varA,B,C,D,i:LongWord;buff:T16x4LongWordRecord;// 64-byte buffer beginA:=FState[0];B:=FState[1];C:=FState[2];D:=FState[3];fori:=0to15dobeginbuff[i]:=FCBuffer[i*4+0]+(FCBuffer[i*4+1]shl8)+(FCBuffer[i*4+2]shl16)+(FCBuffer[i*4+3]shl24);end;// Round 1 { Note: (x and y) or ( (not x) and z) is equivalent to (((z xor y) and x) xor z) -HHellstrцm }fori:=0to3dobeginA:=ROL((((DxorC)andB)xorD)+A+buff[i*4+0],3);D:=ROL((((CxorB)andA)xorC)+D+buff[i*4+1],7);C:=ROL((((BxorA)andD)xorB)+C+buff[i*4+2],11);B:=ROL((((AxorD)andC)xorA)+B+buff[i*4+3],19);end;// Round 2 { Note: (x and y) or (x and z) or (y and z) is equivalent to ((x and y) or (z and (x or y))) -HHellstrцm }fori:=0to3dobeginA:=ROL(((BandC)or(Dand(BorC)))+A+buff[0*4+i]+$5A827999,3);D:=ROL(((AandB)or(Cand(AorB)))+D+buff[1*4+i]+$5A827999,5);C:=ROL(((DandA)or(Band(DorA)))+C+buff[2*4+i]+$5A827999,9);B:=ROL(((CandD)or(Aand(CorD)))+B+buff[3*4+i]+$5A827999,13);end;// Round 3 A:=ROL((BxorCxorD)+A+buff[0]+$6ED9EBA1,3);D:=ROL((AxorBxorC)+D+buff[8]+$6ED9EBA1,9);C:=ROL((DxorAxorB)+C+buff[4]+$6ED9EBA1,11);B:=ROL((CxorDxorA)+B+buff[12]+$6ED9EBA1,15);A:=ROL((BxorCxorD)+A+buff[2]+$6ED9EBA1,3);D:=ROL((AxorBxorC)+D+buff[10]+$6ED9EBA1,9);C:=ROL((DxorAxorB)+C+buff[6]+$6ED9EBA1,11);B:=ROL((CxorDxorA)+B+buff[14]+$6ED9EBA1,15);A:=ROL((BxorCxorD)+A+buff[1]+$6ED9EBA1,3);D:=ROL((AxorBxorC)+D+buff[9]+$6ED9EBA1,9);C:=ROL((DxorAxorB)+C+buff[5]+$6ED9EBA1,11);B:=ROL((CxorDxorA)+B+buff[13]+$6ED9EBA1,15);A:=ROL((BxorCxorD)+A+buff[3]+$6ED9EBA1,3);D:=ROL((AxorBxorC)+D+buff[11]+$6ED9EBA1,9);C:=ROL((DxorAxorB)+C+buff[7]+$6ED9EBA1,11);B:=ROL((CxorDxorA)+B+buff[15]+$6ED9EBA1,15);Inc(FState[0],A);Inc(FState[1],B);Inc(FState[2],C);Inc(FState[3],D);end;{$Q+}{ TIdHashMessageDigest5Ex }constMD5_SINE:array[1..64]ofLongWord=({ Round 1. }$d76aa478,$e8c7b756,$242070db,$c1bdceee,$f57c0faf,$4787c62a,$a8304613,$fd469501,$698098d8,$8b44f7af,$ffff5bb1,$895cd7be,$6b901122,$fd987193,$a679438e,$49b40821,{ Round 2. }$f61e2562,$c040b340,$265e5a51,$e9b6c7aa,$d62f105d,$02441453,$d8a1e681,$e7d3fbc8,$21e1cde6,$c33707d6,$f4d50d87,$455a14ed,$a9e3e905,$fcefa3f8,$676f02d9,$8d2a4c8a,{ Round 3. }$fffa3942,$8771f681,$6d9d6122,$fde5380c,$a4beea44,$4bdecfa9,$f6bb4b60,$bebfbc70,$289b7ec6,$eaa127fa,$d4ef3085,$04881d05,$d9d4d039,$e6db99e5,$1fa27cf8,$c4ac5665,{ Round 4. }$f4292244,$432aff97,$ab9423a7,$fc93a039,$655b59c3,$8f0ccc92,$ffeff47d,$85845dd1,$6fa87e4f,$fe2ce6e0,$a3014314,$4e0811a1,$f7537e82,$bd3af235,$2ad7d2bb,$eb86d391);{$Q-}// Arithmetic operations performed modulo $100000000 functionTIdHashMessageDigest5Ex.InitHash:TIdHashIntCtx;beginResult:=GetMD5HashInst;end;classfunctionTIdHashMessageDigest5Ex.IsIntfAvailable:Boolean;beginResult:=IsHashingIntfAvailandIsMD5HashIntfAvail;end;procedureTIdHashMessageDigest5Ex.MDCoder;varA,B,C,D:LongWord;i:Integer;x:T16x4LongWordRecord;// 64-byte buffer beginA:=FState[0];B:=FState[1];C:=FState[2];D:=FState[3];fori:=0to15dobeginx[i]:=FCBuffer[i*4+0]+(FCBuffer[i*4+1]shl8)+(FCBuffer[i*4+2]shl16)+(FCBuffer[i*4+3]shl24);end;{ Round 1 }{ Note: (x and y) or ( (not x) and z) is equivalent to (((z xor y) and x) xor z) -HHellstrцm }A:=ROL(A+(((DxorC)andB)xorD)+x[0]+MD5_SINE[1],7)+B;D:=ROL(D+(((CxorB)andA)xorC)+x[1]+MD5_SINE[2],12)+A;C:=ROL(C+(((BxorA)andD)xorB)+x[2]+MD5_SINE[3],17)+D;B:=ROL(B+(((AxorD)andC)xorA)+x[3]+MD5_SINE[4],22)+C;A:=ROL(A+(((DxorC)andB)xorD)+x[4]+MD5_SINE[5],7)+B;D:=ROL(D+(((CxorB)andA)xorC)+x[5]+MD5_SINE[6],12)+A;C:=ROL(C+(((BxorA)andD)xorB)+x[6]+MD5_SINE[7],17)+D;B:=ROL(B+(((AxorD)andC)xorA)+x[7]+MD5_SINE[8],22)+C;A:=ROL(A+(((DxorC)andB)xorD)+x[8]+MD5_SINE[9],7)+B;D:=ROL(D+(((CxorB)andA)xorC)+x[9]+MD5_SINE[10],12)+A;C:=ROL(C+(((BxorA)andD)xorB)+x[10]+MD5_SINE[11],17)+D;B:=ROL(B+(((AxorD)andC)xorA)+x[11]+MD5_SINE[12],22)+C;A:=ROL(A+(((DxorC)andB)xorD)+x[12]+MD5_SINE[13],7)+B;D:=ROL(D+(((CxorB)andA)xorC)+x[13]+MD5_SINE[14],12)+A;C:=ROL(C+(((BxorA)andD)xorB)+x[14]+MD5_SINE[15],17)+D;B:=ROL(B+(((AxorD)andC)xorA)+x[15]+MD5_SINE[16],22)+C;{ Round 2 }{ Note: (x and z) or (y and (not z) ) is equivalent to (((y xor x) and z) xor y) -HHellstrцm }A:=ROL(A+(Cxor(Dand(BxorC)))+x[1]+MD5_SINE[17],5)+B;D:=ROL(D+(Bxor(Cand(AxorB)))+x[6]+MD5_SINE[18],9)+A;C:=ROL(C+(Axor(Band(DxorA)))+x[11]+MD5_SINE[19],14)+D;B:=ROL(B+(Dxor(Aand(CxorD)))+x[0]+MD5_SINE[20],20)+C;A:=ROL(A+(Cxor(Dand(BxorC)))+x[5]+MD5_SINE[21],5)+B;D:=ROL(D+(Bxor(Cand(AxorB)))+x[10]+MD5_SINE[22],9)+A;C:=ROL(C+(Axor(Band(DxorA)))+x[15]+MD5_SINE[23],14)+D;B:=ROL(B+(Dxor(Aand(CxorD)))+x[4]+MD5_SINE[24],20)+C;A:=ROL(A+(Cxor(Dand(BxorC)))+x[9]+MD5_SINE[25],5)+B;D:=ROL(D+(Bxor(Cand(AxorB)))+x[14]+MD5_SINE[26],9)+A;C:=ROL(C+(Axor(Band(DxorA)))+x[3]+MD5_SINE[27],14)+D;B:=ROL(B+(Dxor(Aand(CxorD)))+x[8]+MD5_SINE[28],20)+C;A:=ROL(A+(Cxor(Dand(BxorC)))+x[13]+MD5_SINE[29],5)+B;D:=ROL(D+(Bxor(Cand(AxorB)))+x[2]+MD5_SINE[30],9)+A;C:=ROL(C+(Axor(Band(DxorA)))+x[7]+MD5_SINE[31],14)+D;B:=ROL(B+(Dxor(Aand(CxorD)))+x[12]+MD5_SINE[32],20)+C;{ Round 3. }A:=ROL(A+(BxorCxorD)+x[5]+MD5_SINE[33],4)+B;D:=ROL(D+(AxorBxorC)+x[8]+MD5_SINE[34],11)+A;C:=ROL(C+(DxorAxorB)+x[11]+MD5_SINE[35],16)+D;B:=ROL(B+(CxorDxorA)+x[14]+MD5_SINE[36],23)+C;A:=ROL(A+(BxorCxorD)+x[1]+MD5_SINE[37],4)+B;D:=ROL(D+(AxorBxorC)+x[4]+MD5_SINE[38],11)+A;C:=ROL(C+(DxorAxorB)+x[7]+MD5_SINE[39],16)+D;B:=ROL(B+(CxorDxorA)+x[10]+MD5_SINE[40],23)+C;A:=ROL(A+(BxorCxorD)+x[13]+MD5_SINE[41],4)+B;D:=ROL(D+(AxorBxorC)+x[0]+MD5_SINE[42],11)+A;C:=ROL(C+(DxorAxorB)+x[3]+MD5_SINE[43],16)+D;B:=ROL(B+(CxorDxorA)+x[6]+MD5_SINE[44],23)+C;A:=ROL(A+(BxorCxorD)+x[9]+MD5_SINE[45],4)+B;D:=ROL(D+(AxorBxorC)+x[12]+MD5_SINE[46],11)+A;C:=ROL(C+(DxorAxorB)+x[15]+MD5_SINE[47],16)+D;B:=ROL(B+(CxorDxorA)+x[2]+MD5_SINE[48],23)+C;{ Round 4. }A:=ROL(A+((BornotD)xorC)+x[0]+MD5_SINE[49],6)+B;D:=ROL(D+((AornotC)xorB)+x[7]+MD5_SINE[50],10)+A;C:=ROL(C+((DornotB)xorA)+x[14]+MD5_SINE[51],15)+D;B:=ROL(B+((CornotA)xorD)+x[5]+MD5_SINE[52],21)+C;A:=ROL(A+((BornotD)xorC)+x[12]+MD5_SINE[53],6)+B;D:=ROL(D+((AornotC)xorB)+x[3]+MD5_SINE[54],10)+A;C:=ROL(C+((DornotB)xorA)+x[10]+MD5_SINE[55],15)+D;B:=ROL(B+((CornotA)xorD)+x[1]+MD5_SINE[56],21)+C;A:=ROL(A+((BornotD)xorC)+x[8]+MD5_SINE[57],6)+B;D:=ROL(D+((AornotC)xorB)+x[15]+MD5_SINE[58],10)+A;C:=ROL(C+((DornotB)xorA)+x[6]+MD5_SINE[59],15)+D;B:=ROL(B+((CornotA)xorD)+x[13]+MD5_SINE[60],21)+C;A:=ROL(A+((BornotD)xorC)+x[4]+MD5_SINE[61],6)+B;D:=ROL(D+((AornotC)xorB)+x[11]+MD5_SINE[62],10)+A;C:=ROL(C+((DornotB)xorA)+x[2]+MD5_SINE[63],15)+D;B:=ROL(B+((CornotA)xorD)+x[9]+MD5_SINE[64],21)+C;Inc(FState[0],A);Inc(FState[1],B);Inc(FState[2],C);Inc(FState[3],D);end;{$Q+}{$ENDIF}end.

===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru

Viewing all articles
Browse latest Browse all 78

Trending Articles


Vimeo 10.7.1 by Vimeo.com, Inc.


UPDATE SC IDOL: TWO BECOME ONE


KASAMBAHAY BILL IN THE HOUSE


Girasoles para colorear


Presence Quotes – Positive Quotes


EASY COME, EASY GO


Love with Heart Breaking Quotes


Re:Mutton Pies (lleechef)


Ka longiing longsem kaba skhem bad kaba khlain ka pynlong kein ia ka...


Vimeo 10.7.0 by Vimeo.com, Inc.


FORECLOSURE OF REAL ESTATE MORTGAGE


FORTUITOUS EVENT


Pokemon para colorear


Sapos para colorear


Smile Quotes


Letting Go Quotes


Love Song lyrics that marks your Heart


RE: Mutton Pies (frankie241)


Hato lada ym dei namar ka jingpyrshah jong U JJM Nichols Roy (Bah Joy) ngin...


Long Distance Relationship Tagalog Love Quotes