diff -r da2ae96f639b -r cd501b96611d crypto/weakcryptospi/source/hash/hmac.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypto/weakcryptospi/source/hash/hmac.cpp Fri Nov 06 13:21:00 2009 +0200 @@ -0,0 +1,256 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include +#include +#include +#include +#include +#include "hashshim.h" + + +#define EXPANDLOOP + +// +// HMAC implementation +// + +CHMAC::CHMAC() + { + } + + +CHMAC::CHMAC(CMessageDigest* aDigest) + :CMessageDigest(), + iDigest(aDigest), + iInnerPad(KMaxBlockSize), + iOuterPad(KMaxBlockSize) + { + } + +CHMAC::CHMAC(const CHMAC& aMD) + :CMessageDigest(aMD), + iDigest(NULL), + iInnerPad(aMD.iInnerPad), + iOuterPad(aMD.iOuterPad), + iBlockSize(aMD.iBlockSize) + { + } + +EXPORT_C CHMAC::~CHMAC(void) + { + delete iDigest; + } + +EXPORT_C CHMAC* CHMAC::NewL(const TDesC8& aKey,CMessageDigest* aDigest) + { + CHMAC* self = CHMACShim::NewL(aKey, aDigest); + if (! self) + { + // not able to use CryptoSpi, possibly due to an exterally + // derived legacy class so fallback to old implementation. + self=new(ELeave) CHMAC(aDigest); + CleanupStack::PushL(self); + self->InitialiseL(aKey); + CleanupStack::Pop(self); + } + return self; + } + + +// These methods are now deprecated. This is because hashes and HMACs +// should be implemented as plugins to the SPI framework. However, for +// binary compatibility reasons, these methods must be left here. +// There are no tests (hence no coverage) for HMACs outside the plugin +// framework, but this original code is left unmodified. +// +#ifdef _BullseyeCoverage +#pragma suppress_warnings on +#pragma BullseyeCoverage off +#pragma suppress_warnings off +#endif + + +void CHMAC::InitialiseL(const TDesC8& aKey) + { + InitBlockSizeL(); + // initialisation + if (iDigest) + { + iDigest->Reset(); + if( (TUint32)aKey.Size() > iBlockSize) + { + iInnerPad = iDigest->Final(aKey); + } + else + { + iInnerPad = aKey; + } + + TUint i; + for (i=iInnerPad.Size();iHash(iInnerPad); + } + } + +void CHMAC::InitBlockSizeL() + { + if (iDigest) + { + iBlockSize = iDigest->BlockSize(); + } + if(iBlockSize > KMaxBlockSize) + { + User::Leave(KErrNotSupported); + } + + iInnerPad.SetLength(iBlockSize); + iOuterPad.SetLength(iBlockSize); + iInnerPadCopy.SetLength(iBlockSize); + iOuterPadCopy.SetLength(iBlockSize); + } + +EXPORT_C CMessageDigest* CHMAC::CopyL(void) + { + CHMAC* that=new(ELeave) CHMAC(*this); + CleanupStack::PushL(that); + that->iDigest=iDigest ? iDigest->CopyL() : NULL; + CleanupStack::Pop(); + return that; + } + +EXPORT_C CMessageDigest* CHMAC::ReplicateL(void) + { + CHMAC* that=new(ELeave) CHMAC(*this); + CleanupStack::PushL(that); + that->iDigest=iDigest ? iDigest->ReplicateL() : NULL; + that->Reset(); + CleanupStack::Pop(); + return that; + } + +EXPORT_C TInt CHMAC::BlockSize(void) + { + return iBlockSize; + } + +EXPORT_C TInt CHMAC::HashSize(void) + { + return iDigest ? iDigest->HashSize() : 0; + } + +EXPORT_C void CHMAC::Reset(void) + { + if (iDigest) + { + iDigest->Reset(); + iDigest->Update(iInnerPad); + } + } + +// JCS, There may be a more efficient method but I can't find it +// because using the DoFinal/DoUpdate functions directly calls +// Store/Restore at inappropriate times and scribbles over stored +// data +// This is the only way I've found to both generate a hash value +// and get this in the correctly updated state +EXPORT_C TPtrC8 CHMAC::Hash(const TDesC8& aMessage) + { + TPtrC8 ptr(KNullDesC8()); + TPtrC8 finalPtr(KNullDesC8()); + StoreState(); + if (iDigest) + { + ptr.Set(iDigest->Final(aMessage)); + iDigest->Update(iOuterPad); + finalPtr.Set(iDigest->Final(ptr)); + } + + RestoreState(); + + if(iDigest) + { + iDigest->Update(aMessage); + } + + return (finalPtr); + } + +EXPORT_C void CHMAC::Update(const TDesC8& aMessage) + { + if(iDigest) + { + iDigest->Update(aMessage); + } + } + +EXPORT_C TPtrC8 CHMAC::Final(const TDesC8& aMessage) + { + TPtrC8 ptr(KNullDesC8()); + if(iDigest) + { + ptr.Set(iDigest->Final(aMessage)); + iDigest->Update(iOuterPad); + iDigest->Final(ptr); + Reset(); + } + return (ptr); + } + +EXPORT_C TPtrC8 CHMAC::Final() + { + TPtrC8 ptr(KNullDesC8()); + if(iDigest) + { + ptr.Set(iDigest->Final()); + iDigest->Update(iOuterPad); + iDigest->Final(ptr); + Reset(); + } + return (ptr); + } + +void CHMAC::RestoreState() + { + iOuterPad.Copy(iOuterPadCopy); + iInnerPad.Copy(iInnerPadCopy); + if (iDigest) + iDigest->RestoreState(); + } + +void CHMAC::StoreState() + { + iOuterPadCopy.Copy(iOuterPad); + iInnerPadCopy.Copy(iInnerPad); + if (iDigest) + iDigest->StoreState(); + } + +