--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/networksecurity/ipsec/ipseccrypto/src/ipseccrypto_prt.cpp Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,328 @@
+// 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 "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 <e32cmn.h>
+
+#include "ipseccrypto.h"
+#include <networking/ipsecerr.h>
+
+#include <des.h>
+#include <3des.h>
+#include <rijndael.h>
+#include <hash.h>
+
+#include "keys.h"
+#include "cryptospidef.h"
+#include "cryptosymmetriccipherapi.h"
+#ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
+#include "ruleselector.h"
+#include "plugincharacteristics.h"
+#include "cryptospistateapi.h"
+#include "cryptoparams.h"
+#include "cryptomacapi.h"
+using namespace CryptoSpi;
+#endif // SYMBIAN_IPSEC_VOIP_SUPPORT
+
+#define DES_CBLOCK_SIZE 8
+#define AES_CBLOCK_SIZE 16
+
+
+#define SHA_DIGEST_LENGTH 20
+#define MD5_DIGEST_LENGTH 16
+#define SHA_CBLOCK 64
+#define MD5_CBLOCK 64
+
+//
+
+class CMessageDigestSymbian : public CMessageDigestCrypto
+ /**
+ * Generic Hash engine wrapper
+ */
+ {
+public:
+ CMessageDigestSymbian(CMessageDigest *aDigest);
+ virtual void Init();
+ virtual void Update(const TDesC8& aMessage);
+ virtual void Final(TDes8& aDigest);
+ static void FillinInfoSha1(TAlgorithmDesc &anEntry);
+ static void FillinInfoMd5(TAlgorithmDesc &anEntry);
+ ~CMessageDigestSymbian();
+private:
+ CMessageDigest *iDigest;
+ };
+
+CMessageDigestSymbian::CMessageDigestSymbian(CMessageDigest *aDigest) : iDigest(aDigest)
+ {
+ ASSERT(aDigest);
+ }
+
+void CMessageDigestSymbian::Init()
+ {
+ ASSERT(iDigest);
+ iDigest->Reset();
+ }
+
+void CMessageDigestSymbian::Update(const TDesC8& aMessage)
+ {
+ ASSERT(iDigest);
+ iDigest->Update(aMessage);
+ }
+
+void CMessageDigestSymbian::Final(TDes8& aDigest)
+ {
+ ASSERT(iDigest);
+ aDigest.Copy(iDigest->Final());
+ }
+
+CMessageDigestSymbian::~CMessageDigestSymbian()
+ {
+ delete iDigest;
+ }
+
+
+//
+
+// CProtocolEay::AlgorithmList + algorithm specific FillinInfo's
+//
+// return descriptions of the algorithms supported by this module
+//
+static void FillinInfoDescbc(TAlgorithmDesc &anEntry)
+ {
+ anEntry.iName = KIpsecName_DES_CBC;
+ anEntry.iAlgType = EAlgorithmClass_Cipher;
+ anEntry.iMinBits = 64;
+ anEntry.iMaxBits = 64;
+ anEntry.iBlock = DES_CBLOCK_SIZE;
+ anEntry.iVector = 8;
+ }
+
+static void FillinInfo3Descbc(TAlgorithmDesc &anEntry)
+ {
+ anEntry.iName = KIpsecName_3DES_CBC;
+ anEntry.iAlgType = EAlgorithmClass_Cipher;
+ anEntry.iMinBits = 3*64;
+ anEntry.iMaxBits = 3*64;
+ anEntry.iBlock = DES_CBLOCK_SIZE;
+ anEntry.iVector = 8;
+ }
+
+
+static void FillinInfoAescbc(TAlgorithmDesc &anEntry)
+ {
+ anEntry.iName = KIpsecName_AES_CBC;
+ anEntry.iAlgType = EAlgorithmClass_Cipher;
+ anEntry.iMinBits = 128;
+ anEntry.iMaxBits = 256;
+ anEntry.iBlock = AES_CBLOCK_SIZE;
+ anEntry.iVector = 16;
+ }
+
+static void FillinInfoAesctr(TAlgorithmDesc &anEntry)
+ {
+ anEntry.iName = KIpsecName_AES_CTR;
+ anEntry.iAlgType = EAlgorithmClass_Cipher;
+ anEntry.iMinBits = 128;
+ anEntry.iMaxBits = 256;
+ anEntry.iBlock = AES_CBLOCK_SIZE;
+ anEntry.iVector = 16; // NOTE : Value set to 16 to be compliant to the current crypto implementation
+ // which expects the IVSize to be 16. Will have to be updated (to 8) once the fix is
+ // completed at the crypto layer
+ }
+#ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
+static void FillinInfoAesXcbcMac96(TAlgorithmDesc &anEntry)
+ {
+ anEntry.iName = KIpsecName_AES_XCBC_MAC;
+ anEntry.iAlgType = EAlgorithmClass_Mac;
+ anEntry.iMinBits = 96;
+ anEntry.iMaxBits = 128;
+ anEntry.iBlock = AES_CBLOCK_SIZE;
+ anEntry.iVector = 16;
+ }
+#endif
+
+void CMessageDigestSymbian::FillinInfoSha1(TAlgorithmDesc &anEntry)
+ {
+ anEntry.iName = KIpsecName_SHA1;
+ anEntry.iAlgType = EAlgorithmClass_Digest;
+ anEntry.iMinBits = SHA_DIGEST_LENGTH * 8;
+ anEntry.iMaxBits = SHA_DIGEST_LENGTH * 8;
+ anEntry.iBlock = SHA_CBLOCK;
+ anEntry.iVector = SHA_DIGEST_LENGTH;
+ }
+
+void CMessageDigestSymbian::FillinInfoMd5(TAlgorithmDesc &anEntry)
+ {
+ anEntry.iName = KIpsecName_MD5;
+ anEntry.iAlgType = EAlgorithmClass_Digest;
+ anEntry.iMinBits = MD5_DIGEST_LENGTH * 8;
+ anEntry.iMaxBits = MD5_DIGEST_LENGTH * 8;
+ anEntry.iBlock = MD5_CBLOCK;
+ anEntry.iVector = MD5_DIGEST_LENGTH;
+ }
+
+
+TUint CProtocolEay::AlgorithmList(TAlgorithmDesc *&aList)
+ {
+ aList = new TAlgorithmDesc[EAlgorithm_Max];
+ if (aList == NULL)
+ {
+ return EAlgorithm_Max;
+ }
+
+ CMessageDigestSymbian::FillinInfoSha1(aList[EAlgorithm_Sha1]);
+ CMessageDigestSymbian::FillinInfoMd5(aList[EAlgorithm_Md5]);
+ FillinInfoDescbc(aList[EAlgorithm_Descbc]);
+ FillinInfo3Descbc(aList[EAlgorithm_3Descbc]);
+ FillinInfoAescbc(aList[EAlgorithm_Aescbc]);
+ FillinInfoAesctr(aList[EAlgorithm_Aesctr]);
+#ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
+ FillinInfoAesXcbcMac96(aList[EAlgorithm_AesXcbcMac96]);
+#endif
+ return EAlgorithm_Max;
+ }
+
+//
+// Instantiate a Cipher algorithm
+//
+CryptoSpi::CSymmetricCipher* CProtocolEay::SymmetricCipherL(TUint aAlg, const TDesC8 &aKey)
+ {
+ CryptoSpi::CSymmetricCipher *enc = NULL;
+ TUid operModeUid = CryptoSpi::KOperationModeCBCUid;
+ TUid algUid = CryptoSpi::KAesUid;
+ TUid cryptoModeUid = CryptoSpi::KCryptoModeEncryptUid;
+ TUid paddingModeUid = CryptoSpi::KPaddingModeNoneUid;
+ switch(aAlg)
+ {
+ case EAlgorithm_Descbc:
+ algUid = CryptoSpi::KDesUid;
+ break;
+ case EAlgorithm_3Descbc:
+ algUid = CryptoSpi::K3DesUid;
+ break;
+ case EAlgorithm_Aescbc:
+ algUid = CryptoSpi::KAesUid;
+ break;
+ case EAlgorithm_Aesctr:
+ algUid = CryptoSpi::KAesUid;
+ operModeUid = CryptoSpi::KOperationModeCTRUid;;
+ break;
+ default:
+ User::Leave(EIpsec_UnknownCipherNumber);
+ }
+ // Initialize the Encryptor
+ CryptoSpi::TKeyProperty keyProperty = {algUid, KNullUid, CryptoSpi::KSymmetricKeyUid, CryptoSpi::KNonEmbeddedKeyUid};
+ CryptoSpi::CCryptoParams* keyParam =CryptoSpi::CCryptoParams::NewLC();
+ keyParam->AddL(aKey, CryptoSpi::KSymmetricKeyParameterUid);
+ CryptoSpi::CKey *key=CryptoSpi::CKey::NewLC(keyProperty, *keyParam);
+ TRAPD(res, CryptoSpi::CSymmetricCipherFactory::CreateSymmetricCipherL
+ (
+ enc,
+ algUid,
+ *key,
+ cryptoModeUid,
+ operModeUid,
+ paddingModeUid,
+ NULL));
+ CleanupStack::PopAndDestroy(key);
+ CleanupStack::PopAndDestroy(keyParam);
+ if (res != KErrNone)
+ {
+ // SetKey takes place implicit to the CreateSymmetricCipherL() factory call. If there is any issue with the key
+ // we would get KErrNotSupported which we need to map to EIpsec_BadCipherKey
+ if (res == KErrNotSupported)
+ {
+ User::Leave(EIpsec_BadCipherKey);
+ }
+ User::Leave(res);
+ }
+ return enc;
+ }
+
+//
+// CProtocolEay::MessageDigest
+// Instantiate a Message Digest algorithm
+//
+CMessageDigestCrypto* CProtocolEay::MessageDigest(TUint aAlg)
+ {
+ CMessageDigest *digest = NULL;
+ // Instead of CSHA1 and CMD5, we should have TSHA1 and TMD5
+ // to be used as member classes, and the TRAP below would
+ // not be needed -- or at least, should have non-leaving
+ // New available!
+ TRAP_IGNORE(
+ switch (aAlg)
+ {
+ case EAlgorithm_Sha1:
+ digest = CSHA1::NewL();
+ break;
+ case EAlgorithm_Md5:
+ digest = CMD5::NewL();
+ break;
+ default:
+ break;
+ }
+ );
+ if (digest == NULL)
+ return NULL; // No Engine available: out of memory or bad call.
+ CMessageDigestSymbian *wrapper = new CMessageDigestSymbian(digest);
+ if (wrapper == NULL)
+ delete digest; // Out of memory
+ return wrapper;
+ }
+
+#ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
+CMac* CProtocolEay::GetMacImplementationL(const TDesC8& aKey)
+ {
+ //create rule based selector for filtering the desired MAC interface plug-ins.
+ CSelectionRules* rules = CSelectionRules::NewL();
+ CleanupStack::PushL(rules);
+ CSelectionRuleContent* rule = NULL;
+ const long i=0;
+ CCryptoParam* ruleValueParam = CCryptoIntParam::NewL(0, KMacModeTypeUid);
+
+ TUid id={KAlgorithmCipherAesXcbcMac96};
+ rule = CSelectionRuleContent::NewL(KMacInterfaceUid,id, ruleValueParam,EOpEqual,ETrue);
+ rules->AddSelectionRuleL(rule);
+ CRuleSelector* ruleSelector = CRuleSelector::NewL(rules);
+ CleanupStack::Pop(rules);
+ CleanupStack::PushL(ruleSelector);
+ CCryptoSpiStateApi::SetSelector(ruleSelector);
+ // Create & Set the key
+ TKeyProperty keyProperty = {KAesUid, KNullUid, KSymmetricKey,KNonEmbeddedKeyUid};
+ CCryptoParams* keyParam =CCryptoParams::NewLC();
+ keyParam->AddL(aKey, KSymmetricKeyParameterUid);
+ CKey* uniKey=CKey::NewLC(keyProperty, *keyParam);
+ //Retrieve a Synchronous MAC Factory Object and use AES-XCBC-MAC-96 or any other MACalgorithm.
+ CMac* macImpl =NULL;
+ TRAPD(err,CMacFactory::CreateMacL(macImpl, KAesXcbcMac96Uid,*uniKey, NULL));
+ //cleanup uniKey and keyParam.
+ CleanupStack::PopAndDestroy(2,keyParam);
+ CCryptoSpiStateApi::UnsetSelector();
+ CleanupStack::PopAndDestroy(ruleSelector);
+ return macImpl;
+ }
+
+HBufC8* CProtocolEay::RetrieveMacValueL(CMac *aMac, const TDesC8& aSourceData )
+ {
+
+ //Retrieve the 8bit mac value
+ HBufC8* macValue = HBufC8::NewLC(16);
+ TPtr8 macPtr = macValue->Des();
+ //Copy the mac content into the heap based descriptor
+ macPtr.Copy(aMac->MacL(aSourceData));
+ CleanupStack::PopAndDestroy(macValue);
+ return macValue;
+ }
+#endif // SYMBIAN_IPSEC_VOIP_SUPPORT