|
1 /* |
|
2 * Copyright (c) 2007 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: Implementation of class CAkaIsaInterface |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 |
|
21 #include <e32math.h> |
|
22 #include <etelmmerr.h> |
|
23 #include <mmtsy_names.h> //TSY and Phone name |
|
24 #include <hash.h> |
|
25 #include <implementationproxy.h> //for ecom |
|
26 #include "GBAAkaIsa.h" |
|
27 #include "GBALogger.h" |
|
28 #include "GbaCommon.h" |
|
29 |
|
30 //Constants |
|
31 const TInt KMaxBufferSize = 256; |
|
32 const TInt KNetworkIdLength2 = 2; |
|
33 const TInt KNetworkIdLength3 = 3; |
|
34 const TInt KIntegerConstant4 = 4; |
|
35 const TInt KIntegerConstant16 = 16; |
|
36 const TInt KIntegerConstant32 = 32; |
|
37 |
|
38 _LIT8( KAT, "@" ); |
|
39 _LIT8( KIMSMNC, "ims.mnc" ); |
|
40 _LIT8( KIMSMNC0, "ims.mnc0" ); |
|
41 _LIT8( KBSFMNC, "bsf.mnc" ); |
|
42 _LIT8( KBSFMNC0, "bsf.mnc0" ); |
|
43 _LIT8( KMCC,".mcc"); |
|
44 _LIT8( KPUB3GPPORG, ".pub.3gppnetwork.org"); |
|
45 _LIT8( K3GPPORG, ".3gppnetwork.org"); |
|
46 _LIT8( K3GPPGBARES, "3gpp-gba-res"); |
|
47 _LIT8( K3GPPGBAKS, "3gpp-gba-ks"); |
|
48 _LIT8( KGBAME, "gba-me"); |
|
49 |
|
50 #ifdef __WINS__ |
|
51 _LIT8( KWINTESTID, "test@pub.3gpp.org"); |
|
52 #endif |
|
53 |
|
54 static MUICCInterface* NewFunctionL(); |
|
55 |
|
56 |
|
57 // ======== LOCAL FUNCTIONS ======== |
|
58 // --------------------------------------------------------------------------- |
|
59 // MUICCInterface* NewFunctionL() |
|
60 // --------------------------------------------------------------------------- |
|
61 // |
|
62 MUICCInterface* NewFunctionL() |
|
63 { |
|
64 GBA_TRACE_DEBUG(("MUICCInterface* NewFunctionL")); |
|
65 MUICCInterface* UICCInterface = NULL; |
|
66 UICCInterface = CAkaIsaInterface::NewL(); |
|
67 return UICCInterface; |
|
68 } |
|
69 |
|
70 |
|
71 // ----------------------------------------------------------------------------- |
|
72 // TImplementationProxy ImplementationTable[] |
|
73 // ----------------------------------------------------------------------------- |
|
74 // |
|
75 const TImplementationProxy ImplementationTable[] = |
|
76 { |
|
77 IMPLEMENTATION_PROXY_ENTRY(GBA_UICC_INTERFACE_IMPLE, NewFunctionL) |
|
78 }; |
|
79 |
|
80 |
|
81 // ----------------------------------------------------------------------------- |
|
82 // TImplementationProxy* ImplementationGroupProxy() |
|
83 // This function is needed by ECom and is the only one exported function |
|
84 // ----------------------------------------------------------------------------- |
|
85 // |
|
86 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) |
|
87 { |
|
88 aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); |
|
89 return (ImplementationTable); |
|
90 } |
|
91 |
|
92 |
|
93 // ================= MEMBER FUNCTIONS ======================= |
|
94 |
|
95 // ----------------------------------------------------------------------------- |
|
96 // CAkaIsaInterface::CAkaIsaInterface() |
|
97 // ----------------------------------------------------------------------------- |
|
98 // |
|
99 CAkaIsaInterface::CAkaIsaInterface():iCardInterface( ENoInterface ) |
|
100 { |
|
101 } |
|
102 |
|
103 |
|
104 // ----------------------------------------------------------------------------- |
|
105 // CAkaIsaInterface::NewL() |
|
106 // ----------------------------------------------------------------------------- |
|
107 // |
|
108 MUICCInterface* CAkaIsaInterface::NewL() |
|
109 { |
|
110 GBA_TRACE_DEBUG(("Constructing: CAkaIsaInterface")); |
|
111 CAkaIsaInterface* self = new(ELeave) CAkaIsaInterface(); |
|
112 CleanupStack::PushL(self); |
|
113 self->ConstructL(); |
|
114 CleanupStack::Pop(self); |
|
115 GBA_TRACE_DEBUG(("Construction complete: CAkaIsaInterface")); |
|
116 return self; |
|
117 } |
|
118 |
|
119 |
|
120 // ----------------------------------------------------------------------------- |
|
121 // CAkaIsaInterface::NewL() |
|
122 // ----------------------------------------------------------------------------- |
|
123 // |
|
124 void CAkaIsaInterface::ConstructL() |
|
125 { |
|
126 GBA_TRACE_BEGIN(); |
|
127 //Connect to ETel server |
|
128 User::LeaveIfError( iEtelServer.Connect() ); |
|
129 //Load phone module |
|
130 User::LeaveIfError( iEtelServer.LoadPhoneModule( KMmTsyModuleName ) ); |
|
131 //open phone |
|
132 User::LeaveIfError( iPhone.Open( iEtelServer, KMmTsyPhoneName ) ); |
|
133 //open custom api |
|
134 User::LeaveIfError( iCustomAPI.Open(iPhone) ); |
|
135 // check card interface, initialize iCardInterface |
|
136 QueryCardInterfaceL(); |
|
137 GBA_TRACE_END(); |
|
138 } |
|
139 |
|
140 |
|
141 // ----------------------------------------------------------------------------- |
|
142 // CAkaIsaInterface::~CAkaIsaInterface() |
|
143 // ----------------------------------------------------------------------------- |
|
144 // |
|
145 CAkaIsaInterface::~CAkaIsaInterface() |
|
146 { |
|
147 GBA_TRACE_BEGIN(); |
|
148 //Close all created resources |
|
149 iCustomAPI.Close(); |
|
150 iPhone.Close(); |
|
151 iEtelServer.Close(); |
|
152 GBA_TRACE_END(); |
|
153 } |
|
154 |
|
155 |
|
156 void CAkaIsaInterface::QueryIdentityL( TDes8& aIdentity ) |
|
157 { |
|
158 #ifdef __WINS__ |
|
159 aIdentity.Copy(KWINTESTID); |
|
160 return; |
|
161 #endif |
|
162 |
|
163 GBA_TRACE_BEGIN(); |
|
164 GBA_TRACE_DEBUG(("QueryIdentity is starting...")); |
|
165 |
|
166 TUint32 caps = 0; |
|
167 GBA_TRACE_DEBUG(("Phone is open now doing the actual query...")); |
|
168 |
|
169 // Get capability |
|
170 User::LeaveIfError( iPhone.GetIdentityCaps( caps ) ); |
|
171 |
|
172 if ( caps & (RMobilePhone::KCapsGetSubscriberId)) |
|
173 { |
|
174 RMobilePhone::TMobilePhoneSubscriberId id; |
|
175 |
|
176 TRequestStatus status; |
|
177 |
|
178 status = KRequestPending; |
|
179 RMobilePhone::TMobilePhoneSubscriberId iccID; |
|
180 iPhone.GetSubscriberId( status, iccID ); |
|
181 User::WaitForRequest( status ); |
|
182 |
|
183 GBA_TRACE_DEBUG_NUM(("Can't get IMSI, error = %d"), status.Int() ); |
|
184 User::LeaveIfError( status.Int() ); |
|
185 |
|
186 GBA_TRACE_DEBUG(("id=")); |
|
187 GBA_TRACE_DEBUG_DESC(iccID); |
|
188 |
|
189 aIdentity.Zero(); |
|
190 aIdentity.Copy(iccID); |
|
191 |
|
192 // derive the ending part |
|
193 // get the mobile network name MNC and country code MCC |
|
194 |
|
195 //Make IMPI |
|
196 RMobilePhone::TMobilePhoneNetworkInfoV1 info; |
|
197 TPckg<RMobilePhone::TMobilePhoneNetworkInfoV1> netInfoPckg(info); |
|
198 status = KRequestPending; |
|
199 iPhone.GetHomeNetwork(status, netInfoPckg); |
|
200 |
|
201 User::WaitForRequest( status ); |
|
202 GBA_TRACE_DEBUG_NUM(("Can't get network name, error = %d"), status.Int() ); |
|
203 User::LeaveIfError( status.Int() ); |
|
204 |
|
205 // append the "<IMSI>@ims.mnc<MNC>.mcc<MCC>.3gppnetwork.org" |
|
206 |
|
207 aIdentity.Append( KAT ); |
|
208 |
|
209 if ( info.iNetworkId.Length() == KNetworkIdLength2 ) |
|
210 { |
|
211 //add one more zero if only 2 digits |
|
212 aIdentity.Append( KIMSMNC0 ); |
|
213 } |
|
214 |
|
215 if ( info.iNetworkId.Length() == KNetworkIdLength3 ) |
|
216 { |
|
217 aIdentity.Append( KIMSMNC ); |
|
218 } |
|
219 |
|
220 aIdentity.Append( info.iNetworkId ); |
|
221 |
|
222 aIdentity.Append( KMCC ); |
|
223 aIdentity.Append( info.iCountryCode ); |
|
224 aIdentity.Append( K3GPPORG ); |
|
225 |
|
226 |
|
227 GBA_TRACE_DEBUG(("aIdentity=")); |
|
228 GBA_TRACE_DEBUG_DESC(aIdentity); |
|
229 } |
|
230 else |
|
231 { |
|
232 aIdentity.Copy(_L8("")); |
|
233 } |
|
234 |
|
235 GBA_TRACE_END(); |
|
236 } |
|
237 |
|
238 // ----------------------------------------------------------------------------- |
|
239 // CAkaIsaInterface::QueryAuthenticationGBAUL |
|
240 // If the GBA_U available, pass RAND and AUTN to smart card via custom API |
|
241 // otherwise use RMobilePhone instead |
|
242 // ----------------------------------------------------------------------------- |
|
243 TBool CAkaIsaInterface::QueryAuthenticationGBAUL( const TDesC8& aNonce, |
|
244 TDes8& aResponse, |
|
245 TDes8& aResync ) |
|
246 { |
|
247 GBA_TRACE_BEGIN(); |
|
248 TBool keys_available = ETrue; |
|
249 //creat buffer to carry the input and output value |
|
250 RMmCustomAPI::TSimAuthenticationGbaBootstrap gbadata; |
|
251 |
|
252 RMmCustomAPI::TGbaBootstrapDataPckg gbabuf( gbadata ); |
|
253 |
|
254 //Copy input data, RAND and AUTN |
|
255 gbadata.iRandomParameters.Copy(aNonce.Ptr(),KAKA_RAND_LENGTH); |
|
256 gbadata.iAUTN.Copy(aNonce.Ptr()+KAKA_RAND_LENGTH,KAKA_RAND_LENGTH); |
|
257 |
|
258 //call the API to get the RES |
|
259 TRequestStatus status; |
|
260 |
|
261 status = KRequestPending; |
|
262 |
|
263 GBA_TRACE_DEBUG(("Send Authentication request to card")); |
|
264 iCustomAPI.GetWlanSimAuthenticationData( status, gbabuf ); |
|
265 GBA_TRACE_DEBUG(("Wait for result...")); |
|
266 User::WaitForRequest( status ); |
|
267 |
|
268 GBA_TRACE_DEBUG_NUM(("Authentication is Done, err = %d"),status.Int() ); |
|
269 |
|
270 if(status == KErrNone) |
|
271 { |
|
272 aResponse.Copy(gbadata.iRES); |
|
273 GBA_TRACE_DEBUG_BINARY(gbadata.iRES); |
|
274 } |
|
275 else |
|
276 { |
|
277 keys_available = EFalse; |
|
278 |
|
279 if (status != KErrMMEtelSqnVerificationFailed ) |
|
280 { |
|
281 User::LeaveIfError( status.Int() ); |
|
282 } |
|
283 } |
|
284 |
|
285 if ( status == KErrMMEtelSqnVerificationFailed ) |
|
286 { |
|
287 GBA_TRACE_DEBUG_NUM(("AUTS len is Done !!!, len = %d"), gbadata.iAUTS.Length() ); |
|
288 GBA_TRACE_DEBUG_BINARY(gbadata.iAUTS); |
|
289 |
|
290 if(gbadata.iAUTS.Length() == 0) |
|
291 { |
|
292 GBA_TRACE_DEBUG(("Auts is Still zero !!!!!")); |
|
293 } |
|
294 else |
|
295 { |
|
296 GBA_TRACE_DEBUG((" before copy")); |
|
297 aResync.Copy(gbadata.iAUTS); |
|
298 GBA_TRACE_DEBUG(("after copy auts")); |
|
299 } |
|
300 } |
|
301 GBA_TRACE_DEBUG((" Done!")); |
|
302 GBA_TRACE_END(); |
|
303 return keys_available; |
|
304 } |
|
305 |
|
306 |
|
307 // ----------------------------------------------------------------------------- |
|
308 // CAkaIsaInterface::QueryAuthentication2GL |
|
309 // If the GBA_U available, pass RAND and AUTN to smart card via custom API |
|
310 // otherwise use RMobilePhone instead |
|
311 // run simulated aka |
|
312 // ----------------------------------------------------------------------------- |
|
313 |
|
314 void CAkaIsaInterface::QueryAuthentication2GL( const TDesC8& aNonce, TDes8& aResponse ) |
|
315 { |
|
316 GBA_TRACE_BEGIN(); |
|
317 RMmCustomAPI::TSimAuthenticationEapSim authSIMdata; |
|
318 RMmCustomAPI::TSimDataPckg authSIMBuf(authSIMdata); |
|
319 |
|
320 TRequestStatus status; |
|
321 status = KRequestPending; |
|
322 |
|
323 authSIMdata.iRandomParameters.Copy(aNonce.Ptr(),KAKA_RAND_LENGTH); |
|
324 GBA_TRACE_DEBUG(("SIM authentication")); |
|
325 iCustomAPI.GetWlanSimAuthenticationData(status,authSIMBuf); |
|
326 |
|
327 User::WaitForRequest( status ); |
|
328 GBA_TRACE_DEBUG_NUM(("GetWlanSimAuthenticationData return, status = %d"), status.Int() ); |
|
329 User::LeaveIfError( status.Int() ); |
|
330 |
|
331 GBA_TRACE_DEBUG(("Creating 2G authentication vector KDF(key,\"3gpp-gba-res\",sres)")); |
|
332 GBA_TRACE_DEBUG_BINARY(authSIMdata.iSRES); |
|
333 GBA_TRACE_DEBUG_BINARY(authSIMdata.iKC); |
|
334 |
|
335 TBuf8<KMaxBufferSize> lastSRESKC; |
|
336 TBuf8<2*RMmCustomAPI::KMaxKCLength+KAKA_RAND_LENGTH> kc2; |
|
337 |
|
338 // COPYING Kc twice |
|
339 GBA_TRACE_DEBUG(("Copying iKC")); |
|
340 for( TInt i=0; i<(RMmCustomAPI::KMaxKCLength) ; i++ ) |
|
341 { |
|
342 kc2.Append( (TUint8)(authSIMdata.iKC[i]) ); |
|
343 } |
|
344 GBA_TRACE_DEBUG(("Copying iKC")); |
|
345 for( TInt i=0;i<(RMmCustomAPI::KMaxKCLength);i++ ) |
|
346 { |
|
347 kc2.Append( (TUint8)(authSIMdata.iKC[i]) ); |
|
348 } |
|
349 GBA_TRACE_DEBUG(("appending RAND")); |
|
350 kc2.Append(aNonce.Ptr(),KAKA_RAND_LENGTH); |
|
351 |
|
352 GBA_TRACE_DEBUG(("K part")); |
|
353 GBA_TRACE_DEBUG_BINARY(kc2); |
|
354 |
|
355 // appending RAND |
|
356 lastSRESKC.Append( 0x01); |
|
357 lastSRESKC.Append(K3GPPGBARES); |
|
358 lastSRESKC.Append( 0x00); |
|
359 lastSRESKC.Append( 0x0C); |
|
360 GBA_TRACE_DEBUG(("Copying SRES")); |
|
361 |
|
362 for( TInt i=0; i<KIntegerConstant4; i++ ) |
|
363 { |
|
364 lastSRESKC.Append( (TUint8)(authSIMdata.iSRES[i]) ); |
|
365 } |
|
366 lastSRESKC.Append( 0x00); |
|
367 lastSRESKC.Append( 0x04); |
|
368 GBA_TRACE_DEBUG(("S part")); |
|
369 GBA_TRACE_DEBUG_BINARY(lastSRESKC); |
|
370 |
|
371 // derive response |
|
372 CMessageDigest* digest = CMessageDigestFactory::NewDigestL( CMessageDigest::ESHA256); |
|
373 CleanupStack::PushL( digest ); |
|
374 CHMAC* sha256 = CHMAC::NewL(kc2, digest); |
|
375 CleanupStack::Pop( digest ); |
|
376 CleanupStack::PushL( sha256 ); |
|
377 TPtrC8 hash(sha256->Hash(lastSRESKC)); |
|
378 GBA_TRACE_DEBUG(("resulting hash: ")); |
|
379 GBA_TRACE_DEBUG_BINARY(hash); |
|
380 |
|
381 aResponse.Append(hash.Ptr(),KRESPONSE_2G_LENGTH); |
|
382 |
|
383 // KEY MATERIAL NEEDS TO BE STORED |
|
384 // CHECK 3GPP TS 3.3220 V7.5.0 (2006-09) page 54 item 7 |
|
385 // The BSF shall generate key material Ks by computing Ks = KDF (key, Ks-input, "3gpp-gba-ks", SRES). |
|
386 // The B-TID value shall be also generated in format of NAI by taking the base64 encoded [12] RAND value |
|
387 // from step 3, and the BSF server name, i.e. base64encoded(RAND)@BSF_servers_domain_name. |
|
388 GBA_TRACE_DEBUG(("DERIVING THE MASTER KEY Ks")); |
|
389 |
|
390 TBuf8<KMaxBufferSize> hashMaterial; |
|
391 hashMaterial.Append(0x01); |
|
392 hashMaterial.Append(aNonce.Mid(KIntegerConstant32,KIntegerConstant16)); |
|
393 hashMaterial.Append(0x00); |
|
394 hashMaterial.Append(0x10); |
|
395 hashMaterial.Append(K3GPPGBAKS); |
|
396 hashMaterial.Append(0x00); |
|
397 hashMaterial.Append(0x0b); |
|
398 hashMaterial.Append(authSIMdata.iSRES.Left(RMmCustomAPI::KMaxRESLength)); |
|
399 hashMaterial.Append(0x00); |
|
400 hashMaterial.Append(0x04); |
|
401 |
|
402 GBA_TRACE_DEBUG(("key for creating the key")); |
|
403 GBA_TRACE_DEBUG_BINARY(kc2); |
|
404 |
|
405 GBA_TRACE_DEBUG(("hashing material for creating the key")); |
|
406 GBA_TRACE_DEBUG_BINARY(hashMaterial); |
|
407 |
|
408 TPtrC8 keymaterial( sha256->Hash( hashMaterial) ); |
|
409 |
|
410 GBA_TRACE_DEBUG(("Master key Ks, !!! Remove from LOG")); |
|
411 GBA_TRACE_DEBUG_BINARY(keymaterial); |
|
412 |
|
413 iCKBuf.Copy(keymaterial.Left(KIntegerConstant16)); |
|
414 iIKBuf.Copy(keymaterial.Mid(KIntegerConstant16,KIntegerConstant16)); |
|
415 |
|
416 CleanupStack::PopAndDestroy( sha256 ); |
|
417 |
|
418 GBA_TRACE_DEBUG(("Done!")); |
|
419 GBA_TRACE_END(); |
|
420 } |
|
421 |
|
422 // ----------------------------------------------------------------------------- |
|
423 // CAkaIsaInterface::QueryAuthentication3GL |
|
424 // If the GBA_U available, pass RAND and AUTN to smart card via custom API |
|
425 // otherwise use RMobilePhone instead |
|
426 // run aka |
|
427 // ----------------------------------------------------------------------------- |
|
428 TBool CAkaIsaInterface::QueryAuthentication3GL( const TDesC8& aNonce, |
|
429 TDes8& aResponse, |
|
430 TDes8& aResync ) |
|
431 { |
|
432 GBA_TRACE_BEGIN(); |
|
433 TBool keys_available = ETrue; |
|
434 |
|
435 RMmCustomAPI::TSimAuthenticationEapAka authAkadata; |
|
436 RMmCustomAPI::TAkaDataPckg authAkaBuf(authAkadata); |
|
437 TRequestStatus status; |
|
438 status = KRequestPending; |
|
439 authAkadata.iRandomParameters.Copy(aNonce.Ptr(),KAKA_RAND_LENGTH); |
|
440 authAkadata.iAUTN.Copy(aNonce.Ptr()+KAKA_RAND_LENGTH,KAKA_RAND_LENGTH); |
|
441 GBA_TRACE_DEBUG(("AKA authentication")); |
|
442 |
|
443 iCustomAPI.GetWlanSimAuthenticationData(status,authAkaBuf); |
|
444 User::WaitForRequest( status ); |
|
445 |
|
446 GBA_TRACE_DEBUG_NUM(("GBA_ME:QueryAuthentication3GL: Authentication error = %d"),status.Int() ); |
|
447 |
|
448 if( status.Int() == KErrNone ) |
|
449 { |
|
450 GBA_TRACE_DEBUG(("AKA, appending result")); |
|
451 aResponse.Copy(authAkadata.iRES); |
|
452 GBA_TRACE_DEBUG_BINARY(authAkadata.iRES); |
|
453 |
|
454 GBA_TRACE_DEBUG(("storing keys")); |
|
455 |
|
456 // store results |
|
457 iCKBuf.Copy(authAkadata.iCK); |
|
458 iIKBuf.Copy(authAkadata.iIK); |
|
459 } |
|
460 else |
|
461 { |
|
462 keys_available = EFalse; |
|
463 |
|
464 if (status != KErrMMEtelSqnVerificationFailed ) |
|
465 { |
|
466 User::LeaveIfError( status.Int() ); |
|
467 } |
|
468 } |
|
469 |
|
470 if ( status == KErrMMEtelSqnVerificationFailed ) |
|
471 { |
|
472 GBA_TRACE_DEBUG_NUM(("GBA_ME:QueryAuthentication3GL: AUTS len is Done !!!, len = %d"), authAkadata.iAUTS.Length() ); |
|
473 GBA_TRACE_DEBUG_BINARY( authAkadata.iAUTS ); |
|
474 |
|
475 if(authAkadata.iAUTS.Length() == 0) |
|
476 { |
|
477 GBA_TRACE_DEBUG(("GBA_U:QueryAuthentication3GL: Auts is Still zero !!!!!")); |
|
478 } |
|
479 else |
|
480 { |
|
481 GBA_TRACE_DEBUG(("QueryAuthentication3GL before copy")); |
|
482 aResync.Copy(authAkadata.iAUTS); |
|
483 GBA_TRACE_DEBUG(("QueryAuthentication3GL after copy auts")); |
|
484 } |
|
485 } |
|
486 GBA_TRACE_END(); |
|
487 return keys_available; |
|
488 } |
|
489 |
|
490 |
|
491 // ----------------------------------------------------------------------------- |
|
492 // CAkaIsaInterface::QueryAuthenticationL |
|
493 // If the GBA_U available, pass RAND and AUTN to smart card via custom API |
|
494 // otherwise use RMobilePhone instead |
|
495 // ----------------------------------------------------------------------------- |
|
496 TBool CAkaIsaInterface::QueryAuthenticationL( |
|
497 const TDesC8& aNonce, |
|
498 TDes8& aResponse, |
|
499 TDes8& aResync ) |
|
500 { |
|
501 GBA_TRACE_BEGIN(); |
|
502 GBA_TRACE_DEBUG(("aka nonce=")); |
|
503 GBA_TRACE_DEBUG_BINARY(aNonce); |
|
504 // GBA_U not availiable |
|
505 if ( iCardInterface != EGBAUInterface ) |
|
506 { |
|
507 GBA_TRACE_DEBUG(("QueryAuthenticationL is starting...")); |
|
508 |
|
509 //run aka |
|
510 if ( iCardInterface == E3GInterface ) |
|
511 { |
|
512 return QueryAuthentication3GL( aNonce, aResponse, aResync ); |
|
513 } |
|
514 |
|
515 // run simulated aka |
|
516 if ( iCardInterface == E2GInterface ) |
|
517 { |
|
518 QueryAuthentication2GL( aNonce, aResponse ); |
|
519 return ETrue; |
|
520 } |
|
521 return EFalse; |
|
522 } |
|
523 else |
|
524 { |
|
525 GBA_TRACE_DEBUG(("GBA_U authentication")); |
|
526 return QueryAuthenticationGBAUL( aNonce, aResponse, aResync ); |
|
527 } |
|
528 } |
|
529 |
|
530 |
|
531 // ----------------------------------------------------------------------------- |
|
532 // CAkaIsaInterface::QueryKeyMaterialL() |
|
533 // If GBA_U, send the request to smart card. |
|
534 // ----------------------------------------------------------------------------- |
|
535 // |
|
536 void CAkaIsaInterface::QueryKeyMaterialL(const TDesC8& aKey, const TDesC8& aRand, const TDesC8& aIMPI, const TDesC8& aUTF8_NAF_ID, TDes8& aDerivedKey ) |
|
537 { |
|
538 if ( iCardInterface == EGBAUInterface ) |
|
539 { |
|
540 GBA_TRACE_DEBUG_BINARY(aUTF8_NAF_ID); |
|
541 |
|
542 GBA_TRACE_DEBUG(("GBA_U:QueryKeyMaterialL: Enter the function")); |
|
543 |
|
544 TRequestStatus status; |
|
545 status = KRequestPending; |
|
546 |
|
547 RMmCustomAPI::TSimAuthenticationGbaNafDerivation nafdata; |
|
548 |
|
549 RMmCustomAPI::TGbaNafDerivationDataPckg nafbuf( nafdata ); |
|
550 |
|
551 nafdata.iNafId.Copy( aUTF8_NAF_ID ); |
|
552 |
|
553 |
|
554 GBA_TRACE_DEBUG(("GBA_U:QueryKeyMaterialL: copy nafid, no truncate")); |
|
555 GBA_TRACE_DEBUG_BINARY(aUTF8_NAF_ID); |
|
556 |
|
557 nafdata.iImpi.Copy( aIMPI ); |
|
558 |
|
559 GBA_TRACE_DEBUG(("GBA_U:QueryKeyMaterialL: copy impi, no truncate")); |
|
560 iCustomAPI.GetWlanSimAuthenticationData( status, nafbuf ); |
|
561 |
|
562 User::WaitForRequest( status ); |
|
563 |
|
564 GBA_TRACE_DEBUG_NUM(("GBA_U:QueryKeyMaterialL: QueryKeyMaterial is Done, err = %d"), status.Int()); |
|
565 |
|
566 User::LeaveIfError( status.Int() ); |
|
567 |
|
568 aDerivedKey.Copy( nafdata.iKsExtNaf ); //return the ks_ext_naf |
|
569 } |
|
570 else //GBA_ME |
|
571 { |
|
572 GBA_TRACE_DEBUG(("QueryKeyMaterial")); |
|
573 GBA_TRACE_DEBUG(("derive key as specified in 33.22 V7.5.0 page 35")); |
|
574 // derive key as specified in 33.22 V7.5.0 page 35 |
|
575 // S = FC || P0 || L0 || P1 || L1 || P2 || L2 || P3 || L3 ||... || Pn || Ln |
|
576 // derived key = HMAC-SHA-256 ( Key , S ) |
|
577 // - FC = 0x01, |
|
578 // - P1 = RAND, |
|
579 // - L1 = length of RAND is 16 octets (i.e. 0x00 0x10), |
|
580 // - P2 = IMPI encoded to an octet string using UTF-8 encoding (see clause B.2.1), |
|
581 // - L2 = length of IMPI is variable (not greater that 65535), |
|
582 // - 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 |
|
583 // - L3 = length of NAF_ID is variable (not greater that 65535). |
|
584 // In the key derivation of Ks_NAF as specified in clause 4 and Ks_ext_NAF as specified in clause 5, |
|
585 // - P0 = "gba-me" (i.e. 0x67 0x62 0x61 0x2d 0x6d 0x65), and |
|
586 // - L0 = length of P0 is 6 octets (i.e., 0x00 0x06). |
|
587 // In the key derivation of Ks_int_NAF as specified in clause 5, |
|
588 // - P0 = "gba-u" (i.e. 0x67 0x62 0x61 0x2d 0x75), and |
|
589 // - L0 = length of P0 is 5 octets (i.e., 0x00 0x05). |
|
590 TBuf8<KMaxBufferSize> ks_NAF_material; |
|
591 // FC |
|
592 ks_NAF_material.Append(0x01); |
|
593 // P0 |
|
594 ks_NAF_material.Append(KGBAME); |
|
595 // L0 |
|
596 ks_NAF_material.Append(0x00); |
|
597 ks_NAF_material.Append(0x06); |
|
598 // P1 |
|
599 ks_NAF_material.Append(aRand); |
|
600 // L1 - length of rand in two bytes |
|
601 ks_NAF_material.Append(0x00); |
|
602 ks_NAF_material.Append((TUint8)aRand.Length()); |
|
603 // P2 |
|
604 ks_NAF_material.Append(aIMPI); |
|
605 // L2 - length of impi in two bytes |
|
606 ks_NAF_material.Append(0x00); |
|
607 ks_NAF_material.Append((TUint8)aIMPI.Length()); |
|
608 // P2 |
|
609 ks_NAF_material.Append(aUTF8_NAF_ID); |
|
610 // L2 - length of FQDN (NAF_ID) in two bytes |
|
611 ks_NAF_material.Append(0x00); |
|
612 ks_NAF_material.Append((TUint8)aUTF8_NAF_ID.Length()); |
|
613 GBA_TRACE_DEBUG(("NAF_ID")); |
|
614 GBA_TRACE_DEBUG_DESC(aUTF8_NAF_ID); |
|
615 GBA_TRACE_DEBUG(("Value of K")); |
|
616 GBA_TRACE_DEBUG_BINARY(aKey); |
|
617 GBA_TRACE_DEBUG(("Value of S")); |
|
618 GBA_TRACE_DEBUG_BINARY(ks_NAF_material); |
|
619 |
|
620 CMessageDigest* digest = CMessageDigestFactory::NewDigestL( CMessageDigest::ESHA256); |
|
621 CleanupStack::PushL( digest ); |
|
622 CHMAC* sha256 = CHMAC::NewL(aKey, digest); //sha256 will take the ownership of digest pointer |
|
623 CleanupStack::Pop( digest ); |
|
624 CleanupStack::PushL( sha256 ); |
|
625 TPtrC8 hash(sha256->Hash(ks_NAF_material)); |
|
626 aDerivedKey.Copy(hash); |
|
627 CleanupStack::PopAndDestroy( sha256 ); //sha256 |
|
628 } |
|
629 } |
|
630 |
|
631 |
|
632 // ----------------------------------------------------------------------------- |
|
633 // CAkaIsaInterface::QueryKs() |
|
634 // ----------------------------------------------------------------------------- |
|
635 // |
|
636 TBool CAkaIsaInterface::QueryKs( TDes8& aKS ) |
|
637 { |
|
638 GBA_TRACE_DEBUG(("CAkaIsaInterface::QueryKs")); |
|
639 if( iIKBuf.Length()> 0 && iCKBuf.Length() > 0 ) |
|
640 { |
|
641 GBA_TRACE_DEBUG(("got Ks to copy")); |
|
642 aKS.Append(iCKBuf); |
|
643 aKS.Append(iIKBuf); |
|
644 GBA_TRACE_DEBUG(("Copy done!")); |
|
645 return ETrue; |
|
646 } |
|
647 GBA_TRACE_DEBUG(("No Ks to copy, something wrong in Authentication")); |
|
648 return EFalse; |
|
649 } |
|
650 |
|
651 |
|
652 // ----------------------------------------------------------------------------- |
|
653 // CAkaIsaInterface::QueryHomeNetworkDnL() |
|
654 // ----------------------------------------------------------------------------- |
|
655 // |
|
656 void CAkaIsaInterface::QueryHomeNetworkDnL( TDes8& aHNDN ) |
|
657 { |
|
658 RMobilePhone::TMobilePhoneNetworkInfoV1 info; |
|
659 TPckg<RMobilePhone::TMobilePhoneNetworkInfoV1> netInfoPckg(info); |
|
660 TRequestStatus status; |
|
661 |
|
662 status = KRequestPending; |
|
663 iPhone.GetHomeNetwork(status, netInfoPckg); |
|
664 User::WaitForRequest( status ); |
|
665 |
|
666 GBA_TRACE_DEBUG_NUM(("phone status = %d"), status.Int() ); |
|
667 User::LeaveIfError( status.Int() ); |
|
668 |
|
669 // append the bsf.mnc0<MNC>.mcc<MCC>.pub.3gppnetwork.org or bsf.mnc.<MNC>.mcc<MCC>.pub.3gppnetwork.org |
|
670 |
|
671 if ( InterfaceIs2G() ) |
|
672 { |
|
673 aHNDN.Copy( KHTTPSTag ); |
|
674 } |
|
675 else |
|
676 { |
|
677 aHNDN.Copy( KHTTPTag ); |
|
678 } |
|
679 |
|
680 if ( info.iNetworkId.Length() == KNetworkIdLength2 ) |
|
681 { |
|
682 //Append KBSFMNC0 to aHNDN |
|
683 aHNDN.Append( KBSFMNC0 ); |
|
684 } |
|
685 |
|
686 if ( info.iNetworkId.Length() == KNetworkIdLength3 ) |
|
687 { |
|
688 //Append KBSFMNC to aHNDN |
|
689 aHNDN.Append( KBSFMNC ); |
|
690 } |
|
691 |
|
692 aHNDN.Append( info.iNetworkId ); |
|
693 aHNDN.Append( KMCC ); |
|
694 aHNDN.Append( info.iCountryCode ); |
|
695 aHNDN.Append( KPUB3GPPORG ); |
|
696 } |
|
697 |
|
698 |
|
699 // ----------------------------------------------------------------------------- |
|
700 // CAkaIsaInterface::InterfaceIs2G() |
|
701 // ----------------------------------------------------------------------------- |
|
702 // |
|
703 TBool CAkaIsaInterface::InterfaceIs2G() |
|
704 { |
|
705 GBA_TRACE_DEBUG(("CAkaIsaInterface: Enter the function ")); |
|
706 GBA_TRACE_DEBUG_NUM(("CAkaIsaInterface: iCardInterface is %d "), iCardInterface ); |
|
707 return iCardInterface == E2GInterface; |
|
708 }; |
|
709 |
|
710 |
|
711 // ----------------------------------------------------------------------------- |
|
712 // CAkaIsaInterface::QueryGBAUAvailability() |
|
713 // Get the GBA_U availability from smart card via custom API |
|
714 // ----------------------------------------------------------------------------- |
|
715 void CAkaIsaInterface::QueryGBAUAvailabilityL( TBool& aGBAAvail ) |
|
716 { |
|
717 GBA_TRACE_DEBUG(("QueryGBAUAvailability: Enter the function ")); |
|
718 GBA_TRACE_DEBUG_NUM(("QueryGBAUAvailability: iCardInterface is %d "), iCardInterface ); |
|
719 aGBAAvail = ( iCardInterface == EGBAUInterface ); |
|
720 } |
|
721 |
|
722 // ----------------------------------------------------------------------------- |
|
723 // CAkaIsaInterface::UpdateGBADataL() |
|
724 // Save the B-TID and keylifetime to smart card |
|
725 // ----------------------------------------------------------------------------- |
|
726 |
|
727 TInt CAkaIsaInterface::UpdateGBADataL( const TDesC8& aBTID, const TDesC8& aLifetime ) |
|
728 { |
|
729 |
|
730 GBA_TRACE_DEBUG(("GBA_U:UpdateGBADataL: Enter the function")); |
|
731 |
|
732 TRequestStatus status; |
|
733 status = KRequestPending; |
|
734 |
|
735 RMmCustomAPI::TSimAuthenticationGbaBootstrapUpdate updatedata; |
|
736 |
|
737 updatedata.iBTid.Copy( aBTID ); |
|
738 updatedata.iKeyLifeTime.Copy( aLifetime ); |
|
739 |
|
740 RMmCustomAPI::TGbaBootstrapUpdateDataPckg updatebuf( updatedata ); |
|
741 |
|
742 iCustomAPI.GetWlanSimAuthenticationData( status, updatebuf ); |
|
743 |
|
744 User::WaitForRequest( status ); |
|
745 |
|
746 GBA_TRACE_DEBUG_NUM(("GBA_U:UpdateGBADataL: Update GBA is Done, err = %d"), status.Int()); |
|
747 |
|
748 return status.Int(); |
|
749 } |
|
750 |
|
751 |
|
752 // ----------------------------------------------------------------------------- |
|
753 // CAkaIsaInterface::Release() |
|
754 // ----------------------------------------------------------------------------- |
|
755 void CAkaIsaInterface::Release() |
|
756 { |
|
757 delete this; |
|
758 } |
|
759 |
|
760 |
|
761 // ----------------------------------------------------------------------------- |
|
762 // CAkaIsaInterface::NotifyCardChangeL() |
|
763 // ----------------------------------------------------------------------------- |
|
764 void CAkaIsaInterface::NotifyCardChangeL() |
|
765 { |
|
766 // the card is changed, we need to re-initialize the interface |
|
767 QueryCardInterfaceL(); |
|
768 } |
|
769 |
|
770 |
|
771 // ----------------------------------------------------------------------------- |
|
772 // CAkaIsaInterface::QueryCardInterfaceL() |
|
773 // ----------------------------------------------------------------------------- |
|
774 // |
|
775 void CAkaIsaInterface::QueryCardInterfaceL() |
|
776 { |
|
777 GBA_TRACE_BEGIN(); |
|
778 |
|
779 GBA_TRACE_DEBUG(("QueryCardInterfaceL is starting...")); |
|
780 |
|
781 TUint32 caps = 0; |
|
782 |
|
783 GBA_TRACE_DEBUG(("Found! Phone open! Checking what kind of ICC access we have...known types : {SIM,RUSIM,USIM}")); |
|
784 User::LeaveIfError( iPhone.GetIccAccessCaps( caps ) ); |
|
785 |
|
786 if ( caps & RMobilePhone::KCapsUSimAccessSupported ) |
|
787 { |
|
788 GBA_TRACE_DEBUG(("This device offers USIM access")); |
|
789 |
|
790 //check if the card support GBA-U interface |
|
791 GBA_TRACE_DEBUG(("Check is GBA-U supported")); |
|
792 TRequestStatus status; |
|
793 status = KRequestPending; |
|
794 |
|
795 RMmCustomAPI::TAppSupport appSupport; |
|
796 |
|
797 //GBA-U 0, MGV-U 1 |
|
798 appSupport.iAppNum = 0; |
|
799 |
|
800 iCustomAPI.GetUSIMServiceSupport( status, appSupport); |
|
801 |
|
802 User::WaitForRequest( status ); |
|
803 |
|
804 GBA_TRACE_DEBUG_NUM(("QueryCardInterfaceL: GBA_U avail checking is Done, err = %d"), status.Int()); |
|
805 |
|
806 if ( status.Int() == KErrNotFound ) |
|
807 { |
|
808 //Not gba-u service available |
|
809 GBA_TRACE_DEBUG(("QueryCardInterfaceL: it returns KErrNotFound, No GBA-U ")); |
|
810 // set interface as 3g then |
|
811 iCardInterface = E3GInterface; |
|
812 } |
|
813 else if ( status.Int() == KErrNone ) |
|
814 { |
|
815 //pass the value back |
|
816 GBA_TRACE_DEBUG(("QueryCardInterfaceL: it returns KErrNone")); |
|
817 if ( appSupport.iSupported ) |
|
818 { |
|
819 GBA_TRACE_DEBUG(("QueryCardInterfaceL: GBA-U support ")); |
|
820 iCardInterface = EGBAUInterface; |
|
821 } |
|
822 else |
|
823 { |
|
824 GBA_TRACE_DEBUG(("QueryCardInterfaceL: GBA-U NOT support ")); |
|
825 iCardInterface = E3GInterface; |
|
826 } |
|
827 } |
|
828 else |
|
829 { |
|
830 //leave , unexpected situation |
|
831 User::LeaveIfError(status.Int()); |
|
832 } |
|
833 } |
|
834 else if( caps & RMobilePhone::KCapsSimAccessSupported ) |
|
835 { |
|
836 GBA_TRACE_DEBUG(("This device offers SIM access only")); |
|
837 iCardInterface = E2GInterface; |
|
838 //The card only support 2G interface |
|
839 } |
|
840 else |
|
841 { |
|
842 //nothing |
|
843 } |
|
844 } |
|
845 |
|
846 //EOF |