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