networksecurity/ipsec/ipseccrypto/src/ipseccrypto_prt.cpp
changeset 0 af10295192d8
child 11 db85996de7c4
child 20 e8d041006974
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <e32cmn.h>
       
    17 
       
    18 #include "ipseccrypto.h"
       
    19 #include <networking/ipsecerr.h>
       
    20 
       
    21 #include <des.h>
       
    22 #include <3des.h>
       
    23 #include <rijndael.h>
       
    24 #include <hash.h>
       
    25 
       
    26 #include "keys.h"
       
    27 #include "cryptospidef.h"
       
    28 #include "cryptosymmetriccipherapi.h"
       
    29 #ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
       
    30 #include "ruleselector.h"
       
    31 #include "plugincharacteristics.h"
       
    32 #include "cryptospistateapi.h"
       
    33 #include "cryptoparams.h"
       
    34 #include "cryptomacapi.h"
       
    35 using namespace CryptoSpi;
       
    36 #endif // SYMBIAN_IPSEC_VOIP_SUPPORT
       
    37 
       
    38 #define DES_CBLOCK_SIZE 8
       
    39 #define AES_CBLOCK_SIZE 16
       
    40 
       
    41 
       
    42 #define SHA_DIGEST_LENGTH 20
       
    43 #define MD5_DIGEST_LENGTH 16
       
    44 #define SHA_CBLOCK  64
       
    45 #define MD5_CBLOCK  64
       
    46 
       
    47 //
       
    48 
       
    49 class CMessageDigestSymbian : public CMessageDigestCrypto
       
    50 	/**
       
    51 	* Generic Hash engine wrapper
       
    52 	*/
       
    53 	{
       
    54 public:
       
    55 	CMessageDigestSymbian(CMessageDigest *aDigest);
       
    56 	virtual void Init();
       
    57 	virtual void Update(const TDesC8& aMessage);
       
    58 	virtual void Final(TDes8& aDigest);
       
    59 	static void FillinInfoSha1(TAlgorithmDesc &anEntry);
       
    60 	static void FillinInfoMd5(TAlgorithmDesc &anEntry);
       
    61 	~CMessageDigestSymbian();
       
    62 private:
       
    63 	CMessageDigest *iDigest;
       
    64 	};
       
    65 
       
    66 CMessageDigestSymbian::CMessageDigestSymbian(CMessageDigest *aDigest) : iDigest(aDigest)
       
    67 	{
       
    68 	ASSERT(aDigest);
       
    69 	}
       
    70 
       
    71 void CMessageDigestSymbian::Init()
       
    72 	{
       
    73 	ASSERT(iDigest);
       
    74 	iDigest->Reset();
       
    75 	}
       
    76 	
       
    77 void CMessageDigestSymbian::Update(const TDesC8& aMessage)
       
    78 	{
       
    79 	ASSERT(iDigest);
       
    80 	iDigest->Update(aMessage);
       
    81 	}
       
    82 	
       
    83 void CMessageDigestSymbian::Final(TDes8& aDigest)
       
    84 	{
       
    85 	ASSERT(iDigest);
       
    86 	aDigest.Copy(iDigest->Final());
       
    87 	}
       
    88 	
       
    89 CMessageDigestSymbian::~CMessageDigestSymbian()
       
    90 	{
       
    91 	delete iDigest;
       
    92 	}
       
    93 
       
    94 
       
    95 //
       
    96 
       
    97 //  CProtocolEay::AlgorithmList + algorithm specific FillinInfo's
       
    98 //
       
    99 //      return descriptions of the algorithms supported by this module
       
   100 //
       
   101 static void FillinInfoDescbc(TAlgorithmDesc &anEntry)
       
   102 	{
       
   103 	anEntry.iName = KIpsecName_DES_CBC;
       
   104 	anEntry.iAlgType = EAlgorithmClass_Cipher;
       
   105 	anEntry.iMinBits = 64;
       
   106 	anEntry.iMaxBits = 64;
       
   107 	anEntry.iBlock = DES_CBLOCK_SIZE;
       
   108 	anEntry.iVector = 8;
       
   109 	}
       
   110 
       
   111 static void FillinInfo3Descbc(TAlgorithmDesc &anEntry)
       
   112 	{
       
   113 	anEntry.iName = KIpsecName_3DES_CBC;
       
   114 	anEntry.iAlgType = EAlgorithmClass_Cipher;
       
   115 	anEntry.iMinBits = 3*64;
       
   116 	anEntry.iMaxBits = 3*64;
       
   117 	anEntry.iBlock = DES_CBLOCK_SIZE;
       
   118 	anEntry.iVector = 8;
       
   119 	}
       
   120 
       
   121 
       
   122 static void FillinInfoAescbc(TAlgorithmDesc &anEntry)
       
   123 	{
       
   124 	anEntry.iName = KIpsecName_AES_CBC;
       
   125 	anEntry.iAlgType = EAlgorithmClass_Cipher;
       
   126 	anEntry.iMinBits = 128;
       
   127 	anEntry.iMaxBits = 256;
       
   128 	anEntry.iBlock = AES_CBLOCK_SIZE;
       
   129 	anEntry.iVector = 16;
       
   130 	}
       
   131 
       
   132 static void FillinInfoAesctr(TAlgorithmDesc &anEntry)
       
   133 	{
       
   134 	anEntry.iName = KIpsecName_AES_CTR;
       
   135 	anEntry.iAlgType = EAlgorithmClass_Cipher;
       
   136 	anEntry.iMinBits = 128;
       
   137 	anEntry.iMaxBits = 256;
       
   138 	anEntry.iBlock = AES_CBLOCK_SIZE;
       
   139 	anEntry.iVector = 16; // NOTE : Value set to 16 to be compliant to the current crypto implementation 
       
   140 					      // which expects the IVSize to be 16. Will have to be updated (to 8) once the fix is 
       
   141 					      // completed at the crypto layer
       
   142 	}
       
   143 #ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
       
   144 static void FillinInfoAesXcbcMac96(TAlgorithmDesc &anEntry)
       
   145 	{
       
   146 	anEntry.iName = KIpsecName_AES_XCBC_MAC;
       
   147 	anEntry.iAlgType = EAlgorithmClass_Mac;
       
   148 	anEntry.iMinBits = 96;
       
   149 	anEntry.iMaxBits = 128;
       
   150 	anEntry.iBlock = AES_CBLOCK_SIZE;
       
   151 	anEntry.iVector = 16; 
       
   152 	}
       
   153 #endif
       
   154 
       
   155 void CMessageDigestSymbian::FillinInfoSha1(TAlgorithmDesc &anEntry)
       
   156 	{
       
   157 	anEntry.iName = KIpsecName_SHA1;
       
   158 	anEntry.iAlgType = EAlgorithmClass_Digest;
       
   159 	anEntry.iMinBits = SHA_DIGEST_LENGTH * 8;
       
   160 	anEntry.iMaxBits = SHA_DIGEST_LENGTH * 8;
       
   161 	anEntry.iBlock = SHA_CBLOCK;
       
   162 	anEntry.iVector = SHA_DIGEST_LENGTH;
       
   163 	}
       
   164 
       
   165 void CMessageDigestSymbian::FillinInfoMd5(TAlgorithmDesc &anEntry)
       
   166 	{
       
   167 	anEntry.iName = KIpsecName_MD5;
       
   168 	anEntry.iAlgType = EAlgorithmClass_Digest;
       
   169 	anEntry.iMinBits = MD5_DIGEST_LENGTH * 8;
       
   170 	anEntry.iMaxBits = MD5_DIGEST_LENGTH * 8;
       
   171 	anEntry.iBlock = MD5_CBLOCK;
       
   172 	anEntry.iVector = MD5_DIGEST_LENGTH;
       
   173 	}
       
   174 
       
   175 
       
   176 TUint CProtocolEay::AlgorithmList(TAlgorithmDesc *&aList)
       
   177 	{
       
   178 	aList = new TAlgorithmDesc[EAlgorithm_Max];
       
   179 	if (aList == NULL)
       
   180 		{
       
   181 		return EAlgorithm_Max;
       
   182 		}
       
   183 
       
   184 	CMessageDigestSymbian::FillinInfoSha1(aList[EAlgorithm_Sha1]);
       
   185 	CMessageDigestSymbian::FillinInfoMd5(aList[EAlgorithm_Md5]);
       
   186 	FillinInfoDescbc(aList[EAlgorithm_Descbc]);
       
   187 	FillinInfo3Descbc(aList[EAlgorithm_3Descbc]);
       
   188 	FillinInfoAescbc(aList[EAlgorithm_Aescbc]);
       
   189 	FillinInfoAesctr(aList[EAlgorithm_Aesctr]);
       
   190 #ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
       
   191 	FillinInfoAesXcbcMac96(aList[EAlgorithm_AesXcbcMac96]);
       
   192 #endif
       
   193 	return EAlgorithm_Max;
       
   194 	}
       
   195 
       
   196 //
       
   197 //  Instantiate a Cipher algorithm
       
   198 //
       
   199 CryptoSpi::CSymmetricCipher* CProtocolEay::SymmetricCipherL(TUint aAlg, const TDesC8 &aKey)
       
   200 	{
       
   201 	CryptoSpi::CSymmetricCipher *enc = NULL;
       
   202 	TUid operModeUid = CryptoSpi::KOperationModeCBCUid;
       
   203 	TUid algUid = CryptoSpi::KAesUid;
       
   204 	TUid cryptoModeUid = CryptoSpi::KCryptoModeEncryptUid;
       
   205 	TUid paddingModeUid = CryptoSpi::KPaddingModeNoneUid;
       
   206 	switch(aAlg)
       
   207 	{
       
   208 		case EAlgorithm_Descbc:
       
   209 			algUid = CryptoSpi::KDesUid;
       
   210 			break;
       
   211 		case EAlgorithm_3Descbc:
       
   212 			algUid = CryptoSpi::K3DesUid;
       
   213 			break;
       
   214 		case EAlgorithm_Aescbc:
       
   215 			algUid = CryptoSpi::KAesUid;
       
   216 			break;
       
   217 		case EAlgorithm_Aesctr:
       
   218 			algUid = CryptoSpi::KAesUid;
       
   219 			operModeUid = CryptoSpi::KOperationModeCTRUid;;
       
   220 			break;
       
   221 		default:
       
   222 			User::Leave(EIpsec_UnknownCipherNumber);	
       
   223 	}
       
   224 	// Initialize the Encryptor
       
   225 	CryptoSpi::TKeyProperty keyProperty = {algUid, KNullUid, CryptoSpi::KSymmetricKeyUid, CryptoSpi::KNonEmbeddedKeyUid};
       
   226 	CryptoSpi::CCryptoParams* keyParam =CryptoSpi::CCryptoParams::NewLC();
       
   227 	keyParam->AddL(aKey, CryptoSpi::KSymmetricKeyParameterUid);
       
   228 	CryptoSpi::CKey *key=CryptoSpi::CKey::NewLC(keyProperty, *keyParam);
       
   229 	TRAPD(res, CryptoSpi::CSymmetricCipherFactory::CreateSymmetricCipherL
       
   230 				(
       
   231 				enc, 
       
   232 				algUid, 
       
   233 				*key, 
       
   234 				cryptoModeUid, 
       
   235 				operModeUid, 
       
   236 				paddingModeUid, 
       
   237 				NULL));	
       
   238 	CleanupStack::PopAndDestroy(key);
       
   239 	CleanupStack::PopAndDestroy(keyParam);
       
   240 	if (res != KErrNone) 
       
   241 		{
       
   242 		// SetKey takes place implicit to the CreateSymmetricCipherL() factory call. If there is any issue with the key
       
   243 		// we would get KErrNotSupported which we need to map to EIpsec_BadCipherKey
       
   244 		if (res == KErrNotSupported)
       
   245 			{
       
   246 			User::Leave(EIpsec_BadCipherKey);
       
   247 			}
       
   248 		User::Leave(res);
       
   249 		}		
       
   250 	return enc;
       
   251 	}
       
   252 
       
   253 //
       
   254 //  CProtocolEay::MessageDigest
       
   255 //      Instantiate a Message Digest algorithm
       
   256 //
       
   257 CMessageDigestCrypto* CProtocolEay::MessageDigest(TUint aAlg)
       
   258 	{
       
   259 	CMessageDigest *digest = NULL;
       
   260 	// Instead of CSHA1 and CMD5, we should have TSHA1 and TMD5
       
   261 	// to be used as member classes, and the TRAP below would
       
   262 	// not be needed -- or at least, should have non-leaving
       
   263 	// New available!
       
   264 	TRAP_IGNORE(
       
   265 		switch (aAlg)
       
   266 			{
       
   267 		case EAlgorithm_Sha1:
       
   268 			digest = CSHA1::NewL();
       
   269 			break;
       
   270 		case EAlgorithm_Md5:
       
   271 			digest = CMD5::NewL();
       
   272 			break;
       
   273 		default:
       
   274 			break;
       
   275 			}
       
   276 		);
       
   277 	if (digest == NULL)
       
   278 		return NULL;	// No Engine available: out of memory or bad call.
       
   279 	CMessageDigestSymbian *wrapper = new CMessageDigestSymbian(digest);
       
   280 	if (wrapper == NULL)
       
   281 		delete digest;	// Out of memory
       
   282 	return wrapper;
       
   283 	}
       
   284 
       
   285 #ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
       
   286 CMac* CProtocolEay::GetMacImplementationL(const TDesC8& aKey)
       
   287 	{
       
   288 	//create rule based selector for filtering the desired MAC interface plug-ins.
       
   289 	CSelectionRules* rules = CSelectionRules::NewL();
       
   290 	CleanupStack::PushL(rules);
       
   291 	CSelectionRuleContent* rule = NULL;
       
   292 	const long i=0;
       
   293 	CCryptoParam* ruleValueParam =  CCryptoIntParam::NewL(0, KMacModeTypeUid);
       
   294 	
       
   295 	TUid id={KAlgorithmCipherAesXcbcMac96};
       
   296 	 rule = CSelectionRuleContent::NewL(KMacInterfaceUid,id, ruleValueParam,EOpEqual,ETrue);
       
   297 	rules->AddSelectionRuleL(rule);
       
   298 	CRuleSelector* ruleSelector = CRuleSelector::NewL(rules);
       
   299 	CleanupStack::Pop(rules);
       
   300 	CleanupStack::PushL(ruleSelector);
       
   301 	CCryptoSpiStateApi::SetSelector(ruleSelector);
       
   302 	// Create & Set the key
       
   303 	TKeyProperty keyProperty = {KAesUid, KNullUid, KSymmetricKey,KNonEmbeddedKeyUid};
       
   304 	CCryptoParams* keyParam =CCryptoParams::NewLC();
       
   305 	keyParam->AddL(aKey, KSymmetricKeyParameterUid);
       
   306 	CKey* uniKey=CKey::NewLC(keyProperty, *keyParam);
       
   307 	//Retrieve a Synchronous MAC Factory Object and use AES-XCBC-MAC-96 or any other MACalgorithm.
       
   308 	CMac* macImpl =NULL;
       
   309 	TRAPD(err,CMacFactory::CreateMacL(macImpl, KAesXcbcMac96Uid,*uniKey, NULL));
       
   310 	//cleanup uniKey and keyParam.
       
   311 	CleanupStack::PopAndDestroy(2,keyParam);
       
   312 	CCryptoSpiStateApi::UnsetSelector();
       
   313 	CleanupStack::PopAndDestroy(ruleSelector);
       
   314 	return macImpl;
       
   315 	}
       
   316 
       
   317 HBufC8* CProtocolEay::RetrieveMacValueL(CMac *aMac, const TDesC8& aSourceData )
       
   318 	{
       
   319 
       
   320 	//Retrieve the 8bit mac value
       
   321 	HBufC8* macValue = HBufC8::NewLC(16);
       
   322 	TPtr8 macPtr = macValue->Des();
       
   323 	//Copy the mac content into the heap based descriptor
       
   324 	macPtr.Copy(aMac->MacL(aSourceData));
       
   325 	CleanupStack::PopAndDestroy(macValue);
       
   326 	return  macValue;
       
   327 	}
       
   328 #endif // SYMBIAN_IPSEC_VOIP_SUPPORT