Login
`
Templates, Tools and Utilities
|
||
Icetips Article
Back to article list
Search Articles
Add Comment
Printer friendly
Direct link
Windows API: MD5 algorithm 2004-03-17 -- Dan Gorrell Newsgroups: softvelocity.public.clarion6
Here is a piece of a cyptography library that I'm working on. It's going to
be a while before I am able to release the whole thing, so I thought I'd
just toss this out there for free. This procedure takes a string and
computes an RFC compliant MD5 hash.
! MD5FromString -- part of the DanCrypto Clarion Cryptography Library
! Copyright 2004 (C) by Daniel J. Gorrell
! You may use this code freely for personal, commercial, or other purposes so long as this
! copyright notice is maintained within the code. This code may not be redistributed as
! part of a programming library or template without written consent of the author.
MD5FromString PROCEDURE(STRING myString)
InputLen LONG
TargetLen LONG
ResultA CSTRING(9)
ResultB CSTRING(9)
ResultC CSTRING(9)
ResultD CSTRING(9)
Extras LONG
DivTimes LONG
ABuf LONG
BBuf LONG
CBuf LONG
DBuf LONG
AA LONG
BB LONG
CC LONG
DD LONG
myTempLong LONG
myTempBytes GROUP,OVER(myTempLong)
Byte1 BYTE
Byte2 BYTE
Byte3 BYTE
Byte4 BYTE
END
ProcessingString &CSTRING
my64BitLength GROUP
myActualLong ULONG
myPaddingLong ULONG
END
my64BitChars STRING(8),OVER(my64BitLength)
myXBytes STRING(64)
myXLongs ULONG,DIM(16),OVER(myXBytes)
retval STRING(32)
CODE
!STEP 1 - Append padding bits
!Get original string size
InputLen = LEN(myString)
!Determine the size of the target string
IF InputLen > 55 THEN
IF InputLen > 64 THEN
DivTimes = ABS(InputLen/64)
Extras = (InputLen - (DivTimes * 64))
IF Extras > 55 THEN
TargetLen = InputLen + (120 - Extras)
ELSE
TargetLen = InputLen + (56 - Extras)
END
ELSE
TargetLen = InputLen + (120 - InputLen)
END
ELSE
TargetLen = InputLen + (56 - InputLen)
END
!Create CString that is TargetLen + 8 Bytes (for length)
ProcessingString &= NEW(CSTRING(TargetLen + 8))
!Null out entire string (to add 0-bit padding)
memset(ADDRESS(ProcessingString),00000000b,SIZE(ProcessingString))
!Copy original string into CString for processing
ProcessingString[1:InputLen] = myString[1:InputLen]
!Add one-bit padding byte to CString
ProcessingString[InputLen+1] = CHR(128) !128 is base10 for 10000000b
!STEP 2 - Append 64 bit representation of original message length to end
my64BitLength.myPaddingLong = 00000000h
my64BitLength.myActualLong = (InputLen * 8)
ProcessingString[TargetLen+1:TargetLen+8] = my64BitChars[1:8]
!STEP 3 - Initialize MD Buffers
ABuf = 1732584193
BBuf = -271733879
CBuf = -1732584194
DBuf = 271733878
!STEP 4 - Process Message in 16-Word (LONG) Blocks
LOOP i# = 64 TO SIZE(ProcessingString) BY 64
!Clear our processing buffer
memset(ADDRESS(myXBytes),00000000b,64)
!Load in 16 LONGS / 64 CHARS
myXBytes[1:64] = ProcessingString[(i#-63):i#]
LOOP j# = 1 TO 16 BY 1
myTempLong = 0000h
myTempLong = BOR(myTempLong, BSHIFT(VAL( |
ProcessingString[((i#-63)+(((J#-1)*4)+0))]),0))
myTempLong = BOR(myTempLong, BSHIFT(VAL( |
ProcessingString[((i#-63)+(((J#-1)*4)+1))]),8))
myTempLong = BOR(myTempLong, BSHIFT(VAL( |
ProcessingString[((i#-63)+(((J#-1)*4)+2))]),16))
myTempLong = BOR(myTempLong, BSHIFT(VAL( |
ProcessingString[((i#-63)+(((J#-1)*4)+3))]),24))
myXLongs[j#] = myTempLong
END
AA = ABuf
BB = BBuf
CC = CBuf
DD = DBuf
SELF.MD5_FF(ABuf, BBuf, CBuf, DBuf, myXLongs[1], 7, -680876936)
SELF.MD5_FF(DBuf, ABuf, BBuf, CBuf, myXLongs[2], 12, -389564586)
SELF.MD5_FF(CBuf, DBuf, ABuf, BBuf, myXLongs[3], 17, 606105819)
SELF.MD5_FF(BBuf, CBuf, DBuf, ABuf, myXLongs[4], 22, -1044525330)
SELF.MD5_FF(ABuf, BBuf, CBuf, DBuf, myXLongs[5], 7, -176418897)
SELF.MD5_FF(DBuf, ABuf, BBuf, CBuf, myXLongs[6], 12, 1200080426)
SELF.MD5_FF(CBuf, DBuf, ABuf, BBuf, myXLongs[7], 17, -1473231341)
SELF.MD5_FF(BBuf, CBuf, DBuf, ABuf, myXLongs[8], 22, -45705983)
SELF.MD5_FF(ABuf, BBuf, CBuf, DBuf, myXLongs[9], 7, 1770035416)
SELF.MD5_FF(DBuf, ABuf, BBuf, CBuf, myXLongs[10], 12, -1958414417)
SELF.MD5_FF(CBuf, DBuf, ABuf, BBuf, myXLongs[11], 17, -42063)
SELF.MD5_FF(BBuf, CBuf, DBuf, ABuf, myXLongs[12], 22, -1990404162)
SELF.MD5_FF(ABuf, BBuf, CBuf, DBuf, myXLongs[13], 7, 1804603682)
SELF.MD5_FF(DBuf, ABuf, BBuf, CBuf, myXLongs[14], 12, -40341101)
SELF.MD5_FF(CBuf, DBuf, ABuf, BBuf, myXLongs[15], 17, -1502002290)
SELF.MD5_FF(BBuf, CBuf, DBuf, ABuf, myXLongs[16], 22, 1236535329)
SELF.MD5_GG(ABuf, BBuf, CBuf, DBuf, myXLongs[2], 5, -165796510)
SELF.MD5_GG(DBuf, ABuf, BBuf, CBuf, myXLongs[7], 9, -1069501632)
SELF.MD5_GG(CBuf, DBuf, ABuf, BBuf, myXLongs[12], 14, 643717713)
SELF.MD5_GG(BBuf, CBuf, DBuf, ABuf, myXLongs[1], 20, -373897302)
SELF.MD5_GG(ABuf, BBuf, CBuf, DBuf, myXLongs[6], 5, -701558691)
SELF.MD5_GG(DBuf, ABuf, BBuf, CBuf, myXLongs[11], 9, 38016083)
SELF.MD5_GG(CBuf, DBuf, ABuf, BBuf, myXLongs[16], 14, -660478335)
SELF.MD5_GG(BBuf, CBuf, DBuf, ABuf, myXLongs[5], 20, -405537848)
SELF.MD5_GG(ABuf, BBuf, CBuf, DBuf, myXLongs[10], 5, 568446438)
SELF.MD5_GG(DBuf, ABuf, BBuf, CBuf, myXLongs[15], 9, -1019803690)
SELF.MD5_GG(CBuf, DBuf, ABuf, BBuf, myXLongs[4], 14, -187363961)
SELF.MD5_GG(BBuf, CBuf, DBuf, ABuf, myXLongs[9], 20, 1163531501)
SELF.MD5_GG(ABuf, BBuf, CBuf, DBuf, myXLongs[14], 5, -1444681467)
SELF.MD5_GG(DBuf, ABuf, BBuf, CBuf, myXLongs[3], 9, -51403784)
SELF.MD5_GG(CBuf, DBuf, ABuf, BBuf, myXLongs[8], 14, 1735328473)
SELF.MD5_GG(BBuf, CBuf, DBuf, ABuf, myXLongs[13], 20, -1926607734)
SELF.MD5_HH(ABuf, BBuf, CBuf, DBuf, myXLongs[6], 4, -378558)
SELF.MD5_HH(DBuf, ABuf, BBuf, CBuf, myXLongs[9], 11, -2022574463)
SELF.MD5_HH(CBuf, DBuf, ABuf, BBuf, myXLongs[12], 16, 1839030562)
SELF.MD5_HH(BBuf, CBuf, DBuf, ABuf, myXLongs[15], 23, -35309556)
SELF.MD5_HH(ABuf, BBuf, CBuf, DBuf, myXLongs[2], 4, -1530992060)
SELF.MD5_HH(DBuf, ABuf, BBuf, CBuf, myXLongs[5], 11, 1272893353)
SELF.MD5_HH(CBuf, DBuf, ABuf, BBuf, myXLongs[8], 16, -155497632)
SELF.MD5_HH(BBuf, CBuf, DBuf, ABuf, myXLongs[11], 23, -1094730640)
SELF.MD5_HH(ABuf, BBuf, CBuf, DBuf, myXLongs[14], 4, 681279174)
SELF.MD5_HH(DBuf, ABuf, BBuf, CBuf, myXLongs[1], 11, -358537222)
SELF.MD5_HH(CBuf, DBuf, ABuf, BBuf, myXLongs[4], 16, -722521979)
SELF.MD5_HH(BBuf, CBuf, DBuf, ABuf, myXLongs[7], 23, 76029189)
SELF.MD5_HH(ABuf, BBuf, CBuf, DBuf, myXLongs[10], 4, -640364487)
SELF.MD5_HH(DBuf, ABuf, BBuf, CBuf, myXLongs[13], 11, -421815835)
SELF.MD5_HH(CBuf, DBuf, ABuf, BBuf, myXLongs[16], 16, 530742520)
SELF.MD5_HH(BBuf, CBuf, DBuf, ABuf, myXLongs[3], 23, -995338651)
SELF.MD5_II(ABuf, BBuf, CBuf, DBuf, myXLongs[1], 6, -198630844)
SELF.MD5_II(DBuf, ABuf, BBuf, CBuf, myXLongs[8], 10, 1126891415)
SELF.MD5_II(CBuf, DBuf, ABuf, BBuf, myXLongs[15], 15, -1416354905)
SELF.MD5_II(BBuf, CBuf, DBuf, ABuf, myXLongs[6], 21, -57434055)
SELF.MD5_II(ABuf, BBuf, CBuf, DBuf, myXLongs[13], 6, 1700485571)
SELF.MD5_II(DBuf, ABuf, BBuf, CBuf, myXLongs[4], 10, -1894986606)
SELF.MD5_II(CBuf, DBuf, ABuf, BBuf, myXLongs[11], 15, -1051523)
SELF.MD5_II(BBuf, CBuf, DBuf, ABuf, myXLongs[2], 21, -2054922799)
SELF.MD5_II(ABuf, BBuf, CBuf, DBuf, myXLongs[9], 6, 1873313359)
SELF.MD5_II(DBuf, ABuf, BBuf, CBuf, myXLongs[16], 10, -30611744)
SELF.MD5_II(CBuf, DBuf, ABuf, BBuf, myXLongs[7], 15, -1560198380)
SELF.MD5_II(BBuf, CBuf, DBuf, ABuf, myXLongs[14], 21, 1309151649)
SELF.MD5_II(ABuf, BBuf, CBuf, DBuf, myXLongs[5], 6, -145523070)
SELF.MD5_II(DBuf, ABuf, BBuf, CBuf, myXLongs[12], 10, -1120210379)
SELF.MD5_II(CBuf, DBuf, ABuf, BBuf, myXLongs[3], 15, 718787259)
SELF.MD5_II(BBuf, CBuf, DBuf, ABuf, myXLongs[10], 21, -343485551)
ABuf += AA
BBuf += BB
CBuf += CC
DBuf += DD
END
LtoA(ABuf,ResultA,16)
LtoA(BBuf,ResultB,16)
LtoA(CBuf,ResultC,16)
LtoA(DBuf,ResultD,16)
IF LEN(ResultA) < 8 THEN
LOOP i# = 1 TO (8 - LEN(ResultA)) BY 1
ResultA = '0' & ResultA
END
END
IF LEN(ResultB) < 8 THEN
LOOP i# = 1 TO (8 - LEN(ResultB)) BY 1
ResultB = '0' & ResultB
END
END
IF LEN(ResultC) < 8 THEN
LOOP i# = 1 TO (8 - LEN(ResultC)) BY 1
ResultC = '0' & ResultC
END
END
IF LEN(ResultD) < 8 THEN
LOOP i# = 1 TO (8 - LEN(ResultD)) BY 1
ResultD = '0' & ResultD
END
END
retval = ResultA[7:8] & ResultA[5:6] & ResultA[3:4] & ResultA[1:2] & |
ResultB[7:8] & ResultB[5:6] & ResultB[3:4] & ResultB[1:2] & |
ResultC[7:8] & ResultC[5:6] & ResultC[3:4] & ResultC[1:2] & |
ResultD[7:8] & ResultD[5:6] & ResultD[3:4] & ResultD[1:2]
DISPOSE(ProcessingString)
ProcessingString &= NULL
RETURN(retval)
You'll need the following in your map.
MODULE('runtime library')
LtoA(LONG,*CSTRING,SIGNED),ULONG,RAW,NAME('_ltoa'),PROC
memcpy(LONG,LONG,UNSIGNED),NAME('_memcpy')
memset(LONG,LONG,UNSIGNED),NAME('_memset')
END
You'll need to rename them to procedures instead of methods, and change the calls in the main procedure
so they don't reference SELF.
DanCrypt.MD5_FF PROCEDURE(*LONG mya, LONG myb, LONG myc,
LONG myd, LONG myx, LONG mys, LONG myac)
CODE
mya = myb + SELF.MD5_RotateLeft((mya + BOR((BAND(myb,myc)),|
(BAND(BXOR(myb,-1),myd))) + |
myx + myac),mys)
RETURN
DanCrypt.MD5_GG PROCEDURE(*LONG mya, LONG myb, LONG myc, |
LONG myd, LONG myx, LONG mys, |
LONG myac)
CODE
mya = myb + SELF.MD5_RotateLeft((mya + BOR((BAND(myb,myd)),|
(BAND(myc,(BXOR(myd,-1))))) + |
myx + myac),mys)
RETURN
DanCrypt.MD5_HH PROCEDURE(*LONG mya, LONG myb, LONG myc, |
LONG myd, LONG myx, LONG mys, |
LONG myac)
CODE
mya = myb + SELF.MD5_RotateLeft((mya + BXOR((BXOR(myb,myc)),myd) + |
myx + myac),mys)
RETURN
DanCrypt.MD5_II PROCEDURE(*LONG mya, LONG myb, LONG myc, |
LONG myd, LONG myx, LONG mys, |
LONG myac)
CODE
mya = myb + SELF.MD5_RotateLeft((mya + BXOR(myc,(BOR(myb,|
(BXOR(myd,-1))))) + |
myx + myac),mys)
RETURN
DanCrypt.MD5_RotateLeft PROCEDURE(LONG lValue, LONG iShiftBits)
retval LONG
CODE
retval = (BOR(BSHIFT(lValue,iShiftBits),|
BSHIFT(lValue, (-1 * (32 - iShiftBits)))))
RETURN(retval)
Today is November 21, 2024, 4:00 am This article has been viewed 35208 times. Google search has resulted in 280 hits on this article since January 25, 2004.
|
|