gba/uicc/src/GbaAkaIsa.cpp
changeset 0 164170e6151a
child 5 3b17fc5c9564
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gba/uicc/src/GbaAkaIsa.cpp	Tue Jan 26 15:20:08 2010 +0200
@@ -0,0 +1,846 @@
+/*
+* Copyright (c) 2007 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:  Implementation of class CAkaIsaInterface
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <e32math.h>
+#include <etelmmerr.h>
+#include <mmtsy_names.h>            //TSY and Phone name
+#include <hash.h>
+#include <implementationproxy.h>    //for ecom
+#include "GBAAkaIsa.h"
+#include "GBALogger.h"
+#include "GbaCommon.h"
+
+//Constants
+const TInt KMaxBufferSize = 256;
+const TInt KNetworkIdLength2 = 2;
+const TInt KNetworkIdLength3 = 3;
+const TInt KIntegerConstant4 = 4;
+const TInt KIntegerConstant16 = 16;
+const TInt KIntegerConstant32 = 32;
+
+_LIT8( KAT, "@" );
+_LIT8( KIMSMNC, "ims.mnc" );
+_LIT8( KIMSMNC0, "ims.mnc0" );
+_LIT8( KBSFMNC, "bsf.mnc" ); 
+_LIT8( KBSFMNC0, "bsf.mnc0" );     
+_LIT8( KMCC,".mcc");        
+_LIT8( KPUB3GPPORG, ".pub.3gppnetwork.org");
+_LIT8( K3GPPORG, ".3gppnetwork.org");
+_LIT8( K3GPPGBARES, "3gpp-gba-res");
+_LIT8( K3GPPGBAKS, "3gpp-gba-ks");
+_LIT8( KGBAME, "gba-me");
+
+#ifdef __WINS__
+_LIT8( KWINTESTID, "test@pub.3gpp.org");
+#endif
+
+static MUICCInterface* NewFunctionL();
+
+
+// ======== LOCAL FUNCTIONS ========
+// ---------------------------------------------------------------------------
+// MUICCInterface* NewFunctionL()
+// ---------------------------------------------------------------------------
+//
+MUICCInterface* NewFunctionL()
+    {
+    GBA_TRACE_DEBUG(("MUICCInterface* NewFunctionL"));
+    MUICCInterface* UICCInterface = NULL;
+    UICCInterface = CAkaIsaInterface::NewL();
+    return UICCInterface;
+    }
+
+
+// -----------------------------------------------------------------------------
+// TImplementationProxy ImplementationTable[] 
+// -----------------------------------------------------------------------------
+//
+const TImplementationProxy ImplementationTable[] =
+    {
+    IMPLEMENTATION_PROXY_ENTRY(GBA_UICC_INTERFACE_IMPLE, NewFunctionL)
+    };
+
+
+// -----------------------------------------------------------------------------
+// TImplementationProxy* ImplementationGroupProxy()
+// This function is needed by ECom and is the only one exported function
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+    {
+    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+    return (ImplementationTable);
+    }
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::CAkaIsaInterface()
+// -----------------------------------------------------------------------------
+//
+CAkaIsaInterface::CAkaIsaInterface():iCardInterface( ENoInterface )   
+    {
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::NewL()
+// -----------------------------------------------------------------------------
+//
+MUICCInterface* CAkaIsaInterface::NewL()
+    {
+    GBA_TRACE_DEBUG(("Constructing: CAkaIsaInterface"));
+    CAkaIsaInterface* self = new(ELeave) CAkaIsaInterface();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    GBA_TRACE_DEBUG(("Construction complete: CAkaIsaInterface"));
+    return self;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::NewL()
+// -----------------------------------------------------------------------------
+//
+void CAkaIsaInterface::ConstructL()
+    {
+    GBA_TRACE_BEGIN();
+    //Connect to ETel server
+    User::LeaveIfError( iEtelServer.Connect() );
+    //Load phone module
+    User::LeaveIfError( iEtelServer.LoadPhoneModule( KMmTsyModuleName ) );
+    //open phone
+    User::LeaveIfError( iPhone.Open( iEtelServer, KMmTsyPhoneName ) );
+    //open custom api
+    User::LeaveIfError( iCustomAPI.Open(iPhone) );
+    // check card interface, initialize iCardInterface
+    QueryCardInterfaceL();
+    GBA_TRACE_END();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::~CAkaIsaInterface()
+// -----------------------------------------------------------------------------
+//
+CAkaIsaInterface::~CAkaIsaInterface()
+    {
+    GBA_TRACE_BEGIN();
+    //Close all created resources 
+    iCustomAPI.Close(); 
+    iPhone.Close();
+    iEtelServer.Close();
+    GBA_TRACE_END();
+    }
+
+
+void CAkaIsaInterface::QueryIdentityL( TDes8& aIdentity ) 
+    {
+    #ifdef __WINS__
+    aIdentity.Copy(KWINTESTID);
+    return;
+    #endif
+
+    GBA_TRACE_BEGIN();
+    GBA_TRACE_DEBUG(("QueryIdentity is starting..."));
+    
+    TUint32 caps = 0;
+    GBA_TRACE_DEBUG(("Phone is open now doing the actual query..."));
+
+    // Get capability
+    User::LeaveIfError( iPhone.GetIdentityCaps( caps ) );
+
+    if ( caps & (RMobilePhone::KCapsGetSubscriberId))
+        {
+        RMobilePhone::TMobilePhoneSubscriberId id;
+        
+        TRequestStatus status;
+        
+        status =  KRequestPending;
+        RMobilePhone::TMobilePhoneSubscriberId iccID;
+        iPhone.GetSubscriberId( status, iccID );
+        User::WaitForRequest( status );
+        
+        GBA_TRACE_DEBUG_NUM(("Can't get IMSI, error = %d"), status.Int() );
+        User::LeaveIfError( status.Int() );
+        
+        GBA_TRACE_DEBUG(("id="));
+        GBA_TRACE_DEBUG_DESC(iccID);
+
+        aIdentity.Zero();
+        aIdentity.Copy(iccID);
+        
+        // derive the ending part
+        // get the mobile network name MNC and country code MCC
+        
+        //Make IMPI 
+        RMobilePhone::TMobilePhoneNetworkInfoV1 info;
+        TPckg<RMobilePhone::TMobilePhoneNetworkInfoV1> netInfoPckg(info);
+        status =  KRequestPending;
+        iPhone.GetHomeNetwork(status, netInfoPckg);
+        
+        User::WaitForRequest( status );
+        GBA_TRACE_DEBUG_NUM(("Can't get network name, error = %d"), status.Int() );
+        User::LeaveIfError( status.Int() );
+        
+        // append the "<IMSI>@ims.mnc<MNC>.mcc<MCC>.3gppnetwork.org"
+        
+        aIdentity.Append( KAT );
+
+        if ( info.iNetworkId.Length() == KNetworkIdLength2 )
+            {
+            //add one more zero if only 2 digits
+            aIdentity.Append( KIMSMNC0 );
+            }
+    
+        if ( info.iNetworkId.Length() == KNetworkIdLength3 )
+            {
+            aIdentity.Append( KIMSMNC ); 
+            }
+
+        aIdentity.Append( info.iNetworkId );
+
+        aIdentity.Append( KMCC );        
+        aIdentity.Append( info.iCountryCode );
+        aIdentity.Append( K3GPPORG );
+      
+
+        GBA_TRACE_DEBUG(("aIdentity="));
+        GBA_TRACE_DEBUG_DESC(aIdentity);
+        }
+    else
+        {
+        aIdentity.Copy(_L8(""));
+        }
+    
+    GBA_TRACE_END();
+    }
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::QueryAuthenticationGBAUL
+// If the GBA_U available, pass RAND and AUTN to smart card via custom API
+// otherwise use RMobilePhone instead
+// -----------------------------------------------------------------------------
+TBool CAkaIsaInterface::QueryAuthenticationGBAUL(   const TDesC8& aNonce,
+                                                    TDes8& aResponse,
+                                                    TDes8& aResync ) 
+    {
+    GBA_TRACE_BEGIN();
+    TBool keys_available = ETrue;
+    //creat buffer to carry the input and output value
+    RMmCustomAPI::TSimAuthenticationGbaBootstrap gbadata;
+    
+    RMmCustomAPI::TGbaBootstrapDataPckg gbabuf( gbadata ); 
+    
+    //Copy input data, RAND and AUTN
+    gbadata.iRandomParameters.Copy(aNonce.Ptr(),KAKA_RAND_LENGTH);
+    gbadata.iAUTN.Copy(aNonce.Ptr()+KAKA_RAND_LENGTH,KAKA_RAND_LENGTH);
+    
+    //call the API to get the RES 
+    TRequestStatus status;
+    
+    status =  KRequestPending;
+    
+    GBA_TRACE_DEBUG(("Send Authentication request to card"));
+    iCustomAPI.GetWlanSimAuthenticationData( status, gbabuf );
+    GBA_TRACE_DEBUG(("Wait for result..."));
+    User::WaitForRequest( status );
+    
+    GBA_TRACE_DEBUG_NUM(("Authentication is Done, err = %d"),status.Int() );
+
+    if(status == KErrNone)
+        {
+        aResponse.Copy(gbadata.iRES);
+        GBA_TRACE_DEBUG_BINARY(gbadata.iRES);
+        }
+    else
+        {
+        keys_available = EFalse;
+        
+        if (status != KErrMMEtelSqnVerificationFailed )
+            {
+            User::LeaveIfError( status.Int() );
+            }
+        }
+
+    if ( status == KErrMMEtelSqnVerificationFailed )
+        {
+        GBA_TRACE_DEBUG_NUM(("AUTS len is Done !!!, len = %d"), gbadata.iAUTS.Length() );
+        GBA_TRACE_DEBUG_BINARY(gbadata.iAUTS);
+      
+        if(gbadata.iAUTS.Length() == 0)
+            {
+            GBA_TRACE_DEBUG(("Auts is Still zero !!!!!"));
+            }
+       else
+            {
+            GBA_TRACE_DEBUG((" before copy"));
+            aResync.Copy(gbadata.iAUTS); 
+            GBA_TRACE_DEBUG(("after copy auts"));
+            }
+        }
+    GBA_TRACE_DEBUG((" Done!"));
+    GBA_TRACE_END(); 
+    return keys_available;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::QueryAuthentication2GL
+// If the GBA_U available, pass RAND and AUTN to smart card via custom API
+// otherwise use RMobilePhone instead
+// run simulated aka
+// -----------------------------------------------------------------------------
+
+void CAkaIsaInterface::QueryAuthentication2GL(  const TDesC8& aNonce, TDes8& aResponse )
+    {
+    GBA_TRACE_BEGIN();
+    RMmCustomAPI::TSimAuthenticationEapSim authSIMdata;
+    RMmCustomAPI::TSimDataPckg authSIMBuf(authSIMdata);
+    
+    TRequestStatus status;
+    status =  KRequestPending;
+    
+    authSIMdata.iRandomParameters.Copy(aNonce.Ptr(),KAKA_RAND_LENGTH);
+    GBA_TRACE_DEBUG(("SIM authentication"));
+    iCustomAPI.GetWlanSimAuthenticationData(status,authSIMBuf);
+    
+    User::WaitForRequest( status );
+    GBA_TRACE_DEBUG_NUM(("GetWlanSimAuthenticationData return, status = %d"), status.Int() );
+    User::LeaveIfError( status.Int() );
+    
+    GBA_TRACE_DEBUG(("Creating 2G authentication vector KDF(key,\"3gpp-gba-res\",sres)"));
+    GBA_TRACE_DEBUG_BINARY(authSIMdata.iSRES);
+    GBA_TRACE_DEBUG_BINARY(authSIMdata.iKC);
+    
+    TBuf8<KMaxBufferSize> lastSRESKC;
+    TBuf8<2*RMmCustomAPI::KMaxKCLength+KAKA_RAND_LENGTH> kc2;
+    
+    // COPYING Kc twice
+    GBA_TRACE_DEBUG(("Copying iKC"));
+    for( TInt  i=0; i<(RMmCustomAPI::KMaxKCLength) ; i++ )
+        {
+        kc2.Append(  (TUint8)(authSIMdata.iKC[i]) );
+        }
+    GBA_TRACE_DEBUG(("Copying iKC"));
+    for( TInt  i=0;i<(RMmCustomAPI::KMaxKCLength);i++ )
+        {
+        kc2.Append(  (TUint8)(authSIMdata.iKC[i]) );
+        }
+    GBA_TRACE_DEBUG(("appending RAND"));
+    kc2.Append(aNonce.Ptr(),KAKA_RAND_LENGTH);
+    
+    GBA_TRACE_DEBUG(("K part"));
+    GBA_TRACE_DEBUG_BINARY(kc2);
+    
+    // appending RAND
+    lastSRESKC.Append( 0x01);
+    lastSRESKC.Append(K3GPPGBARES);
+    lastSRESKC.Append( 0x00);
+    lastSRESKC.Append( 0x0C);
+    GBA_TRACE_DEBUG(("Copying SRES"));
+    
+    for( TInt i=0; i<KIntegerConstant4; i++ )
+        {
+        lastSRESKC.Append( (TUint8)(authSIMdata.iSRES[i]) );
+        }
+    lastSRESKC.Append( 0x00);
+    lastSRESKC.Append( 0x04);
+    GBA_TRACE_DEBUG(("S part"));
+    GBA_TRACE_DEBUG_BINARY(lastSRESKC);
+    
+    // derive response
+    CMessageDigest* digest = CMessageDigestFactory::NewDigestL( CMessageDigest::ESHA256);
+    CleanupStack::PushL( digest );
+    CHMAC* sha256 = CHMAC::NewL(kc2, digest);
+    CleanupStack::Pop( digest );
+    CleanupStack::PushL( sha256 );
+    TPtrC8 hash(sha256->Hash(lastSRESKC));
+    GBA_TRACE_DEBUG(("resulting hash: "));
+    GBA_TRACE_DEBUG_BINARY(hash);
+    
+    aResponse.Append(hash.Ptr(),KRESPONSE_2G_LENGTH);
+    
+    // KEY MATERIAL NEEDS TO BE STORED
+    // CHECK 3GPP TS 3.3220 V7.5.0 (2006-09) page 54 item 7
+    // The BSF shall generate key material Ks by computing Ks = KDF (key, Ks-input, "3gpp-gba-ks", SRES).
+    // The B-TID value shall be also generated in format of NAI by taking the base64 encoded [12] RAND value
+    // from step 3, and the BSF server name, i.e. base64encoded(RAND)@BSF_servers_domain_name.
+    GBA_TRACE_DEBUG(("DERIVING THE MASTER KEY Ks"));
+    
+    TBuf8<KMaxBufferSize> hashMaterial;
+    hashMaterial.Append(0x01);
+    hashMaterial.Append(aNonce.Mid(KIntegerConstant32,KIntegerConstant16));
+    hashMaterial.Append(0x00);
+    hashMaterial.Append(0x10);
+    hashMaterial.Append(K3GPPGBAKS);
+    hashMaterial.Append(0x00);
+    hashMaterial.Append(0x0b);
+    hashMaterial.Append(authSIMdata.iSRES.Left(RMmCustomAPI::KMaxRESLength));
+    hashMaterial.Append(0x00);
+    hashMaterial.Append(0x04);
+    
+    GBA_TRACE_DEBUG(("key for creating the key"));
+    GBA_TRACE_DEBUG_BINARY(kc2);
+    
+    GBA_TRACE_DEBUG(("hashing material for creating the key"));
+    GBA_TRACE_DEBUG_BINARY(hashMaterial);
+    
+    TPtrC8 keymaterial( sha256->Hash( hashMaterial) );
+    
+    GBA_TRACE_DEBUG(("Master key Ks, !!! Remove from LOG"));
+    GBA_TRACE_DEBUG_BINARY(keymaterial);
+    
+    iCKBuf.Copy(keymaterial.Left(KIntegerConstant16));
+    iIKBuf.Copy(keymaterial.Mid(KIntegerConstant16,KIntegerConstant16));
+    
+    CleanupStack::PopAndDestroy( sha256 );
+    
+    GBA_TRACE_DEBUG(("Done!"));
+    GBA_TRACE_END();
+    }
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::QueryAuthentication3GL
+// If the GBA_U available, pass RAND and AUTN to smart card via custom API
+// otherwise use RMobilePhone instead
+// run aka
+// -----------------------------------------------------------------------------
+TBool CAkaIsaInterface::QueryAuthentication3GL(   const TDesC8& aNonce,
+                                                    TDes8& aResponse,
+                                                    TDes8& aResync )
+    {
+    GBA_TRACE_BEGIN();
+    TBool keys_available = ETrue;
+    
+    RMmCustomAPI::TSimAuthenticationEapAka authAkadata;
+    RMmCustomAPI::TAkaDataPckg authAkaBuf(authAkadata);
+    TRequestStatus status;
+    status =  KRequestPending;
+    authAkadata.iRandomParameters.Copy(aNonce.Ptr(),KAKA_RAND_LENGTH);
+    authAkadata.iAUTN.Copy(aNonce.Ptr()+KAKA_RAND_LENGTH,KAKA_RAND_LENGTH);
+    GBA_TRACE_DEBUG(("AKA authentication"));
+    
+    iCustomAPI.GetWlanSimAuthenticationData(status,authAkaBuf);
+    User::WaitForRequest( status );
+    
+    GBA_TRACE_DEBUG_NUM(("GBA_ME:QueryAuthentication3GL: Authentication error = %d"),status.Int()  );
+    
+    if( status.Int() == KErrNone )
+        {
+        GBA_TRACE_DEBUG(("AKA, appending result"));
+        aResponse.Copy(authAkadata.iRES);
+        GBA_TRACE_DEBUG_BINARY(authAkadata.iRES);
+        
+        GBA_TRACE_DEBUG(("storing keys"));
+        
+        // store results
+        iCKBuf.Copy(authAkadata.iCK);
+        iIKBuf.Copy(authAkadata.iIK);
+        }
+    else
+        {
+        keys_available = EFalse;
+        
+        if (status != KErrMMEtelSqnVerificationFailed )
+            {
+            User::LeaveIfError( status.Int() );
+            }
+        }
+    
+    if ( status == KErrMMEtelSqnVerificationFailed )
+        {
+        GBA_TRACE_DEBUG_NUM(("GBA_ME:QueryAuthentication3GL: AUTS len is Done !!!, len = %d"), authAkadata.iAUTS.Length() );
+        GBA_TRACE_DEBUG_BINARY( authAkadata.iAUTS );
+        
+        if(authAkadata.iAUTS.Length() == 0)
+            {
+            GBA_TRACE_DEBUG(("GBA_U:QueryAuthentication3GL: Auts is Still zero !!!!!"));
+            }
+        else
+            {
+            GBA_TRACE_DEBUG(("QueryAuthentication3GL before copy"));
+            aResync.Copy(authAkadata.iAUTS);
+            GBA_TRACE_DEBUG(("QueryAuthentication3GL after copy auts"));
+            }
+        }
+    GBA_TRACE_END();
+    return keys_available;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::QueryAuthenticationL
+// If the GBA_U available, pass RAND and AUTN to smart card via custom API
+// otherwise use RMobilePhone instead
+// -----------------------------------------------------------------------------
+TBool CAkaIsaInterface::QueryAuthenticationL(
+     const TDesC8& aNonce, 
+     TDes8& aResponse, 
+     TDes8& aResync ) 
+    {
+    GBA_TRACE_BEGIN();
+    GBA_TRACE_DEBUG(("aka nonce="));
+    GBA_TRACE_DEBUG_BINARY(aNonce);
+    // GBA_U not availiable
+    if ( iCardInterface != EGBAUInterface )
+        {
+        GBA_TRACE_DEBUG(("QueryAuthenticationL is starting..."));
+        
+        //run aka
+        if ( iCardInterface == E3GInterface )
+            {
+            return QueryAuthentication3GL( aNonce, aResponse, aResync );
+            }
+        
+        // run simulated aka
+        if ( iCardInterface == E2GInterface )
+            {
+            QueryAuthentication2GL( aNonce, aResponse );
+            return ETrue;
+            }
+        return EFalse;
+        }
+    else
+        {
+        GBA_TRACE_DEBUG(("GBA_U authentication"));
+        return QueryAuthenticationGBAUL( aNonce, aResponse, aResync );   
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::QueryKeyMaterialL()
+// If GBA_U, send the request to smart card.
+// -----------------------------------------------------------------------------
+//
+void CAkaIsaInterface::QueryKeyMaterialL(const TDesC8& aKey, const TDesC8& aRand, const TDesC8& aIMPI, const TDesC8& aUTF8_NAF_ID, TDes8& aDerivedKey ) 
+    {
+    if ( iCardInterface == EGBAUInterface )
+        { 
+        GBA_TRACE_DEBUG_BINARY(aUTF8_NAF_ID);
+
+        GBA_TRACE_DEBUG(("GBA_U:QueryKeyMaterialL: Enter the function"));
+        
+        TRequestStatus status;
+        status =  KRequestPending;
+
+        RMmCustomAPI::TSimAuthenticationGbaNafDerivation nafdata;
+    
+        RMmCustomAPI::TGbaNafDerivationDataPckg nafbuf( nafdata );
+  
+        nafdata.iNafId.Copy( aUTF8_NAF_ID );
+        
+        
+        GBA_TRACE_DEBUG(("GBA_U:QueryKeyMaterialL: copy nafid, no truncate"));
+        GBA_TRACE_DEBUG_BINARY(aUTF8_NAF_ID);
+        
+        nafdata.iImpi.Copy( aIMPI );
+        
+         GBA_TRACE_DEBUG(("GBA_U:QueryKeyMaterialL: copy impi, no truncate"));
+        iCustomAPI.GetWlanSimAuthenticationData( status, nafbuf ); 
+       
+        User::WaitForRequest( status ); 
+        
+        GBA_TRACE_DEBUG_NUM(("GBA_U:QueryKeyMaterialL: QueryKeyMaterial is Done, err = %d"), status.Int());
+          
+        User::LeaveIfError( status.Int() );
+
+        aDerivedKey.Copy( nafdata.iKsExtNaf ); //return the ks_ext_naf
+        }
+    else //GBA_ME
+        {
+        GBA_TRACE_DEBUG(("QueryKeyMaterial"));
+        GBA_TRACE_DEBUG(("derive key as specified in 33.22 V7.5.0 page 35"));
+        // derive key as specified in 33.22 V7.5.0 page 35
+        // S = FC || P0 || L0 || P1 || L1 || P2 || L2 || P3 || L3 ||... || Pn || Ln
+        // derived key = HMAC-SHA-256 ( Key , S )
+        // -  FC = 0x01,
+        // -  P1 = RAND,
+        // -  L1 = length of RAND is 16 octets (i.e. 0x00 0x10),
+        // -  P2 = IMPI encoded to an octet string using UTF-8 encoding (see clause B.2.1),
+        // -  L2 = length of IMPI is variable (not greater that 65535),
+        // -  P3 = NAF_ID with the FQDN part of the NAF_ID encoded to an octet string using UTF-8 encoding (see clause B.2.1), and
+        // -  L3 = length of NAF_ID is variable (not greater that 65535).
+        // In the key derivation of Ks_NAF as specified in clause 4 and Ks_ext_NAF as specified in clause 5,
+        // -  P0 = "gba-me" (i.e. 0x67 0x62 0x61 0x2d 0x6d 0x65), and
+        // -  L0 = length of P0 is 6 octets (i.e., 0x00 0x06).
+        // In the key derivation of Ks_int_NAF as specified in clause 5,
+        // -  P0 = "gba-u" (i.e. 0x67 0x62 0x61 0x2d 0x75), and
+        // -  L0 = length of P0 is 5 octets (i.e., 0x00 0x05).
+        TBuf8<KMaxBufferSize> ks_NAF_material;
+        // FC
+        ks_NAF_material.Append(0x01);
+        // P0
+        ks_NAF_material.Append(KGBAME);
+        // L0
+        ks_NAF_material.Append(0x00);
+        ks_NAF_material.Append(0x06);
+        // P1
+        ks_NAF_material.Append(aRand);
+        // L1 - length of rand in two bytes
+        ks_NAF_material.Append(0x00);
+        ks_NAF_material.Append((TUint8)aRand.Length());
+        // P2
+        ks_NAF_material.Append(aIMPI);
+        // L2 - length of impi in two bytes
+        ks_NAF_material.Append(0x00);
+        ks_NAF_material.Append((TUint8)aIMPI.Length());
+        // P2
+        ks_NAF_material.Append(aUTF8_NAF_ID);
+        // L2 - length of FQDN (NAF_ID) in two bytes
+        ks_NAF_material.Append(0x00);
+        ks_NAF_material.Append((TUint8)aUTF8_NAF_ID.Length());
+        GBA_TRACE_DEBUG(("NAF_ID"));
+        GBA_TRACE_DEBUG_DESC(aUTF8_NAF_ID);    
+        GBA_TRACE_DEBUG(("Value of K"));
+        GBA_TRACE_DEBUG_BINARY(aKey);
+        GBA_TRACE_DEBUG(("Value of S"));
+        GBA_TRACE_DEBUG_BINARY(ks_NAF_material);
+        
+        CMessageDigest* digest = CMessageDigestFactory::NewDigestL( CMessageDigest::ESHA256);
+        CleanupStack::PushL( digest );
+        CHMAC* sha256 = CHMAC::NewL(aKey, digest); //sha256 will take the ownership of digest pointer
+        CleanupStack::Pop( digest );
+        CleanupStack::PushL( sha256 );
+        TPtrC8 hash(sha256->Hash(ks_NAF_material));
+        aDerivedKey.Copy(hash);
+        CleanupStack::PopAndDestroy( sha256 ); //sha256
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::QueryKs()
+// -----------------------------------------------------------------------------
+//
+TBool CAkaIsaInterface::QueryKs( TDes8& aKS )
+    {
+    GBA_TRACE_DEBUG(("CAkaIsaInterface::QueryKs"));
+    if( iIKBuf.Length()> 0 && iCKBuf.Length() > 0 )
+        {
+        GBA_TRACE_DEBUG(("got Ks to copy"));
+        aKS.Append(iCKBuf);
+        aKS.Append(iIKBuf);
+        GBA_TRACE_DEBUG(("Copy done!"));
+        return ETrue;
+        }
+    GBA_TRACE_DEBUG(("No Ks to copy, something wrong in Authentication"));
+    return EFalse;
+    }
+    
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::QueryHomeNetworkDnL()
+// -----------------------------------------------------------------------------
+//
+void CAkaIsaInterface::QueryHomeNetworkDnL( TDes8& aHNDN )
+    {
+    RMobilePhone::TMobilePhoneNetworkInfoV1 info;
+    TPckg<RMobilePhone::TMobilePhoneNetworkInfoV1> netInfoPckg(info);
+    TRequestStatus status;
+
+    status =  KRequestPending;
+    iPhone.GetHomeNetwork(status, netInfoPckg);
+    User::WaitForRequest( status );
+    
+    GBA_TRACE_DEBUG_NUM(("phone status = %d"), status.Int() );
+    User::LeaveIfError( status.Int() );
+    
+    // append the bsf.mnc0<MNC>.mcc<MCC>.pub.3gppnetwork.org or bsf.mnc.<MNC>.mcc<MCC>.pub.3gppnetwork.org
+  
+    if ( InterfaceIs2G() )
+        {
+        aHNDN.Copy( KHTTPSTag );  
+        }
+    else
+        {
+        aHNDN.Copy( KHTTPTag ); 
+        } 
+
+    if ( info.iNetworkId.Length() == KNetworkIdLength2 )
+        {
+        //Append KBSFMNC0 to aHNDN
+        aHNDN.Append( KBSFMNC0 );
+        }
+    
+    if ( info.iNetworkId.Length() == KNetworkIdLength3 )
+        {
+		//Append KBSFMNC to aHNDN
+        aHNDN.Append( KBSFMNC ); 
+        }
+       
+    aHNDN.Append( info.iNetworkId );
+    aHNDN.Append( KMCC );        
+    aHNDN.Append( info.iCountryCode );
+    aHNDN.Append( KPUB3GPPORG );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::InterfaceIs2G()
+// -----------------------------------------------------------------------------
+//
+TBool CAkaIsaInterface::InterfaceIs2G() 
+    {
+    GBA_TRACE_DEBUG(("CAkaIsaInterface: Enter the function "));
+    GBA_TRACE_DEBUG_NUM(("CAkaIsaInterface: iCardInterface is %d "), iCardInterface );
+    return iCardInterface == E2GInterface;
+    };
+
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::QueryGBAUAvailability()
+// Get the GBA_U availability from smart card via custom API
+// -----------------------------------------------------------------------------
+void CAkaIsaInterface::QueryGBAUAvailabilityL( TBool& aGBAAvail )
+    {
+    GBA_TRACE_DEBUG(("QueryGBAUAvailability: Enter the function "));
+    GBA_TRACE_DEBUG_NUM(("QueryGBAUAvailability: iCardInterface is %d "), iCardInterface );
+    aGBAAvail = ( iCardInterface == EGBAUInterface );
+    }
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::UpdateGBADataL()
+// Save the B-TID and keylifetime to smart card
+// -----------------------------------------------------------------------------
+
+TInt CAkaIsaInterface::UpdateGBADataL( const TDesC8& aBTID, const TDesC8& aLifetime )
+    {
+    
+    GBA_TRACE_DEBUG(("GBA_U:UpdateGBADataL: Enter the function"));
+    
+    TRequestStatus status;
+    status =  KRequestPending;
+
+    RMmCustomAPI::TSimAuthenticationGbaBootstrapUpdate updatedata;
+
+    updatedata.iBTid.Copy( aBTID );
+    updatedata.iKeyLifeTime.Copy( aLifetime );
+
+    RMmCustomAPI::TGbaBootstrapUpdateDataPckg updatebuf( updatedata );
+        
+    iCustomAPI.GetWlanSimAuthenticationData( status, updatebuf ); 
+     
+    User::WaitForRequest( status );
+    
+    GBA_TRACE_DEBUG_NUM(("GBA_U:UpdateGBADataL: Update GBA is Done, err = %d"), status.Int());
+    
+    return status.Int();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::Release()
+// -----------------------------------------------------------------------------
+void CAkaIsaInterface::Release()
+     {
+     delete this; 
+     }
+
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::NotifyCardChangeL()
+// -----------------------------------------------------------------------------
+void CAkaIsaInterface::NotifyCardChangeL()
+    {
+    // the card is changed, we need to re-initialize the interface 
+	QueryCardInterfaceL();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAkaIsaInterface::QueryCardInterfaceL()
+// ----------------------------------------------------------------------------- 
+//   
+void CAkaIsaInterface::QueryCardInterfaceL()
+    {
+    GBA_TRACE_BEGIN();
+
+    GBA_TRACE_DEBUG(("QueryCardInterfaceL is starting..."));
+
+    TUint32 caps = 0;
+      
+    GBA_TRACE_DEBUG(("Found! Phone open! Checking what kind of ICC access we have...known types : {SIM,RUSIM,USIM}"));    
+    User::LeaveIfError( iPhone.GetIccAccessCaps( caps ) );
+
+    if ( caps & RMobilePhone::KCapsUSimAccessSupported )
+        {
+        GBA_TRACE_DEBUG(("This device  offers USIM access")); 
+             
+        //check if the card support GBA-U interface
+        GBA_TRACE_DEBUG(("Check is GBA-U supported")); 
+        TRequestStatus status;
+        status =  KRequestPending;
+
+        RMmCustomAPI::TAppSupport appSupport;
+    
+        //GBA-U 0, MGV-U 1
+        appSupport.iAppNum = 0; 
+     
+        iCustomAPI.GetUSIMServiceSupport( status, appSupport);
+
+        User::WaitForRequest( status );
+
+        GBA_TRACE_DEBUG_NUM(("QueryCardInterfaceL: GBA_U avail checking is Done, err = %d"), status.Int());
+    
+        if ( status.Int() == KErrNotFound )
+            {
+            //Not gba-u service available
+            GBA_TRACE_DEBUG(("QueryCardInterfaceL: it returns KErrNotFound, No GBA-U "));
+            // set interface as 3g then
+            iCardInterface = E3GInterface;
+            }
+        else if ( status.Int() == KErrNone )
+            {
+            //pass the value back
+            GBA_TRACE_DEBUG(("QueryCardInterfaceL: it returns KErrNone"));
+            if ( appSupport.iSupported )
+                {
+            	GBA_TRACE_DEBUG(("QueryCardInterfaceL: GBA-U support "));
+                iCardInterface = EGBAUInterface;
+                }
+            else
+                {
+                GBA_TRACE_DEBUG(("QueryCardInterfaceL: GBA-U NOT support "));
+                iCardInterface = E3GInterface;	
+                }    
+            }
+        else
+            {
+            //leave , unexpected situation
+            User::LeaveIfError(status.Int());    
+            }    
+        }
+    else if( caps & RMobilePhone::KCapsSimAccessSupported )
+        {
+    	GBA_TRACE_DEBUG(("This device  offers SIM access only"));        
+        iCardInterface = E2GInterface;
+        //The card only support 2G interface
+        }
+    else
+        {
+        //nothing	
+        }
+    }
+
+//EOF