--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/crypto/weakcryptospi/source/hash/hashshim.cpp Fri Nov 06 13:21:00 2009 +0200
@@ -0,0 +1,856 @@
+/*
+* 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:
+* hash shim implementation
+* hash shim implementation
+*
+*/
+
+
+/**
+ @file
+*/
+
+#include "hashshim.h"
+#include <cryptospi/cryptospidef.h>
+#include <cryptospi/plugincharacteristics.h>
+#include "keys.h"
+
+
+using namespace CryptoSpi;
+
+//
+// MD2 shim implementation
+//
+CMD2Shim* CMD2Shim::NewL()
+ {
+ CMD2Shim* self=CMD2Shim::NewLC();
+ CleanupStack::Pop();
+ return self;
+ }
+
+CMD2Shim* CMD2Shim::NewLC()
+ {
+ CMD2Shim* self=new(ELeave) CMD2Shim();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+TInt CMD2Shim::Extension_(TUint aExtensionId, TAny*& a0, TAny* /*a1*/)
+ {
+ TInt ret(KErrNotSupported);
+
+ if (KHashInterfaceUid.iUid==aExtensionId && iHashImpl)
+ {
+ a0=iHashImpl;
+ ret=KErrNone;
+ }
+
+ return ret;
+ }
+
+CMD2Shim::CMD2Shim()
+ {
+ }
+
+CMD2Shim::~CMD2Shim()
+ {
+ delete iHashImpl;
+ }
+
+
+void CMD2Shim::ConstructL()
+ {
+ CHashFactory::CreateHashL(iHashImpl,
+ KMd2Uid,
+ KHashModeUid,
+ NULL, NULL);
+ }
+
+CMessageDigest* CMD2Shim::CopyL()
+ {
+ CMD2Shim* copy=new(ELeave) CMD2Shim();
+ CleanupStack::PushL(copy);
+ copy->iHashImpl=iHashImpl->CopyL();
+ CleanupStack::Pop();
+ return copy;
+ }
+
+CMessageDigest* CMD2Shim::ReplicateL()
+ {
+ CMD2Shim* copy=new(ELeave) CMD2Shim();
+ CleanupStack::PushL(copy);
+ copy->iHashImpl=iHashImpl->ReplicateL();
+ CleanupStack::Pop();
+ return copy;
+ }
+
+
+TInt CMD2Shim::BlockSize()
+ {
+ const TCharacteristics* ptr(NULL);
+ TRAPD(err, iHashImpl->GetCharacteristicsL(ptr);)
+
+ if (err)
+ {
+ return ((err>0)? KErrGeneral : err);
+ }
+ const THashCharacteristics* hashPtr=static_cast<const THashCharacteristics*>(ptr);
+ return hashPtr->iBlockSize/8;
+ }
+
+TInt CMD2Shim::HashSize()
+ {
+ const TCharacteristics* ptr(NULL);
+ TRAPD(err, iHashImpl->GetCharacteristicsL(ptr);)
+ if (err)
+ {
+ return ((err>0)? KErrGeneral : err);
+ }
+ const THashCharacteristics* hashPtr=static_cast<const THashCharacteristics*>(ptr);
+ return hashPtr->iOutputSize/8;
+ }
+
+void CMD2Shim::Update(const TDesC8& aMessage)
+ {
+ iHashImpl->Update(aMessage);
+ }
+
+
+TPtrC8 CMD2Shim::Final(const TDesC8& aMessage)
+ {
+ return iHashImpl->Final(aMessage);
+ }
+
+TPtrC8 CMD2Shim::Final()
+ {
+ TPtrC8 ptr(KNullDesC8());
+ return iHashImpl->Final(ptr);
+ }
+
+void CMD2Shim::Reset()
+ {
+ iHashImpl->Reset();
+ }
+
+
+TPtrC8 CMD2Shim::Hash(const TDesC8& aMessage)
+ {
+ return iHashImpl->Hash(aMessage);
+ }
+
+//
+// Implementation of MD5 shim
+//
+CMD5Shim* CMD5Shim::NewL()
+ {
+ CMD5Shim* self=CMD5Shim::NewLC();
+ CleanupStack::Pop();
+ return self;
+ }
+
+CMD5Shim* CMD5Shim::NewLC()
+ {
+
+ CMD5Shim* self=new(ELeave) CMD5Shim();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+
+ }
+
+CMD5Shim::CMD5Shim()
+ {
+ }
+
+TInt CMD5Shim::Extension_(TUint aExtensionId, TAny*& a0, TAny* /*a1*/)
+ {
+ TInt ret(KErrNotSupported);
+
+ if (KHashInterfaceUid.iUid==aExtensionId && iHashImpl)
+ {
+ a0=iHashImpl;
+ ret=KErrNone;
+ }
+
+ return ret;
+ }
+
+CMD5Shim::~CMD5Shim()
+ {
+ delete iHashImpl;
+ }
+
+
+void CMD5Shim::ConstructL()
+ {
+ CHashFactory::CreateHashL(iHashImpl,
+ KMd5Uid,
+ KHashModeUid,
+ NULL,
+ NULL);
+ }
+
+CMessageDigest* CMD5Shim::CopyL()
+ {
+ CMD5Shim* copy=new(ELeave) CMD5Shim();
+ CleanupStack::PushL(copy);
+ copy->iHashImpl=iHashImpl->CopyL();
+ CleanupStack::Pop();
+ return copy;
+ }
+
+CMessageDigest* CMD5Shim::ReplicateL()
+ {
+ CMD5Shim* copy=new(ELeave) CMD5Shim();
+ CleanupStack::PushL(copy);
+ copy->iHashImpl=iHashImpl->ReplicateL();
+ CleanupStack::Pop();
+ return copy;
+ }
+
+TInt CMD5Shim::BlockSize()
+ {
+ const TCharacteristics* ptr(NULL);
+ TRAPD(err, iHashImpl->GetCharacteristicsL(ptr);)
+ if (err)
+ {
+ return ((err>0)? KErrGeneral : err);
+ }
+ const THashCharacteristics* hashPtr=static_cast<const THashCharacteristics*>(ptr);
+ return hashPtr->iBlockSize/8;
+ }
+
+TInt CMD5Shim::HashSize()
+ {
+ const TCharacteristics* ptr(NULL);
+ TRAPD(err, iHashImpl->GetCharacteristicsL(ptr);)
+ if (err)
+ {
+ return ((err>0)? KErrGeneral : err);
+ }
+ const THashCharacteristics* hashPtr=static_cast<const THashCharacteristics*>(ptr);
+ return hashPtr->iOutputSize/8;
+ }
+
+void CMD5Shim::Update(const TDesC8& aMessage)
+ {
+ iHashImpl->Update(aMessage);
+ }
+
+TPtrC8 CMD5Shim::Final(const TDesC8& aMessage)
+ {
+ return iHashImpl->Final(aMessage);
+ }
+
+TPtrC8 CMD5Shim::Final()
+ {
+ TPtrC8 ptr(KNullDesC8());
+ return iHashImpl->Final(ptr);
+ }
+
+void CMD5Shim::Reset()
+ {
+ iHashImpl->Reset();
+ }
+
+
+TPtrC8 CMD5Shim::Hash(const TDesC8& aMessage)
+ {
+ return iHashImpl->Hash(aMessage);
+ }
+
+//
+// Implementation of SHA1 shim
+//
+
+CSHA1Shim* CSHA1Shim::NewL()
+ {
+ CSHA1Shim* self=CSHA1Shim::NewLC();
+ CleanupStack::Pop();
+ return self;
+ }
+
+CSHA1Shim* CSHA1Shim::NewLC()
+ {
+
+ CSHA1Shim* self=new(ELeave) CSHA1Shim();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+
+ }
+
+CSHA1Shim::CSHA1Shim()
+ {
+ }
+
+
+TInt CSHA1Shim::Extension_(TUint aExtensionId, TAny*& a0, TAny* /*a1*/)
+ {
+ TInt ret(KErrNotSupported);
+
+ if (KHashInterfaceUid.iUid==aExtensionId && iHashImpl)
+ {
+ a0=iHashImpl;
+ ret=KErrNone;
+ }
+
+ return ret;
+ }
+
+CSHA1Shim::~CSHA1Shim()
+ {
+ delete iHashImpl;
+ }
+
+
+void CSHA1Shim::ConstructL()
+ {
+ CHashFactory::CreateHashL(iHashImpl,
+ KSha1Uid,
+ KHashModeUid,
+ NULL,
+ NULL);
+ }
+
+CMessageDigest* CSHA1Shim::CopyL()
+ {
+ CSHA1Shim* copy=new(ELeave) CSHA1Shim();
+ CleanupStack::PushL(copy);
+ copy->iHashImpl=iHashImpl->CopyL();
+ CleanupStack::Pop();
+ return copy;
+ }
+
+CMessageDigest* CSHA1Shim::ReplicateL()
+ {
+ CSHA1Shim* copy=new(ELeave) CSHA1Shim();
+ CleanupStack::PushL(copy);
+ copy->iHashImpl=iHashImpl->ReplicateL();
+ CleanupStack::Pop();
+ return copy;
+ }
+
+TInt CSHA1Shim::BlockSize()
+ {
+ const TCharacteristics* ptr(NULL);
+ TRAPD(err, iHashImpl->GetCharacteristicsL(ptr);)
+ if (err)
+ {
+ return ((err>0)? KErrGeneral : err);
+ }
+ const THashCharacteristics* hashPtr=static_cast<const THashCharacteristics*>(ptr);
+ return hashPtr->iBlockSize/8;
+ }
+
+TInt CSHA1Shim::HashSize()
+ {
+ const TCharacteristics* ptr(NULL);
+ TRAPD(err, iHashImpl->GetCharacteristicsL(ptr);)
+ if (err)
+ {
+ return ((err>0)? KErrGeneral : err);
+ }
+ const THashCharacteristics* hashPtr=static_cast<const THashCharacteristics*>(ptr);
+ return hashPtr->iOutputSize/8;
+ }
+
+void CSHA1Shim::Update(const TDesC8& aMessage)
+ {
+ iHashImpl->Update(aMessage);
+ }
+
+TPtrC8 CSHA1Shim::Final(const TDesC8& aMessage)
+ {
+ return iHashImpl->Final(aMessage);
+ }
+
+TPtrC8 CSHA1Shim::Final()
+ {
+ TPtrC8 ptr(KNullDesC8());
+ return iHashImpl->Final(ptr);
+ }
+
+void CSHA1Shim::Reset()
+ {
+ iHashImpl->Reset();
+ }
+
+TPtrC8 CSHA1Shim::Hash(const TDesC8& aMessage)
+ {
+ return iHashImpl->Hash(aMessage);
+ }
+
+
+//
+// Implementation of SHA2 shim
+//
+
+CSHA2Shim* CSHA2Shim::NewL(TSH2Algo aAlgorithmId)
+ {
+ CSHA2Shim* self=CSHA2Shim::NewLC(aAlgorithmId);
+ CleanupStack::Pop();
+ return self;
+ }
+
+CSHA2Shim* CSHA2Shim::NewLC(TSH2Algo aAlgorithmId)
+ {
+
+ CSHA2Shim* self=new(ELeave) CSHA2Shim();
+ CleanupStack::PushL(self);
+ self->ConstructL(aAlgorithmId);
+ return self;
+ }
+
+CSHA2Shim::CSHA2Shim()
+ {
+ }
+
+TInt CSHA2Shim::Extension_(TUint aExtensionId, TAny*& a0, TAny* /*a1*/)
+ {
+ TInt ret(KErrNotSupported);
+
+ if (KHashInterfaceUid.iUid==aExtensionId && iHashImpl)
+ {
+ a0=iHashImpl;
+ ret=KErrNone;
+ }
+ return ret;
+ }
+
+CSHA2Shim::~CSHA2Shim()
+ {
+ delete iHashImpl;
+ }
+
+void CSHA2Shim::ConstructL(TSH2Algo aAlgorithmId)
+ {
+ TUid algoId = {0};
+ switch(aAlgorithmId)
+ {
+ case E224Bit:
+ {
+ algoId = KSha224Uid;
+ break;
+ }
+ case E256Bit:
+ {
+ algoId = KSha256Uid;
+ break;
+ }
+ case E384Bit:
+ {
+ algoId = KSha384Uid;
+ break;
+ }
+ case E512Bit:
+ {
+ algoId = KSha512Uid;
+ break;
+ }
+ default:
+ User::Leave(KErrNotSupported);
+ }
+
+ CHashFactory::CreateHashL(iHashImpl,
+ algoId,
+ KHashModeUid,
+ NULL,
+ NULL);
+ }
+
+CMessageDigest* CSHA2Shim::CopyL()
+ {
+ CSHA2Shim* copy=new(ELeave) CSHA2Shim();
+ CleanupStack::PushL(copy);
+ copy->iHashImpl=iHashImpl->CopyL();
+ CleanupStack::Pop();
+ return copy;
+ }
+
+CMessageDigest* CSHA2Shim::ReplicateL()
+ {
+ CSHA2Shim* copy=new(ELeave) CSHA2Shim();
+ CleanupStack::PushL(copy);
+ copy->iHashImpl=iHashImpl->ReplicateL();
+ CleanupStack::Pop();
+ return copy;
+ }
+
+TInt CSHA2Shim::BlockSize()
+ {
+ const TCharacteristics* ptr(NULL);
+ TRAPD(err, iHashImpl->GetCharacteristicsL(ptr);)
+ if (err)
+ {
+ return ((err>0)? KErrGeneral : err);
+ }
+ const THashCharacteristics* hashPtr=static_cast<const THashCharacteristics*>(ptr);
+ return hashPtr->iBlockSize/8;
+ }
+
+TInt CSHA2Shim::HashSize()
+ {
+ const TCharacteristics* ptr(NULL);
+ TRAPD(err, iHashImpl->GetCharacteristicsL(ptr);)
+ if (err)
+ {
+ return ((err>0)? KErrGeneral : err);
+ }
+ const THashCharacteristics* hashPtr=static_cast<const THashCharacteristics*>(ptr);
+ return hashPtr->iOutputSize/8;
+ }
+
+void CSHA2Shim::Update(const TDesC8& aMessage)
+ {
+ iHashImpl->Update(aMessage);
+ }
+
+TPtrC8 CSHA2Shim::Final(const TDesC8& aMessage)
+ {
+ return iHashImpl->Final(aMessage);
+ }
+
+TPtrC8 CSHA2Shim::Final()
+ {
+ TPtrC8 ptr(KNullDesC8());
+ return iHashImpl->Final(ptr);
+ }
+
+void CSHA2Shim::Reset()
+ {
+ iHashImpl->Reset();
+ }
+
+TPtrC8 CSHA2Shim::Hash(const TDesC8& aMessage)
+ {
+ return iHashImpl->Hash(aMessage);
+ }
+
+//
+// Implementation of HMAC shim
+//
+
+CHMACShim* CHMACShim::NewL(const TDesC8& aKey, CMessageDigest* aDigest)
+ {
+ CHMACShim* self(0);
+
+ // Check whether the hash contains an SPI plug-in
+ TAny* implPtr(0);
+ TInt err = aDigest->GetExtension(CryptoSpi::KHashInterface, implPtr, NULL);
+ if (err == KErrNone && implPtr)
+ {
+ CryptoSpi::CHash* impl(static_cast<CryptoSpi::CHash*>(implPtr));
+ const CryptoSpi::TCharacteristics* c(0);
+ impl->GetCharacteristicsL(c);
+ const CryptoSpi::THashCharacteristics* hashCharacteristics(static_cast<const CryptoSpi::THashCharacteristics*>(c));
+
+
+ // Verify that the plug-in supports Hmac mode
+ if (hashCharacteristics->IsOperationModeSupported(CryptoSpi::KHmacModeUid))
+ {
+
+ #ifndef SYMBIAN_SDP_IPSEC_VOIP_SUPPORT
+ // Make an own copy
+ CHash* myHash=impl->ReplicateL();
+ CleanupStack::PushL(myHash);
+ #endif
+ // Set the key
+ TKeyProperty keyProperty = {KHmacModeUid, KNullUid, KSymmetricKey, KNonEmbeddedKeyUid};
+ CCryptoParams* keyParam =CCryptoParams::NewLC();
+ keyParam->AddL(aKey, KHmacKeyParameterUid);
+ CKey* uniKey= CKey::NewLC(keyProperty, *keyParam);
+ #ifndef SYMBIAN_SDP_IPSEC_VOIP_SUPPORT
+ myHash->SetKeyL(*uniKey);
+ CleanupStack::PopAndDestroy(2, keyParam);
+ // Set hash to Hmac mode
+ myHash->SetOperationModeL(CryptoSpi::KHmacModeUid);
+ self = new(ELeave) CHMACShim(myHash, aDigest);
+ CleanupStack::Pop(myHash);
+ #else
+ TUid algorithmUID = algorithmUID.Uid(hashCharacteristics->cmn.iAlgorithmUID);
+ //Create a pointer for the Mac Implementation Object
+ CMac* macImpl = NULL;
+ CMacFactory::CreateMacL(macImpl,algorithmUID,*uniKey, NULL);
+ CleanupStack::PushL(macImpl);
+ self = new(ELeave) CHMACShim(macImpl, aDigest,uniKey, algorithmUID);
+ CleanupStack::Pop(macImpl);
+ CleanupStack::Pop(uniKey);
+ CleanupStack::PopAndDestroy(keyParam);
+ #endif
+ }
+ }
+ return self;
+ }
+
+#ifdef SYMBIAN_SDP_IPSEC_VOIP_SUPPORT
+
+CHMACShim::CHMACShim(CryptoSpi::CMac* aImpl, CMessageDigest* aDigest, CryptoSpi::CKey* aKey, TUid aAlgorithmUid)
+ : CHMAC(aDigest), iMacImpl(aImpl), iKey(aKey), iAlgorithmUid(aAlgorithmUid)
+ {
+ }
+
+#else
+
+CHMACShim::CHMACShim(CryptoSpi::CHash* aImpl, CMessageDigest* aDigest)
+ : CHMAC(aDigest), iMacImpl(aImpl)
+ {
+ }
+
+#endif
+
+CHMACShim::CHMACShim()
+ {
+ }
+
+CHMACShim::~CHMACShim()
+ {
+ delete iMacImpl;
+#ifdef SYMBIAN_SDP_IPSEC_VOIP_SUPPORT
+ delete iKey;
+#endif
+ }
+
+TInt CHMACShim::BlockSize()
+ {
+ const TCharacteristics* ptr(NULL);
+ TRAPD(err, iMacImpl->GetCharacteristicsL(ptr));
+
+ if (err)
+ {
+ return ((err>0)? KErrGeneral : err);
+ }
+
+#ifndef SYMBIAN_SDP_IPSEC_VOIP_SUPPORT
+ const THashCharacteristics* hashPtr=static_cast<const THashCharacteristics*>(ptr);
+ return hashPtr->iBlockSize/8;
+#else
+ const TMacCharacteristics* macPtr=static_cast<const TMacCharacteristics*>(ptr);
+ return macPtr->iHashAlgorithmChar->iBlockSize/8;
+#endif
+ }
+
+TInt CHMACShim::HashSize()
+ {
+ const TCharacteristics* ptr(NULL);
+ TRAPD(err, iMacImpl->GetCharacteristicsL(ptr));
+ if (err)
+ {
+ return ((err>0)? KErrGeneral : err);
+ }
+
+#ifndef SYMBIAN_SDP_IPSEC_VOIP_SUPPORT
+ const THashCharacteristics* hashPtr=static_cast<const THashCharacteristics*>(ptr);
+ return hashPtr->iOutputSize/8;
+#else
+ const TMacCharacteristics* macPtr=static_cast<const TMacCharacteristics*>(ptr);
+ return macPtr->iHashAlgorithmChar->iOutputSize/8;
+#endif
+ }
+
+void CHMACShim::Update(const TDesC8& aMessage)
+ {
+#ifdef SYMBIAN_SDP_IPSEC_VOIP_SUPPORT
+ // The error is ignored as the legacy code methods are non-leaving and they call
+ // the new MAC interfaces which uses leaving methods for processing MAC value.
+ // This call always call the non-leaving legacy method.
+ TRAP_IGNORE(iMacImpl->UpdateL(aMessage));
+#else
+ iMacImpl->Update(aMessage);
+#endif
+ }
+
+TPtrC8 CHMACShim::Final(const TDesC8& aMessage)
+ {
+#ifdef SYMBIAN_SDP_IPSEC_VOIP_SUPPORT
+ TPtrC8 macPtr(KNullDesC8());
+ // The error is ignored as the legacy code methods are non-leaving and they call
+ // the new MAC interfaces which uses leaving methods for processing MAC value.
+ // This call always call the non-leaving legacy method.
+ TRAP_IGNORE(macPtr.Set(iMacImpl->FinalL(aMessage)));
+ return macPtr;
+#else
+ return iMacImpl->Final(aMessage);
+#endif
+ }
+
+TPtrC8 CHMACShim::Final()
+ {
+ TPtrC8 ptr(KNullDesC8());
+#ifdef SYMBIAN_SDP_IPSEC_VOIP_SUPPORT
+ TPtrC8 macPtr(KNullDesC8());
+ // The error is ignored as the legacy code methods are non-leaving and they call
+ // the new MAC interfaces which uses leaving methods for processing MAC value.
+ // This call always call the non-leaving legacy method.
+ TRAP_IGNORE(macPtr.Set(iMacImpl->FinalL(ptr)));
+ return macPtr;
+#else
+ return iMacImpl->Final(ptr);
+#endif
+ }
+
+void CHMACShim::Reset()
+ {
+ iMacImpl->Reset();
+ }
+
+TPtrC8 CHMACShim::Hash(const TDesC8& aMessage)
+ {
+#ifdef SYMBIAN_SDP_IPSEC_VOIP_SUPPORT
+ TPtrC8 macPtr(KNullDesC8());
+ // The error is ignored as the legacy code methods are non-leaving and they call
+ // the new MAC interfaces which uses leaving methods for processing MAC value.
+ // This call always call the non-leaving legacy method.
+ TRAP_IGNORE(macPtr.Set(iMacImpl->MacL(aMessage)));
+ return macPtr;
+#else
+ return iMacImpl->Hash(aMessage);
+#endif
+ }
+
+CMessageDigest* CHMACShim::ReplicateL()
+ {
+ CHMACShim* copy=new(ELeave) CHMACShim();
+ CleanupStack::PushL(copy);
+ copy->iMacImpl=iMacImpl->ReplicateL();
+ CleanupStack::Pop(copy);
+ return copy;
+ }
+
+CMessageDigest* CHMACShim::CopyL()
+ {
+ CHMACShim* copy=new(ELeave) CHMACShim();
+ CleanupStack::PushL(copy);
+ copy->iMacImpl=iMacImpl->CopyL();
+ CleanupStack::Pop(copy);
+ return copy;
+ }
+
+//
+// Implemetation of MD4 shim
+//
+CMD4Shim* CMD4Shim::NewL()
+ {
+ CMD4Shim* self=CMD4Shim::NewLC();
+ CleanupStack::Pop();
+ return self;
+ }
+
+CMD4Shim* CMD4Shim::NewLC()
+ {
+ CMD4Shim* self=new(ELeave) CMD4Shim();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+CMD4Shim::CMD4Shim()
+ {
+ }
+
+TInt CMD4Shim::Extension_(TUint aExtensionId, TAny*& a0, TAny* /*a1*/)
+ {
+ TInt ret(KErrNotSupported);
+
+ if (KHashInterfaceUid.iUid==aExtensionId && iHashImpl)
+ {
+ a0=iHashImpl;
+ ret=KErrNone;
+ }
+
+ return ret;
+ }
+
+CMD4Shim::~CMD4Shim()
+ {
+ delete iHashImpl;
+ }
+
+
+void CMD4Shim::ConstructL()
+ {
+ CHashFactory::CreateHashL(iHashImpl,KMd4Uid,KHashModeUid,NULL,NULL);
+ }
+
+CMessageDigest* CMD4Shim::CopyL()
+ {
+ CMD4Shim* copy=new(ELeave) CMD4Shim();
+ CleanupStack::PushL(copy);
+ copy->iHashImpl=iHashImpl->CopyL();
+ CleanupStack::Pop();
+ return copy;
+ }
+
+CMessageDigest* CMD4Shim::ReplicateL()
+ {
+ CMD4Shim* copy=new(ELeave) CMD4Shim();
+ CleanupStack::PushL(copy);
+ copy->iHashImpl=iHashImpl->ReplicateL();
+ CleanupStack::Pop();
+ return copy;
+ }
+
+TInt CMD4Shim::BlockSize()
+ {
+ const TCharacteristics* ptr(NULL);
+ TRAPD(err, iHashImpl->GetCharacteristicsL(ptr);)
+ if (err)
+ {
+ return ((err>0)? KErrGeneral : err);
+ }
+ const THashCharacteristics* hashPtr=static_cast<const THashCharacteristics*>(ptr);
+ return hashPtr->iBlockSize/8;
+ }
+
+TInt CMD4Shim::HashSize()
+ {
+ const TCharacteristics* ptr(NULL);
+ TRAPD(err, iHashImpl->GetCharacteristicsL(ptr);)
+ if (err)
+ {
+ return ((err>0)? KErrGeneral : err);
+ }
+ const THashCharacteristics* hashPtr=static_cast<const THashCharacteristics*>(ptr);
+ return hashPtr->iOutputSize/8;
+ }
+
+void CMD4Shim::Update(const TDesC8& aMessage)
+ {
+ iHashImpl->Update(aMessage);
+ }
+
+TPtrC8 CMD4Shim::Final(const TDesC8& aMessage)
+ {
+ return iHashImpl->Final(aMessage);
+ }
+
+TPtrC8 CMD4Shim::Final()
+ {
+ TPtrC8 ptr(KNullDesC8());
+ return iHashImpl->Final(ptr);
+ }
+
+void CMD4Shim::Reset()
+ {
+ iHashImpl->Reset();
+ }
+
+
+TPtrC8 CMD4Shim::Hash(const TDesC8& aMessage)
+ {
+ return iHashImpl->Hash(aMessage);
+ }
+