vpnengine/ikev2lib/src/ipsecproposal.cpp
changeset 0 33413c0669b9
child 2 ef893827b4d1
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Ipsec Proposal handling
       
    15 *
       
    16 */
       
    17 #include <ipsecpolapi.h>
       
    18 #include "ikedebug.h"
       
    19 #include "ipsecproposal.h"
       
    20 #include "ikev2proposal.h"
       
    21 #include "ikev2payloads.h"
       
    22 #include "ikemsgrec.h"
       
    23 #include "ikev2const.h"
       
    24 #include <networking/pfkeyv2.h>
       
    25 #include "pfkeymsg.h"
       
    26 #include "ipsecsalist.h"
       
    27 
       
    28 HBufC8* IpsecProposal::BuildIpsecSaRequestL(const TPfkeyMessage& aPfkeyMessage, TUint16 aDHGroup)
       
    29 {
       
    30     return BuildIpsecSaRequestL(aPfkeyMessage.iBase.iMsg->sadb_msg_satype,
       
    31                                 aPfkeyMessage.iProposal.iComb->sadb_comb_encrypt,
       
    32                                 aPfkeyMessage.iProposal.iComb->sadb_comb_encrypt_maxbits,
       
    33                                 aPfkeyMessage.iProposal.iComb->sadb_comb_auth,
       
    34                                 aPfkeyMessage.iProposal.iComb->sadb_comb_flags,
       
    35                                 aDHGroup);
       
    36 }
       
    37 
       
    38 
       
    39 HBufC8* IpsecProposal::BuildIpsecSaRequestL(const TUint8 aSaType, const TUint8 aEncryptAlg, 
       
    40                                             const TUint16 aEncryptMaxbits, 
       
    41                                             const TUint8 aAuthAlg, const TUint16 aFlags,
       
    42                                             TUint16 aDHGroup)
       
    43 {
       
    44 	//
       
    45 	// Build Ipsec SA proposal from PFKEY acquire primitive policy data
       
    46 	// In this phase PFKEY Aqcuire contains only one proposal
       
    47 	// (transform)
       
    48 	//
       
    49     HBufC8* proposal = HBufC8::NewL(1024);   
       
    50     
       
    51 	TUint8  TransCnt = 0;
       
    52 	TBool   IntegAlg = EFalse;
       
    53 	TUint16 SaLth    = 0;
       
    54 	TUint16 TranLth  = 0;	
       
    55 	TUint16 PropLth  = 0;
       
    56 
       
    57 	TProposalIkev2*  Proposal  = TProposalIkev2::Cast(const_cast<TUint8*>(proposal->Ptr()));
       
    58 	TTransformIkev2* Transform = NULL;
       
    59 	TDataAttributes* Attributes;
       
    60 	
       
    61 	TPayloadIkev2::Cast(Proposal)->Init();   // Initialize Payload general header
       
    62 	TPayloadIkev2::Cast(Proposal)->SetNextPayload(IKEV2_PAYLOAD_NONE);		
       
    63 	Proposal->SetNum(1);
       
    64 	Proposal->SetSPISize(4); // SPI value shall be added later to proposal
       
    65 	PropLth = (TUint16)Proposal->PropHdrLth();
       
    66 
       
    67 	switch ( aSaType )
       
    68 	{
       
    69 		case SADB_SATYPE_AH:
       
    70 			Proposal->SetProtocol(IKEV2_IPSEC_AH);
       
    71 			IntegAlg = ETrue;
       
    72 			break;
       
    73 
       
    74 		case SADB_SATYPE_ESP:
       
    75 			TransCnt ++;
       
    76 			Proposal->SetProtocol(IKEV2_IPSEC_ESP);
       
    77 			Transform = Proposal->TransformPl();
       
    78 			TPayloadIkev2::Cast(Transform)->Init();   // Initialize Payload general header
       
    79 			TPayloadIkev2::Cast(Transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS);	
       
    80 			Transform->SetReserved();
       
    81 			Transform->SetType(IKEV2_ENCR);   // Encryption Algorithm transform (1)
       
    82 			TranLth = (TUint16)Transform->Size();
       
    83 			
       
    84 			switch ( aEncryptAlg )
       
    85 			{
       
    86 				case ENCR_DES:
       
    87 					Transform->SetID(ENCR_DES);
       
    88 					break;
       
    89 
       
    90 				case ENCR_3DES:
       
    91 					Transform->SetID(ENCR_3DES);
       
    92 					break;
       
    93 
       
    94 				case ENCR_NULL:
       
    95 					Transform->SetID(ENCR_NULL);
       
    96 					break;
       
    97 
       
    98 				case ENCR_AES_CBC:
       
    99 					Transform->SetID(ENCR_AES_CBC);
       
   100 					//
       
   101 					// Variable key length algorithm. Get key length
       
   102 					// attribute to transform data.
       
   103 					//
       
   104 					Attributes = Transform->Attributes();
       
   105 					Attributes->SetType(IKEV2_ENCR_KEY_LTH);
       
   106 					Attributes->SetBasic();
       
   107 					if ( aEncryptMaxbits )
       
   108 						 Attributes->SetValue(aEncryptMaxbits);
       
   109 					else Attributes->SetValue(128);	//default AES key size
       
   110 					TranLth = (TUint16)(TranLth + Attributes->Size());
       
   111 					break;
       
   112 
       
   113 				default:
       
   114 					User::Leave(KErrNotSupported);
       
   115                     break;
       
   116 			}
       
   117 			TPayloadIkev2::Cast(Transform)->SetLength(TranLth);		
       
   118 			PropLth = (TUint16)(PropLth + TranLth);
       
   119 			if ( aAuthAlg != SADB_AALG_NONE )
       
   120 				IntegAlg = ETrue;	
       
   121 			break;
       
   122 
       
   123 		default:
       
   124 			User::Leave(KErrNotSupported);
       
   125             break;
       
   126 	}
       
   127 	
       
   128 	if ( IntegAlg )
       
   129 	{
       
   130 		TransCnt ++;				
       
   131 		if ( Transform ) 
       
   132 		     Transform = (TTransformIkev2*)TPayloadIkev2::Cast(Transform)->Next();
       
   133 		else Proposal->TransformPl();
       
   134 		TPayloadIkev2::Cast(Transform)->Init();   // Initialize Payload general header				
       
   135 		TPayloadIkev2::Cast(Transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS);
       
   136 		Transform->SetType(IKEV2_INTEG);          // Integrity Algorithm transform
       
   137 		Transform->SetReserved();		
       
   138 		TranLth = (TUint16)Transform->Size();		
       
   139 		switch ( aAuthAlg )
       
   140 		{
       
   141 			case SADB_AALG_MD5HMAC:
       
   142 				Transform->SetID(AUTH_HMAC_MD5_96);
       
   143 				break;
       
   144 
       
   145 			case SADB_AALG_SHA1HMAC:
       
   146 				Transform->SetID(AUTH_HMAC_SHA1_96);
       
   147 				break;
       
   148 
       
   149 			default:
       
   150 				User::Leave(KErrNotSupported);
       
   151 		}
       
   152 		TPayloadIkev2::Cast(Transform)->SetLength(TranLth);		
       
   153 		PropLth = (TUint16)(PropLth + TranLth);
       
   154 	}
       
   155 
       
   156 	if ( (aDHGroup != 0 ) && (aFlags & SADB_SAFLAGS_PFS) )
       
   157 	{
       
   158 	   TransCnt ++;
       
   159 	   Transform = (TTransformIkev2*)TPayloadIkev2::Cast(Transform)->Next();
       
   160 	   TPayloadIkev2::Cast(Transform)->Init();   // Initialize Payload general header
       
   161 	   TPayloadIkev2::Cast(Transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS);	   
       
   162 	   Transform->SetType(IKEV2_DH);   // Diffie-Hellman Group (4)
       
   163 	   Transform->SetReserved();
       
   164 	   Transform->SetID(aDHGroup);	   
       
   165 	   TranLth = (TUint16)Transform->Size();
       
   166 	   TPayloadIkev2::Cast(Transform)->SetLength(TranLth);		
       
   167 	   PropLth = (TUint16)(PropLth + TranLth);
       
   168 	}
       
   169 	//
       
   170 	// Add ESN trasnform to Proposal with fixed value not used (0) 
       
   171 	//
       
   172 	TransCnt ++;
       
   173 	Transform = (TTransformIkev2*)TPayloadIkev2::Cast(Transform)->Next();
       
   174 	TPayloadIkev2::Cast(Transform)->Init();   // Initialize Payload general header
       
   175 	TPayloadIkev2::Cast(Transform)->SetNextPayload(IKEV2_PAYLOAD_NONE);
       
   176 	Transform->SetType(IKEV2_ESN);   // ESN (5) [64-bit sequence numbers with ESP]
       
   177 	Transform->SetReserved();
       
   178 	Transform->SetID(0);	   
       
   179 	TranLth = (TUint16)Transform->Size();
       
   180 	TPayloadIkev2::Cast(Transform)->SetLength(TranLth);		
       
   181 	PropLth = (TUint16)(PropLth + TranLth);
       
   182 	
       
   183 	TPayloadIkev2::Cast(Transform)->SetNextPayload(IKEV2_PAYLOAD_NONE);	
       
   184 	Proposal->SetNumTrans(TransCnt);
       
   185 	TPayloadIkev2::Cast(Proposal)->SetLength(PropLth);			
       
   186 	SaLth  = (TUint16)(SaLth + PropLth);
       
   187 		
       
   188 	proposal->Des().SetLength(SaLth);
       
   189 	
       
   190 	HBufC8 *reAllocatedProposal = proposal->ReAlloc(proposal->Length()); 
       
   191 	if (reAllocatedProposal != NULL)
       
   192 	    {
       
   193 	    proposal = reAllocatedProposal;
       
   194 	    }
       
   195 	
       
   196 	return proposal;
       
   197 }
       
   198 
       
   199 
       
   200 HBufC8* IpsecProposal::BuildIpsecSaFromPolicyL(const CIpsecSaSpecList& aSaList, TUint16 aDhGroup)
       
   201 {
       
   202     __ASSERT_DEBUG(aSaList.Count() > 0, User::Invariant());
       
   203 
       
   204     static const TUint KProposalMaxLength = 64;
       
   205     static const TUint KSpiSize = 4;
       
   206     HBufC8* saData = HBufC8::NewL(KProposalMaxLength);
       
   207     TPtr8 saDataPtr = saData->Des();
       
   208 
       
   209     const TIpsecSaSpec& saSpec = aSaList.At(0);
       
   210     TProposalIkev2* proposal  = TProposalIkev2::Cast(saDataPtr.Ptr());
       
   211     TPayloadIkev2::Cast(proposal)->Init();   // Initialize Payload general header
       
   212     TPayloadIkev2::Cast(proposal)->SetNextPayload(IKEV2_PAYLOAD_NONE);      
       
   213     proposal->SetNum(1);
       
   214     proposal->SetSPISize(KSpiSize); // SPI value shall be added later to proposal
       
   215 
       
   216     
       
   217     TTransformIkev2* transform = NULL;
       
   218     
       
   219     TUint8 transformCount = 0;
       
   220     switch ( saSpec.iType )
       
   221     {
       
   222         case SADB_SATYPE_AH:
       
   223             proposal->SetProtocol(IKEV2_IPSEC_AH);
       
   224             saDataPtr.SetLength(proposal->Size() + KSpiSize);
       
   225             break;
       
   226 
       
   227         case SADB_SATYPE_ESP:
       
   228             {
       
   229             transformCount++;
       
   230             proposal->SetProtocol(IKEV2_IPSEC_ESP);
       
   231             transform = proposal->TransformPl();
       
   232             TPayloadIkev2::Cast(transform)->Init();   // Initialize Payload general header
       
   233             TPayloadIkev2::Cast(transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS);    
       
   234             transform->SetReserved();
       
   235             transform->SetType(IKEV2_ENCR);   // Encryption Algorithm transform (1)
       
   236             
       
   237             TUint16 tranformLength = transform->Size();
       
   238 
       
   239             transform->SetID(saSpec.iEalg);
       
   240             if ( saSpec.iEalg == ENCR_AES_CBC )
       
   241             {
       
   242                 //
       
   243                 // Variable key length algorithm. Get key length
       
   244                 // attribute to transform data.
       
   245                 //
       
   246                 TDataAttributes* attributes = transform->Attributes();
       
   247                 attributes->SetType(IKEV2_ENCR_KEY_LTH);
       
   248                 attributes->SetBasic();
       
   249                 if ( saSpec.iEalgLen )
       
   250                      attributes->SetValue((TUint16)saSpec.iEalgLen);
       
   251                 else attributes->SetValue(128); //default AES key size
       
   252                 tranformLength += (TUint16)attributes->Size();
       
   253             }   
       
   254             TPayloadIkev2::Cast(transform)->SetLength(tranformLength);
       
   255             saDataPtr.SetLength(proposal->Size() + KSpiSize + tranformLength);            
       
   256             }
       
   257             break;
       
   258 
       
   259         default:
       
   260             break;
       
   261 
       
   262     }   
       
   263     
       
   264     if (  saSpec.iType == SADB_SATYPE_AH ||
       
   265          (saSpec.iType == SADB_SATYPE_ESP && saSpec.iAalg != SADB_AALG_NONE) )
       
   266      {
       
   267          transformCount++;                
       
   268          if ( transform )
       
   269              {
       
   270              transform = (TTransformIkev2*)TPayloadIkev2::Cast(transform)->Next();
       
   271              }
       
   272          else 
       
   273              {         
       
   274              transform = proposal->TransformPl();
       
   275              }
       
   276          
       
   277          TPayloadIkev2::Cast(transform)->Init();   // Initialize Payload general header              
       
   278          TPayloadIkev2::Cast(transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS);
       
   279          transform->SetType(IKEV2_INTEG);          // Integrity Algorithm transform
       
   280          transform->SetReserved();                  
       
   281          switch ( saSpec.iAalg )
       
   282          {
       
   283              case SADB_AALG_MD5HMAC:
       
   284                  transform->SetID(AUTH_HMAC_MD5_96);
       
   285                  break;
       
   286 
       
   287              case SADB_AALG_SHA1HMAC:
       
   288                  transform->SetID(AUTH_HMAC_SHA1_96);
       
   289                  break;
       
   290 
       
   291              default:
       
   292                  break;
       
   293          }
       
   294          TPayloadIkev2::Cast(transform)->SetLength(transform->Size());     
       
   295          saDataPtr.SetLength(saDataPtr.Length() + transform->Size()); 
       
   296      }    
       
   297     
       
   298     if ( (aDhGroup != 0 ) && saSpec.iPfs )
       
   299     {
       
   300         transformCount++;
       
   301         transform = (TTransformIkev2*)TPayloadIkev2::Cast(transform)->Next();
       
   302         TPayloadIkev2::Cast(transform)->Init();   // Initialize Payload general header
       
   303         TPayloadIkev2::Cast(transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS);       
       
   304         transform->SetType(IKEV2_DH);   // Diffie-Hellman Group (4)
       
   305         transform->SetReserved();
       
   306         transform->SetID(aDhGroup);            
       
   307         TPayloadIkev2::Cast(transform)->SetLength(transform->Size());     
       
   308         saDataPtr.SetLength(saDataPtr.Length() + transform->Size());
       
   309     }
       
   310     
       
   311     transformCount++;
       
   312     transform = (TTransformIkev2*)TPayloadIkev2::Cast(transform)->Next();
       
   313     TPayloadIkev2::Cast(transform)->Init();   // Initialize Payload general header
       
   314     TPayloadIkev2::Cast(transform)->SetNextPayload(IKEV2_PAYLOAD_NONE);
       
   315     transform->SetType(IKEV2_ESN);   // ESN (5) [64-bit sequence numbers with ESP]
       
   316     transform->SetReserved();
       
   317     transform->SetID(0);       
       
   318     TPayloadIkev2::Cast(transform)->SetLength(transform->Size());     
       
   319     saDataPtr.SetLength(saDataPtr.Length() + transform->Size());
       
   320 
       
   321     proposal->SetNumTrans(transformCount);
       
   322     TPayloadIkev2::Cast(proposal)->SetLength(saDataPtr.Length());
       
   323             
       
   324     return saData;
       
   325 }
       
   326