/*
* Copyright (c) 2006-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:
* software hmac implementation
* software hmac implementation
*
*/
/**
@file
*/
#include "hmacimpl.h"
#include "pluginconfig.h"
#include "md2impl.h"
#include "md5impl.h"
#include "sha1impl.h"
#include "keys.h"
#include "md4impl.h"
using namespace SoftwareCrypto;
CHMacImpl* CHMacImpl::NewL(const CKey& aKey, MSoftwareHash* aHash)
{
CHMacImpl* self=NewLC(aKey, aHash);
CleanupStack::Pop();
return self;
}
CHMacImpl* CHMacImpl::NewLC(const CKey& aKey, MSoftwareHash* aHash)
{
CHMacImpl* self=new(ELeave) CHMacImpl();
CleanupStack::PushL(self);
self->ConstructL(aKey, aHash);
return self;
}
CHMacImpl* CHMacImpl::NewL(MSoftwareHash* aHash)
{
CHMacImpl* self=NewLC(aHash);
CleanupStack::Pop();
return self;
}
CHMacImpl* CHMacImpl::NewLC(MSoftwareHash* aHash)
{
CHMacImpl* self=new(ELeave) CHMacImpl();
CleanupStack::PushL(self);
self->ConstructL(aHash);
return self;
}
CHMacImpl::CHMacImpl()
{
}
CHMacImpl::CHMacImpl(const CHMacImpl& aMD)
: iDigest(NULL), iInnerPad(aMD.iInnerPad),
iOuterPad(aMD.iOuterPad), iBlockSize(aMD.iBlockSize)
{
}
CHMacImpl::~CHMacImpl()
{
if (iDigest)
{
iDigest->Close();
}
}
void CHMacImpl::ConstructL(const CKey& aKey, MSoftwareHash* aHash)
{
//Clone the hash implementation
iDigest=static_cast<MSoftwareHash*>(aHash->ReplicateL());
InitBlockSizeL();
const TDesC8& keyContent=aKey.GetTDesC8L(KHmacKeyParameterUid);
Initialise(keyContent);
}
void CHMacImpl::ConstructL(MSoftwareHash* aHash)
{
//Clone the hash implementation
iDigest=static_cast<MSoftwareHash*>(aHash->ReplicateL());
InitBlockSizeL();
}
void CHMacImpl::InitBlockSizeL()
{
const TCharacteristics* ptr(NULL);
iDigest->GetCharacteristicsL(ptr);
const THashCharacteristics* hashPtr=static_cast<const THashCharacteristics*>(ptr);
iBlockSize = hashPtr->iBlockSize/8;
iInnerPad.SetLength(iBlockSize);
iOuterPad.SetLength(iBlockSize);
iInnerPadCopy.SetLength(iBlockSize);
iOuterPadCopy.SetLength(iBlockSize);
}
void CHMacImpl::Initialise(const TDesC8& aKey)
{
// initialisation
if (iDigest)
{
iDigest->Reset();
if( (TUint32)aKey.Size() > iBlockSize)
{
iInnerPad = iDigest->Final(aKey);
}
else
{
iInnerPad = aKey;
}
TUint i;
for (i=iInnerPad.Size();i<iBlockSize;i++)
iInnerPad.Append(0);
iOuterPad=iInnerPad;
const TUint8 Magic1=0x36, Magic2=0x5c;
for (i=0;i<iBlockSize;i++)
{
iInnerPad[i]^=Magic1;
iOuterPad[i]^=Magic2;
}
//start inner hash
iDigest->Hash(iInnerPad);
}
}
MHash* CHMacImpl::CopyL()
{
CHMacImpl* that=new(ELeave) CHMacImpl(*this);
CleanupStack::PushL(that);
that->iDigest=iDigest ? static_cast<MSoftwareHash*>(iDigest->CopyL()) : NULL;
CleanupStack::Pop();
return that;
}
MHash* CHMacImpl::ReplicateL()
{
CHMacImpl* that=new(ELeave) CHMacImpl(*this);
CleanupStack::PushL(that);
that->iDigest=iDigest ? static_cast<MSoftwareHash*>(iDigest->ReplicateL()) : NULL;
that->Reset();
CleanupStack::Pop();
return that;
}
void CHMacImpl::Reset()
{
if (iDigest)
{
iDigest->Reset();
iDigest->Update(iInnerPad);
}
}
TPtrC8 CHMacImpl::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);
}
void CHMacImpl::Update(const TDesC8& aMessage)
{
if(iDigest)
{
iDigest->Update(aMessage);
}
}
TPtrC8 CHMacImpl::Final(const TDesC8& aMessage)
{
TPtrC8 ptr(KNullDesC8());
if(iDigest)
{
ptr.Set(iDigest->Final(aMessage));
iDigest->Update(iOuterPad);
iDigest->Final(ptr);
Reset();
}
return (ptr);
}
void CHMacImpl::RestoreState()
{
iOuterPad.Copy(iOuterPadCopy);
iInnerPad.Copy(iInnerPadCopy);
if (iDigest)
{
iDigest->RestoreState();
}
}
void CHMacImpl::StoreState()
{
iOuterPadCopy.Copy(iOuterPad);
iInnerPadCopy.Copy(iInnerPad);
if (iDigest)
{
iDigest->StoreState();
}
}
void CHMacImpl::SetKeyL(const CKey& aKey)
{
const TDesC8& keyContent=aKey.GetTDesC8L(KHmacKeyParameterUid);
Initialise(keyContent);
}
void CHMacImpl::Close()
{
delete this;
}
void CHMacImpl::GetCharacteristicsL(const TCharacteristics*& aPluginCharacteristics)
{
iDigest->GetCharacteristicsL(aPluginCharacteristics);
}
const CExtendedCharacteristics* CHMacImpl::GetExtendedCharacteristicsL()
{
return iDigest->GetExtendedCharacteristicsL();
}
// Methods which are not supported can be excluded from the coverage.
#ifdef _BullseyeCoverage
#pragma suppress_warnings on
#pragma BullseyeCoverage off
#pragma suppress_warnings off
#endif
TAny* CHMacImpl::GetExtension(TUid /*aExtensionId*/)
{
return NULL;
}
void CHMacImpl::SetOperationModeL(TUid /*aOperationMode*/)
{
User::Leave(KErrNotSupported);
}