crypto/weakcrypto/source/hash/md2.cpp
changeset 71 dd83586b62d6
equal deleted inserted replaced
66:8873e6835f7b 71:dd83586b62d6
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 * (c) 2003 Symbian Ltd.  All rights reserved.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 /**
       
    21  @file
       
    22 */
       
    23 
       
    24 #include <e32std.h>
       
    25 #include <hash.h>
       
    26 
       
    27 #define EXPANDLOOP
       
    28 
       
    29 //
       
    30 // 32bit endianness independent MD2 implementation
       
    31 //
       
    32 CMD2::CMD2(void)
       
    33 : CMessageDigest(),iHash(MD2_HASH)
       
    34 	{
       
    35 	}
       
    36 CMD2::CMD2(const CMD2& aMD)
       
    37 : CMessageDigest(aMD),iHash(aMD.iHash),iNum(aMD.iNum)
       
    38 	{
       
    39 	(void)Mem::Copy(iData,aMD.iData,sizeof(iData));
       
    40 	(void)Mem::Copy(iChecksum,aMD.iChecksum,sizeof(iChecksum));
       
    41 	(void)Mem::Copy(iState,aMD.iState,sizeof(iState));
       
    42 	}
       
    43 EXPORT_C CMD2* CMD2::NewL(void)
       
    44 	{
       
    45 	return (new(ELeave) CMD2);
       
    46 	}
       
    47 EXPORT_C CMessageDigest* CMD2::ReplicateL(void)
       
    48 	{
       
    49 	return NewL();
       
    50 	}
       
    51 EXPORT_C CMD2::~CMD2(void)
       
    52 	{
       
    53 	}
       
    54 
       
    55 EXPORT_C TPtrC8 CMD2::Hash(const TDesC8& aMessage)
       
    56 	{
       
    57 	TPtrC8 ptr(KNullDesC8());
       
    58 	DoUpdate(aMessage.Ptr(),aMessage.Size());
       
    59 	StoreState();	
       
    60 	DoFinal();
       
    61 	ptr.Set(iHash);
       
    62 	RestoreState();	
       
    63 	return ptr;
       
    64 	}
       
    65 
       
    66 EXPORT_C CMessageDigest* CMD2::CopyL(void)
       
    67 	{
       
    68 	return new(ELeave) CMD2(*this);
       
    69 	}
       
    70 EXPORT_C TInt CMD2::BlockSize(void)
       
    71 	{
       
    72 	return sizeof(iData);
       
    73 	}
       
    74 EXPORT_C TInt CMD2::HashSize(void)
       
    75 	{
       
    76 	return MD2_HASH;
       
    77 	}
       
    78 EXPORT_C void CMD2::Reset(void)
       
    79 	{
       
    80 	Mem::FillZ(iData,sizeof(iData));
       
    81 	Mem::FillZ(iChecksum,sizeof(iChecksum));
       
    82 	Mem::FillZ(iState,sizeof(iState));
       
    83 	iNum=0;
       
    84 	}
       
    85 
       
    86 EXPORT_C void CMD2::Update(const TDesC8& aMessage)
       
    87 	{
       
    88 	DoUpdate(aMessage.Ptr(),aMessage.Size());
       
    89 	}
       
    90 
       
    91 EXPORT_C TPtrC8 CMD2::Final(const TDesC8& aMessage)
       
    92 	{
       
    93 	TPtrC8 ptr(KNullDesC8());
       
    94 	DoUpdate(aMessage.Ptr(),aMessage.Size());
       
    95 	DoFinal();
       
    96 	ptr.Set(iHash);
       
    97 	Reset();
       
    98 	return ptr;
       
    99 	}
       
   100 
       
   101 EXPORT_C TPtrC8 CMD2::Final()
       
   102 	{
       
   103 	TPtrC8 ptr(KNullDesC8());
       
   104 	DoFinal();
       
   105 	ptr.Set(iHash);
       
   106 	Reset();
       
   107 	return ptr;
       
   108 	}
       
   109 
       
   110 void CMD2::DoUpdate(const TUint8* aData,TUint aLength)
       
   111 	{
       
   112 	TBool carryOn=ETrue;
       
   113 	if (iNum)
       
   114 		{
       
   115 		if (iNum+aLength>=(TUint)MD2_BLOCK)
       
   116 			{
       
   117 			const TUint temp=MD2_BLOCK-iNum;
       
   118 			(void)Mem::Copy(iData+iNum,aData,temp);
       
   119 			Block(iData);
       
   120 			aData+=temp;
       
   121 			aLength-=temp;
       
   122 			iNum=0;
       
   123 			}
       
   124 		else
       
   125 			{
       
   126 			(void)Mem::Copy(iData+iNum,aData,aLength);
       
   127 			iNum+=aLength;
       
   128 			carryOn=EFalse;
       
   129 			}
       
   130 		}
       
   131 	// processing by block of MD2_BLOCK
       
   132 	if (carryOn)
       
   133 		{
       
   134 		while (aLength>=(TUint)MD2_BLOCK)
       
   135 			{
       
   136 			Block(aData);
       
   137 			aData+=MD2_BLOCK;
       
   138 			aLength-=MD2_BLOCK;
       
   139 			}
       
   140 		(void)Mem::Copy(iData,aData,aLength);
       
   141 		iNum=aLength;
       
   142 		}
       
   143 	}
       
   144 static inline TUint CMD2_S(TUint& elt,TUint8 val)
       
   145 	{
       
   146 	return elt^=val;
       
   147 	}
       
   148 // 
       
   149 // data must be MD2_BLOCK bytes long
       
   150 //
       
   151 void CMD2::Block(const TUint8* data)
       
   152 	{
       
   153 	static const TUint8 S[256]={
       
   154 		0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01,
       
   155 		0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
       
   156 		0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
       
   157 		0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
       
   158 		0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
       
   159 		0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
       
   160 		0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49,
       
   161 		0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
       
   162 		0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
       
   163 		0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
       
   164 		0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27,
       
   165 		0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
       
   166 		0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1,
       
   167 		0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
       
   168 		0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
       
   169 		0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
       
   170 		0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20,
       
   171 		0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
       
   172 		0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6,
       
   173 		0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
       
   174 		0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
       
   175 		0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
       
   176 		0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09,
       
   177 		0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
       
   178 		0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
       
   179 		0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
       
   180 		0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
       
   181 		0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
       
   182 		0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4,
       
   183 		0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
       
   184 		0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A,
       
   185 		0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14,
       
   186 		};
       
   187 	TUint state[MD2_BLOCK*3];
       
   188 	TUint j=iChecksum[MD2_BLOCK-1];
       
   189 	TUint i=0,temp=0;
       
   190 	while (i<(TUint)MD2_BLOCK)
       
   191 		{
       
   192 		const TUint tempState=iState[i];
       
   193 		temp=data[i];
       
   194 		state[i]=tempState;
       
   195 		state[i+16]=temp;
       
   196 		state[i+32]=temp^tempState;
       
   197 		j=CMD2_S(iChecksum[i++],S[temp^j]);
       
   198 		}
       
   199 	temp=0;
       
   200 	TUint* pstate=state;
       
   201 	const TUint *pend=state+(MD2_BLOCK*3);
       
   202 	for (i=0; i<18; i++)
       
   203 		{
       
   204 		while (pstate<pend)
       
   205 			{
       
   206 			temp=CMD2_S(*pstate,S[temp]);pstate++;
       
   207 			temp=CMD2_S(*pstate,S[temp]);pstate++;
       
   208 			temp=CMD2_S(*pstate,S[temp]);pstate++;
       
   209 			temp=CMD2_S(*pstate,S[temp]);pstate++;
       
   210 			temp=CMD2_S(*pstate,S[temp]);pstate++;
       
   211 			temp=CMD2_S(*pstate,S[temp]);pstate++;
       
   212 			temp=CMD2_S(*pstate,S[temp]);pstate++;
       
   213 			temp=CMD2_S(*pstate,S[temp]);pstate++;
       
   214 			}
       
   215 		pstate=state;
       
   216 		temp=(temp+i)&0xff;
       
   217 		}
       
   218 	(void)Mem::Copy(iState,state,MD2_BLOCK*sizeof(TUint));
       
   219 	}
       
   220 void CMD2::DoFinal()
       
   221 	{
       
   222 	const TUint pad=MD2_BLOCK-iNum;
       
   223 	if (pad>0)
       
   224 		Mem::Fill(iData+iNum,(TUint8)pad,pad);
       
   225 	Block(iData);
       
   226 
       
   227 	TUint8* pData=iData;
       
   228 	const TUint8* pEnd=iData+MD2_BLOCK;
       
   229 	const TUint* pChecksum=iChecksum;
       
   230 	while (pData<pEnd)
       
   231 		{
       
   232 		*pData=(TUint8)*pChecksum;//checksum is always less than 255 
       
   233 		pData++;
       
   234 		pChecksum++;
       
   235 		}
       
   236 	Block(iData);
       
   237 
       
   238 	TUint* pState=iState;
       
   239 	for (TUint i=0;i<(TUint)MD2_BLOCK;i++,pState++) //safe: iState and iHash have got same size
       
   240 		iHash[i]=(TUint8)(*pState&0xff);
       
   241 	}
       
   242 
       
   243 void CMD2::RestoreState()
       
   244 {
       
   245 	Mem::Copy(&iData[0], &iDataTemp[0], MD2_BLOCK);
       
   246 	Mem::Copy(&iChecksum[0], &iChecksumTemp[0], MD2_BLOCK*sizeof(TUint));
       
   247 	Mem::Copy(&iState[0], &iStateTemp[0], MD2_BLOCK*sizeof(TUint));
       
   248 }
       
   249 
       
   250 void CMD2::StoreState()
       
   251 {
       
   252 	Mem::Copy(&iDataTemp[0], &iData[0], MD2_BLOCK);
       
   253 	Mem::Copy(&iChecksumTemp[0], &iChecksum[0], MD2_BLOCK*sizeof(TUint));
       
   254 	Mem::Copy(&iStateTemp[0], &iState[0], MD2_BLOCK*sizeof(TUint));
       
   255 }
       
   256