First public contribution.
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
15 * software md4 implementation
16 * software md4 implementation
26 #include <cryptospi/hashplugin.h>
27 #include "pluginconfig.h"
30 using namespace SoftwareCrypto;
33 CMD4Impl* CMD4Impl::NewL()
35 CMD4Impl* self=new (ELeave) CMD4Impl();
40 CMD4Impl* CMD4Impl::NewLC()
42 CMD4Impl* self=NewL();
43 CleanupStack::PushL(self);
47 CMD4Impl::CMD4Impl() : iHash(KMD4HashSize)
51 CMD4Impl::CMD4Impl(const CMD4Impl& aCMD4Impl)
52 : iHash(aCMD4Impl.iHash),iA(aCMD4Impl.iA),iB(aCMD4Impl.iB),iC(aCMD4Impl.iC),iD(aCMD4Impl.iD),
53 iNl(aCMD4Impl.iNl),iNh(aCMD4Impl.iNh)
55 (void)Mem::Copy(iData, aCMD4Impl.iData, sizeof(iData));
62 void CMD4Impl::Reset()
72 void CMD4Impl::Close()
77 void CMD4Impl::GetCharacteristicsL(const TCharacteristics*& aPluginCharacteristics)
79 aPluginCharacteristics=NULL;
80 TInt hashNum=sizeof(KHashCharacteristics)/sizeof(THashCharacteristics*);
81 for (TInt i=0;i<hashNum;i++)
83 if (KHashCharacteristics[i]->cmn.iImplementationUID == ImplementationUid().iUid)
85 aPluginCharacteristics = KHashCharacteristics[i];
91 CExtendedCharacteristics* CMD4Impl::CreateExtendedCharacteristicsL()
93 // All Symbian software plug-ins have unlimited concurrency, cannot be reserved
94 // for exclusive use and are not CERTIFIED to be standards compliant.
95 return CExtendedCharacteristics::NewL(KMaxTInt, EFalse);
97 const CExtendedCharacteristics* CMD4Impl::GetExtendedCharacteristicsL()
99 return CMD4Impl::CreateExtendedCharacteristicsL();
102 TPtrC8 CMD4Impl::Hash(const TDesC8& aMessage)
104 DoUpdate(aMessage.Ptr(),aMessage.Size());
111 void CMD4Impl::Update(const TDesC8& aMessage)
113 DoUpdate(aMessage.Ptr(),aMessage.Size());
116 TPtrC8 CMD4Impl::Final(const TDesC8& aMessage)
118 if (aMessage!=KNullDesC8())
120 DoUpdate(aMessage.Ptr(),aMessage.Size());
127 MHash* CMD4Impl::ReplicateL()
129 return CMD4Impl::NewL();
132 MHash* CMD4Impl::CopyL()
134 return new(ELeave) CMD4Impl(*this);
137 TUid CMD4Impl::ImplementationUid()
139 return KCryptoPluginMd4Uid;
142 void CMD4Impl::DoUpdate(const TUint8* aData,TUint aLength)
144 const TUint8* pend=aData+aLength;
145 for (const TUint8* paData=aData;paData<pend;paData++)
147 const TUint8 byte=*paData;
154 iData[iNl>>2]|=byte<<8;
157 iData[iNl>>2]|=byte<<16;
160 iData[iNl>>2]|=byte<<24;
174 static inline TUint CMD4_F(TUint x,TUint y,TUint z)
176 return (x&y) | (~x&z);
178 static inline TUint CMD4_G(TUint x,TUint y,TUint z)
180 return (x&y) | (x&z) | (y&z);
182 static inline TUint CMD4_H(TUint x,TUint y,TUint z)
189 static inline TUint CMD4_FF(TUint a,const TUint b,const TUint c,const TUint d,const TUint x,const TUint s)
191 a+=CMD4_F(b,c,d) + x;
195 static inline TUint CMD4_GG(TUint a,const TUint b,const TUint c,const TUint d,const TUint x,const TUint s)
197 a+=CMD4_G(b,c,d) + x + (TUint32)0x5a827999;
201 static inline TUint CMD4_HH(TUint a,const TUint b,const TUint c,const TUint d,const TUint x,const TUint s)
203 a+=CMD4_H(b,c,d) + x + (TUint32)0x6ed9eba1;
208 void CMD4Impl::Block()
210 register TUint tempA=iA;
211 register TUint tempB=iB;
212 register TUint tempC=iC;
213 register TUint tempD=iD;
215 tempA = CMD4_FF(tempA,tempB,tempC,tempD,iData[ 0],3);
216 tempD = CMD4_FF(tempD,tempA,tempB,tempC,iData[ 1],7);
217 tempC = CMD4_FF(tempC,tempD,tempA,tempB,iData[ 2],11);
218 tempB = CMD4_FF(tempB,tempC,tempD,tempA,iData[ 3],19);
219 tempA = CMD4_FF(tempA,tempB,tempC,tempD,iData[ 4],3);
220 tempD = CMD4_FF(tempD,tempA,tempB,tempC,iData[ 5],7);
221 tempC = CMD4_FF(tempC,tempD,tempA,tempB,iData[ 6],11);
222 tempB = CMD4_FF(tempB,tempC,tempD,tempA,iData[ 7],19);
223 tempA = CMD4_FF(tempA,tempB,tempC,tempD,iData[ 8],3);
224 tempD = CMD4_FF(tempD,tempA,tempB,tempC,iData[ 9],7);
225 tempC = CMD4_FF(tempC,tempD,tempA,tempB,iData[10],11);
226 tempB = CMD4_FF(tempB,tempC,tempD,tempA,iData[11],19);
227 tempA = CMD4_FF(tempA,tempB,tempC,tempD,iData[12],3);
228 tempD = CMD4_FF(tempD,tempA,tempB,tempC,iData[13],7);
229 tempC = CMD4_FF(tempC,tempD,tempA,tempB,iData[14],11);
230 tempB = CMD4_FF(tempB,tempC,tempD,tempA,iData[15],19);
232 tempA = CMD4_GG(tempA,tempB,tempC,tempD,iData[ 0],3);
233 tempD = CMD4_GG(tempD,tempA,tempB,tempC,iData[ 4],5);
234 tempC = CMD4_GG(tempC,tempD,tempA,tempB,iData[ 8],9);
235 tempB = CMD4_GG(tempB,tempC,tempD,tempA,iData[12],13);
236 tempA = CMD4_GG(tempA,tempB,tempC,tempD,iData[ 1],3);
237 tempD = CMD4_GG(tempD,tempA,tempB,tempC,iData[ 5],5);
238 tempC = CMD4_GG(tempC,tempD,tempA,tempB,iData[ 9],9);
239 tempB = CMD4_GG(tempB,tempC,tempD,tempA,iData[13],13);
240 tempA = CMD4_GG(tempA,tempB,tempC,tempD,iData[ 2],3);
241 tempD = CMD4_GG(tempD,tempA,tempB,tempC,iData[ 6],5);
242 tempC = CMD4_GG(tempC,tempD,tempA,tempB,iData[10],9);
243 tempB = CMD4_GG(tempB,tempC,tempD,tempA,iData[14],13);
244 tempA = CMD4_GG(tempA,tempB,tempC,tempD,iData[ 3],3);
245 tempD = CMD4_GG(tempD,tempA,tempB,tempC,iData[ 7],5);
246 tempC = CMD4_GG(tempC,tempD,tempA,tempB,iData[11],9);
247 tempB = CMD4_GG(tempB,tempC,tempD,tempA,iData[15],13);
249 tempA = CMD4_HH(tempA,tempB,tempC,tempD,iData[ 0],3);
250 tempD = CMD4_HH(tempD,tempA,tempB,tempC,iData[ 8],9);
251 tempC = CMD4_HH(tempC,tempD,tempA,tempB,iData[ 4],11);
252 tempB = CMD4_HH(tempB,tempC,tempD,tempA,iData[12],15);
253 tempA = CMD4_HH(tempA,tempB,tempC,tempD,iData[ 2],3);
254 tempD = CMD4_HH(tempD,tempA,tempB,tempC,iData[10],9);
255 tempC = CMD4_HH(tempC,tempD,tempA,tempB,iData[ 6],11);
256 tempB = CMD4_HH(tempB,tempC,tempD,tempA,iData[14],15);
257 tempA = CMD4_HH(tempA,tempB,tempC,tempD,iData[ 1],3);
258 tempD = CMD4_HH(tempD,tempA,tempB,tempC,iData[ 9],9);
259 tempC = CMD4_HH(tempC,tempD,tempA,tempB,iData[ 5],11);
260 tempB = CMD4_HH(tempB,tempC,tempD,tempA,iData[13],15);
261 tempA = CMD4_HH(tempA,tempB,tempC,tempD,iData[ 3],3);
262 tempD = CMD4_HH(tempD,tempA,tempB,tempC,iData[11],9);
263 tempC = CMD4_HH(tempC,tempD,tempA,tempB,iData[ 7],11);
264 tempB = CMD4_HH(tempB,tempC,tempD,tempA,iData[15],15);
273 #define CMD4_FF(a, b, c, d, x, s) (CMD_R(a += CMD4_F(b,c,d) + x, s))
274 #define CMD4_GG(a, b, c, d, x, s) (CMD_R(a += CMD4_G(b,c,d) + x + (TUint32)0x5a827999, s))
275 #define CMD4_HH(a, b, c, d, x, s) (CMD_R(a += CMD4_H(b,c,d) + x + (TUint32)0x6ed9eba1, s))
276 void CMD4Impl::Block()
278 register TUint tempA=iA;
279 register TUint tempB=iB;
280 register TUint tempC=iC;
281 register TUint tempD=iD;
283 tempA = CMD4_FF(tempA,tempB,tempC,tempD,iData[ 0],3);
284 tempD = CMD4_FF(tempD,tempA,tempB,tempC,iData[ 1],7);
285 tempC = CMD4_FF(tempC,tempD,tempA,tempB,iData[ 2],11);
286 tempB = CMD4_FF(tempB,tempC,tempD,tempA,iData[ 3],19);
287 tempA = CMD4_FF(tempA,tempB,tempC,tempD,iData[ 4],3);
288 tempD = CMD4_FF(tempD,tempA,tempB,tempC,iData[ 5],7);
289 tempC = CMD4_FF(tempC,tempD,tempA,tempB,iData[ 6],11);
290 tempB = CMD4_FF(tempB,tempC,tempD,tempA,iData[ 7],19);
291 tempA = CMD4_FF(tempA,tempB,tempC,tempD,iData[ 8],3);
292 tempD = CMD4_FF(tempD,tempA,tempB,tempC,iData[ 9],7);
293 tempC = CMD4_FF(tempC,tempD,tempA,tempB,iData[10],11);
294 tempB = CMD4_FF(tempB,tempC,tempD,tempA,iData[11],19);
295 tempA = CMD4_FF(tempA,tempB,tempC,tempD,iData[12],3);
296 tempD = CMD4_FF(tempD,tempA,tempB,tempC,iData[13],7);
297 tempC = CMD4_FF(tempC,tempD,tempA,tempB,iData[14],11);
298 tempB = CMD4_FF(tempB,tempC,tempD,tempA,iData[15],19);
300 tempA = CMD4_GG(tempA,tempB,tempC,tempD,iData[ 0],3);
301 tempD = CMD4_GG(tempD,tempA,tempB,tempC,iData[ 4],5);
302 tempC = CMD4_GG(tempC,tempD,tempA,tempB,iData[ 8],9);
303 tempB = CMD4_GG(tempB,tempC,tempD,tempA,iData[12],13);
304 tempA = CMD4_GG(tempA,tempB,tempC,tempD,iData[ 1],3);
305 tempD = CMD4_GG(tempD,tempA,tempB,tempC,iData[ 5],5);
306 tempC = CMD4_GG(tempC,tempD,tempA,tempB,iData[ 9],9);
307 tempB = CMD4_GG(tempB,tempC,tempD,tempA,iData[13],13);
308 tempA = CMD4_GG(tempA,tempB,tempC,tempD,iData[ 2],3);
309 tempD = CMD4_GG(tempD,tempA,tempB,tempC,iData[ 6],5);
310 tempC = CMD4_GG(tempC,tempD,tempA,tempB,iData[10],9);
311 tempB = CMD4_GG(tempB,tempC,tempD,tempA,iData[14],13);
312 tempA = CMD4_GG(tempA,tempB,tempC,tempD,iData[ 3],3);
313 tempD = CMD4_GG(tempD,tempA,tempB,tempC,iData[ 7],5);
314 tempC = CMD4_GG(tempC,tempD,tempA,tempB,iData[11],9);
315 tempB = CMD4_GG(tempB,tempC,tempD,tempA,iData[15],13);
317 tempA = CMD4_HH(tempA,tempB,tempC,tempD,iData[ 0],3);
318 tempD = CMD4_HH(tempD,tempA,tempB,tempC,iData[ 8],9);
319 tempC = CMD4_HH(tempC,tempD,tempA,tempB,iData[ 4],11);
320 tempB = CMD4_HH(tempB,tempC,tempD,tempA,iData[12],15);
321 tempA = CMD4_HH(tempA,tempB,tempC,tempD,iData[ 2],3);
322 tempD = CMD4_HH(tempD,tempA,tempB,tempC,iData[10],9);
323 tempC = CMD4_HH(tempC,tempD,tempA,tempB,iData[ 6],11);
324 tempB = CMD4_HH(tempB,tempC,tempD,tempA,iData[14],15);
325 tempA = CMD4_HH(tempA,tempB,tempC,tempD,iData[ 1],3);
326 tempD = CMD4_HH(tempD,tempA,tempB,tempC,iData[ 9],9);
327 tempC = CMD4_HH(tempC,tempD,tempA,tempB,iData[ 5],11);
328 tempB = CMD4_HH(tempB,tempC,tempD,tempA,iData[13],15);
329 tempA = CMD4_HH(tempA,tempB,tempC,tempD,iData[ 3],3);
330 tempD = CMD4_HH(tempD,tempA,tempB,tempC,iData[11],9);
331 tempC = CMD4_HH(tempC,tempD,tempA,tempB,iData[ 7],11);
332 tempB = CMD4_HH(tempB,tempC,tempD,tempA,iData[15],15);
340 static inline void CMD4_FF(TUint& a,const TUint b,const TUint c,const TUint d,const TUint x,const TUint s)
342 a+=CMD4_F(b,c,d) + x;
345 static inline void CMD4_GG(TUint& a,const TUint b,const TUint c,const TUint d,const TUint x,const TUint s)
347 a+=CMD4_G(b,c,d) + x + (TUint32)0x5a827999;
350 static inline void CMD4_HH(TUint& a,const TUint b,const TUint c,const TUint d,const TUint x,const TUint s)
352 a+=CMD4_H(b,c,d) + x + (TUint32)0x6ed9eba1;
356 void CMD4Impl::Block()
358 register TUint tempA=iA;
359 register TUint tempB=iB;
360 register TUint tempC=iC;
361 register TUint tempD=iD;
363 CMD4_FF(tempA,tempB,tempC,tempD,iData[ 0],3);
364 CMD4_FF(tempD,tempA,tempB,tempC,iData[ 1],7);
365 CMD4_FF(tempC,tempD,tempA,tempB,iData[ 2],11);
366 CMD4_FF(tempB,tempC,tempD,tempA,iData[ 3],19);
367 CMD4_FF(tempA,tempB,tempC,tempD,iData[ 4],3);
368 CMD4_FF(tempD,tempA,tempB,tempC,iData[ 5],7);
369 CMD4_FF(tempC,tempD,tempA,tempB,iData[ 6],11);
370 CMD4_FF(tempB,tempC,tempD,tempA,iData[ 7],19);
371 CMD4_FF(tempA,tempB,tempC,tempD,iData[ 8],3);
372 CMD4_FF(tempD,tempA,tempB,tempC,iData[ 9],7);
373 CMD4_FF(tempC,tempD,tempA,tempB,iData[10],11);
374 CMD4_FF(tempB,tempC,tempD,tempA,iData[11],19);
375 CMD4_FF(tempA,tempB,tempC,tempD,iData[12],3);
376 CMD4_FF(tempD,tempA,tempB,tempC,iData[13],7);
377 CMD4_FF(tempC,tempD,tempA,tempB,iData[14],11);
378 CMD4_FF(tempB,tempC,tempD,tempA,iData[15],19);
380 CMD4_GG(tempA,tempB,tempC,tempD,iData[ 0],3);
381 CMD4_GG(tempD,tempA,tempB,tempC,iData[ 4],5);
382 CMD4_GG(tempC,tempD,tempA,tempB,iData[ 8],9);
383 CMD4_GG(tempB,tempC,tempD,tempA,iData[12],13);
384 CMD4_GG(tempA,tempB,tempC,tempD,iData[ 1],3);
385 CMD4_GG(tempD,tempA,tempB,tempC,iData[ 5],5);
386 CMD4_GG(tempC,tempD,tempA,tempB,iData[ 9],9);
387 CMD4_GG(tempB,tempC,tempD,tempA,iData[13],13);
388 CMD4_GG(tempA,tempB,tempC,tempD,iData[ 2],3);
389 CMD4_GG(tempD,tempA,tempB,tempC,iData[ 6],5);
390 CMD4_GG(tempC,tempD,tempA,tempB,iData[10],9);
391 CMD4_GG(tempB,tempC,tempD,tempA,iData[14],13);
392 CMD4_GG(tempA,tempB,tempC,tempD,iData[ 3],3);
393 CMD4_GG(tempD,tempA,tempB,tempC,iData[ 7],5);
394 CMD4_GG(tempC,tempD,tempA,tempB,iData[11],9);
395 CMD4_GG(tempB,tempC,tempD,tempA,iData[15],13);
397 CMD4_HH(tempA,tempB,tempC,tempD,iData[ 0],3);
398 CMD4_HH(tempD,tempA,tempB,tempC,iData[ 8],9);
399 CMD4_HH(tempC,tempD,tempA,tempB,iData[ 4],11);
400 CMD4_HH(tempB,tempC,tempD,tempA,iData[12],15);
401 CMD4_HH(tempA,tempB,tempC,tempD,iData[ 2],3);
402 CMD4_HH(tempD,tempA,tempB,tempC,iData[10],9);
403 CMD4_HH(tempC,tempD,tempA,tempB,iData[ 6],11);
404 CMD4_HH(tempB,tempC,tempD,tempA,iData[14],15);
405 CMD4_HH(tempA,tempB,tempC,tempD,iData[ 1],3);
406 CMD4_HH(tempD,tempA,tempB,tempC,iData[ 9],9);
407 CMD4_HH(tempC,tempD,tempA,tempB,iData[ 5],11);
408 CMD4_HH(tempB,tempC,tempD,tempA,iData[13],15);
409 CMD4_HH(tempA,tempB,tempC,tempD,iData[ 3],3);
410 CMD4_HH(tempD,tempA,tempB,tempC,iData[11],9);
411 CMD4_HH(tempC,tempD,tempA,tempB,iData[ 7],11);
412 CMD4_HH(tempB,tempC,tempD,tempA,iData[15],15);
422 void CMD4Impl::DoFinal(void)
425 const TUint ul128=128;
429 iData[iNl>>2] = ul128;
432 iData[iNl>>2] += ul128<<8;
435 iData[iNl>>2] += ul128<<16;
438 iData[iNl>>2] += ul128<<24;
448 Mem::FillZ(iData,14*sizeof(TUint));
452 const TUint offset=(iNl+4)>>2;
453 Mem::FillZ(iData+offset,(14-offset)*sizeof(TUint));
456 iData[14]=iNh<<3;//number in bits
457 // this will fail if the total input length is longer than 2^32 in bits
458 //(2^31 in bytes) which is roughly half a gig.
463 // Generate hash value into iHash
466 iHash[0]=(TUint8)(tmp & 255);
467 iHash[1]=(TUint8)((tmp >>= 8) & 255);
468 iHash[2]=(TUint8)((tmp >>= 8) & 255);
469 iHash[3]=(TUint8)((tmp >>= 8) & 255);
472 iHash[4]=(TUint8)(tmp & 255);
473 iHash[5]=(TUint8)((tmp >>= 8) & 255);
474 iHash[6]=(TUint8)((tmp >>= 8) & 255);
475 iHash[7]=(TUint8)((tmp >>= 8) & 255);
478 iHash[8] =(TUint8)(tmp & 255);
479 iHash[9] =(TUint8)((tmp >>= 8) & 255);
480 iHash[10]=(TUint8)((tmp >>= 8) & 255);
481 iHash[11]=(TUint8)((tmp >>= 8) & 255);
484 iHash[12]=(TUint8)(tmp & 255);
485 iHash[13]=(TUint8)((tmp >>= 8) & 255);
486 iHash[14]=(TUint8)((tmp >>= 8) & 255);
487 iHash[15]=(TUint8)((tmp >>= 8) & 255);
490 void CMD4Impl::RestoreState()
498 Mem::Copy(&iData[0], &iDataCopy[0], KMD4BlockSize*sizeof(TUint));
501 void CMD4Impl::StoreState()
509 Mem::Copy(&iDataCopy[0], &iData[0], KMD4BlockSize*sizeof(TUint));
513 // Implemented in hmacimpl.cpp or softwarehashbase.cpp
514 // but required as derived from MHash. No coverage here.
515 #ifdef _BullseyeCoverage
516 #pragma suppress_warnings on
517 #pragma BullseyeCoverage off
518 #pragma suppress_warnings off
521 TAny* CMD4Impl::GetExtension(TUid /*aExtensionId*/)
526 void CMD4Impl::SetOperationModeL(TUid /*aOperationMode*/)
528 User::Leave(KErrNotSupported);
531 void CMD4Impl::SetKeyL(const CKey& /*aKey*/)
533 User::Leave(KErrNotSupported);