os/security/cryptoplugins/cryptospiplugins/test/h4drv/crypto_h4/cryptoldd.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of the License "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
/**
sl@0
    20
 @file
sl@0
    21
 @internalComponent
sl@0
    22
 @released
sl@0
    23
*/
sl@0
    24
#include <kernel/kern_priv.h>
sl@0
    25
#include "cryptodriver.h"
sl@0
    26
#include "cryptoldd.h"
sl@0
    27
#include "keyhandle.h"
sl@0
    28
#include "kmskext.h"
sl@0
    29
sl@0
    30
DECLARE_STANDARD_LDD()
sl@0
    31
    {
sl@0
    32
    return new DCryptoLddChannelFactory;
sl@0
    33
    }
sl@0
    34
sl@0
    35
//#define HW_PERF_CHECK
sl@0
    36
sl@0
    37
_LIT(KCryptoPanicCategory,"DCrypto");
sl@0
    38
sl@0
    39
/**
sl@0
    40
  Constructor
sl@0
    41
*/
sl@0
    42
DCryptoLddChannelFactory::DCryptoLddChannelFactory()
sl@0
    43
	{
sl@0
    44
	TRACE_FUNCTION("DCryptoLddChannelFactory");
sl@0
    45
	// Set version number for this device
sl@0
    46
    iVersion=RCryptoDriver::VersionRequired();
sl@0
    47
	// Auto load a PDD
sl@0
    48
    iParseMask=KDeviceAllowPhysicalDevice;
sl@0
    49
	}
sl@0
    50
sl@0
    51
/**
sl@0
    52
  Destructor
sl@0
    53
*/
sl@0
    54
DCryptoLddChannelFactory::~DCryptoLddChannelFactory()
sl@0
    55
	{
sl@0
    56
	TRACE_FUNCTION("~DCryptoLddChannelFactory");
sl@0
    57
	TraceFunction::DumpCounts();
sl@0
    58
	}
sl@0
    59
sl@0
    60
sl@0
    61
/**
sl@0
    62
  Second stage constructor for DCryptoLddChannelFactory.
sl@0
    63
  This must at least set a name for the driver object.
sl@0
    64
sl@0
    65
  @return KErrNone if successful, otherwise one of the other system wide error codes.
sl@0
    66
*/
sl@0
    67
TInt DCryptoLddChannelFactory::Install()
sl@0
    68
	{
sl@0
    69
	TRACE_FUNCTION("Install");
sl@0
    70
    return SetName(&RCryptoDriver::Name());
sl@0
    71
	}
sl@0
    72
sl@0
    73
/**
sl@0
    74
  Return the drivers capabilities.
sl@0
    75
  Called in the response to an RDevice::GetCaps() request.
sl@0
    76
sl@0
    77
  @param aDes Descriptor into which capabilities information is to be written.
sl@0
    78
*/
sl@0
    79
void DCryptoLddChannelFactory::GetCaps(TDes8& aDes) const
sl@0
    80
	{
sl@0
    81
	TRACE_FUNCTION("GetCaps");
sl@0
    82
    // Create a capabilities object
sl@0
    83
    RCryptoDriver::TCaps caps;
sl@0
    84
	caps.iVersion = iVersion;
sl@0
    85
sl@0
    86
	// We do not have a handle to the PDD, and it might not have been
sl@0
    87
	// loaded yet, so we can't ask it for its capabilities...
sl@0
    88
sl@0
    89
    // Write it back to user memory
sl@0
    90
    Kern::InfoCopy(aDes,(TUint8*)&caps,sizeof(caps));
sl@0
    91
 	return;
sl@0
    92
	}
sl@0
    93
sl@0
    94
/**
sl@0
    95
  Called by the kernel's device driver framework to create a Logical Channel.
sl@0
    96
  This is called in the context of the user thread (client) which requested the creation
sl@0
    97
  of the Logical Channel (e.g. through a call to RBusLogicalChannel::DoCreate).
sl@0
    98
  The thread is in a critical section.
sl@0
    99
sl@0
   100
  @param aChannel Set to point to the created Logical Channel
sl@0
   101
sl@0
   102
  @return KErrNone if successful, otherwise one of the other system wide error codes.
sl@0
   103
*/
sl@0
   104
TInt DCryptoLddChannelFactory::Create(DLogicalChannelBase*& aChannel)
sl@0
   105
	{
sl@0
   106
	TRACE_FUNCTION("Create");
sl@0
   107
    aChannel=new DCryptoLddChannel;
sl@0
   108
    if(!aChannel)
sl@0
   109
        return KErrNoMemory;
sl@0
   110
sl@0
   111
    return KErrNone;
sl@0
   112
	}
sl@0
   113
sl@0
   114
sl@0
   115
//
sl@0
   116
// Logical Channel
sl@0
   117
//
sl@0
   118
sl@0
   119
/**
sl@0
   120
  Constructor
sl@0
   121
*/
sl@0
   122
DCryptoLddChannel::DCryptoLddChannel()
sl@0
   123
    : iLddChanRandom(*this),
sl@0
   124
	  iLddChanAes(*this)
sl@0
   125
	{
sl@0
   126
	TRACE_FUNCTION("DCryptoLddChannel");
sl@0
   127
    // Get pointer to client thread's DThread object
sl@0
   128
    iClient=&Kern::CurrentThread();
sl@0
   129
sl@0
   130
    // Open a reference on client thread so its control block can't disappear until
sl@0
   131
    // this driver has finished with it.
sl@0
   132
    // Note, this call to Open() can't fail since it is the thread we are currently running in.
sl@0
   133
    iClient->Open();
sl@0
   134
    }
sl@0
   135
sl@0
   136
sl@0
   137
/**
sl@0
   138
  Destructor
sl@0
   139
*/
sl@0
   140
DCryptoLddChannel::~DCryptoLddChannel()
sl@0
   141
    {
sl@0
   142
	TRACE_FUNCTION("~DCryptoLddChannel");
sl@0
   143
    // Cancel all processing that we may be doing
sl@0
   144
    DoCancel(RCryptoDriver::EAllRequests);
sl@0
   145
    // Close our reference on the client thread
sl@0
   146
    Kern::SafeClose((DObject*&)iClient,NULL);
sl@0
   147
    }
sl@0
   148
sl@0
   149
sl@0
   150
/**
sl@0
   151
  Second stage constructor called by the kernel's device driver framework.
sl@0
   152
  This is called in the context of the user thread (client) which requested the creation
sl@0
   153
  of the Logical Channel (e.g. through a call to RBusLogicalChannel::DoCreate())
sl@0
   154
  The thread is in a critical section.
sl@0
   155
sl@0
   156
  @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate()
sl@0
   157
  @param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate()
sl@0
   158
  @param aVer The version argument supplied by the client to RBusLogicalChannel::DoCreate()
sl@0
   159
sl@0
   160
  @return KErrNone if successful, otherwise one of the other system wide error codes.
sl@0
   161
*/
sl@0
   162
TInt DCryptoLddChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer)
sl@0
   163
    {
sl@0
   164
	TRACE_FUNCTION("DoCreate");
sl@0
   165
    // Check Platform Security capabilities of client thread (if required).
sl@0
   166
    //
sl@0
   167
    // Here we handle the simple case where:
sl@0
   168
    // 1. The device driver can only have one client thread
sl@0
   169
    // 2. The security policy is the binary all-or-nothing policy.
sl@0
   170
    // E.g. "If you have the right capability you can do anything with the driver
sl@0
   171
    // and if you don't have the capability you can't do anything"
sl@0
   172
    // 
sl@0
   173
    // If only some functionality of the driver is restricted, then the security check should
sl@0
   174
    // go elsewhere. E.g. in DoRequest/DoControl. In that case Kern::CurrentThreadHasCapability
sl@0
   175
    // shouldn't be used because the 'current thread' isn't the client.
sl@0
   176
    //
sl@0
   177
    // In this example we do a check here for ECapability_None (which always passes)...
sl@0
   178
    if(!Kern::CurrentThreadHasCapability(ECapability_None,__PLATSEC_DIAGNOSTIC_STRING("Checked by DRIVER1")))
sl@0
   179
        return KErrPermissionDenied;
sl@0
   180
     
sl@0
   181
    // Check version
sl@0
   182
    if (!Kern::QueryVersionSupported(RCryptoDriver::VersionRequired(),aVer))
sl@0
   183
        return KErrNotSupported;
sl@0
   184
sl@0
   185
     // Give PDD a pointer to this channel
sl@0
   186
    PddChan()->iCryptoLddChannel = this;
sl@0
   187
sl@0
   188
    // Setup LDD for receiving client messages.
sl@0
   189
    SetDfcQ(PddChan()->DfcQue());
sl@0
   190
    iMsgQ.Receive();
sl@0
   191
sl@0
   192
    // Done
sl@0
   193
    return KErrNone;
sl@0
   194
    }
sl@0
   195
sl@0
   196
sl@0
   197
/**
sl@0
   198
  Called when a user thread requests a handle to this channel.
sl@0
   199
*/
sl@0
   200
TInt DCryptoLddChannel::RequestUserHandle(DThread* aThread, TOwnerType aType)
sl@0
   201
    {
sl@0
   202
	TRACE_FUNCTION("RequestUserHandle");
sl@0
   203
    // Make sure that only our client can get a handle
sl@0
   204
    if (aType!=EOwnerThread || aThread!=iClient)
sl@0
   205
        return KErrAccessDenied;
sl@0
   206
    return KErrNone;
sl@0
   207
    }
sl@0
   208
sl@0
   209
sl@0
   210
/**
sl@0
   211
  Process a message for this logical channel.
sl@0
   212
  This function is called in the context of a DFC thread.
sl@0
   213
sl@0
   214
  @param aMessage The message to process.
sl@0
   215
     The iValue member of this distinguishes the message type:
sl@0
   216
     iValue==ECloseMsg, channel close message
sl@0
   217
     iValue==KMaxTInt, a 'DoCancel' message
sl@0
   218
     iValue>=0, a 'DoControl' message with function number equal to iValue
sl@0
   219
     iValue<0, a 'DoRequest' message with function number equal to ~iValue
sl@0
   220
*/
sl@0
   221
void DCryptoLddChannel::HandleMsg(TMessageBase* aMsg)
sl@0
   222
    {
sl@0
   223
	TRACE_FUNCTION("HandleMsg");
sl@0
   224
    TThreadMessage& m=*(TThreadMessage*)aMsg;
sl@0
   225
sl@0
   226
    // Get message type
sl@0
   227
    TInt id=m.iValue;
sl@0
   228
sl@0
   229
    // Decode the message type and dispatch it to the relevent handler function...
sl@0
   230
    
sl@0
   231
    if (id==(TInt)ECloseMsg)
sl@0
   232
        {
sl@0
   233
        // Channel Close
sl@0
   234
        DoCancel(RCryptoDriver::EAllRequests);
sl@0
   235
        m.Complete(KErrNone, EFalse);
sl@0
   236
        return;
sl@0
   237
        }
sl@0
   238
sl@0
   239
    if (id==KMaxTInt)
sl@0
   240
        {
sl@0
   241
        // DoCancel
sl@0
   242
        DoCancel(m.Int0());
sl@0
   243
        m.Complete(KErrNone,ETrue);
sl@0
   244
        return;
sl@0
   245
        }
sl@0
   246
sl@0
   247
    if (id<0)
sl@0
   248
        {
sl@0
   249
        // DoRequest
sl@0
   250
        TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
sl@0
   251
        TInt r=DoRequest(~id,pS,m.Ptr1(),m.Ptr2());
sl@0
   252
        if (r!=KErrNone)
sl@0
   253
            Kern::RequestComplete(iClient,pS,r);
sl@0
   254
        m.Complete(KErrNone,ETrue);
sl@0
   255
        }
sl@0
   256
    else
sl@0
   257
        {
sl@0
   258
        // DoControl
sl@0
   259
        TInt r=DoControl(id,m.Ptr0(),m.Ptr1());
sl@0
   260
        m.Complete(r,ETrue);
sl@0
   261
        }
sl@0
   262
    }
sl@0
   263
sl@0
   264
/**
sl@0
   265
  Process synchronous 'control' requests
sl@0
   266
*/
sl@0
   267
TInt DCryptoLddChannel::DoControl(TInt aFunction, TAny* a1, TAny *)
sl@0
   268
    {
sl@0
   269
	TRACE_FUNCTION("DoControl");
sl@0
   270
    TInt r;
sl@0
   271
sl@0
   272
    switch (aFunction)
sl@0
   273
        {
sl@0
   274
        case RCryptoDriver::EGetHwVersions:
sl@0
   275
            r = GetHwVersions((TDes8*)a1);
sl@0
   276
            break;
sl@0
   277
sl@0
   278
        case RCryptoDriver::EGetConfig:
sl@0
   279
            r = GetConfig((TDes8*)a1);
sl@0
   280
            break;
sl@0
   281
sl@0
   282
        case RCryptoDriver::ESetConfig:
sl@0
   283
            r = SetConfig((const TDesC8*)a1);
sl@0
   284
            break;
sl@0
   285
sl@0
   286
        case RCryptoDriver::EAesSetConfig:
sl@0
   287
            r = iLddChanAes.SetAesConfig((const TDesC8*)a1);
sl@0
   288
            break;
sl@0
   289
sl@0
   290
        default:
sl@0
   291
            r=KErrNotSupported;
sl@0
   292
            break;
sl@0
   293
        }
sl@0
   294
sl@0
   295
    return r;
sl@0
   296
    }
sl@0
   297
sl@0
   298
sl@0
   299
/**
sl@0
   300
  Process asynchronous requests
sl@0
   301
*/
sl@0
   302
TInt DCryptoLddChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
sl@0
   303
    {
sl@0
   304
	TRACE_FUNCTION("DoRequest");
sl@0
   305
    (void)a2; // a2 not used in this example
sl@0
   306
sl@0
   307
    TInt r;
sl@0
   308
sl@0
   309
    switch(aReqNo)
sl@0
   310
        {
sl@0
   311
        case RCryptoDriver::ERandom:
sl@0
   312
			r=iLddChanRandom.Random(aStatus,(TDes8*)a1);
sl@0
   313
            break;
sl@0
   314
sl@0
   315
        case RCryptoDriver::EAesWrite:
sl@0
   316
			r=iLddChanAes.AesWrite(aStatus,(TDesC8*)a1);
sl@0
   317
            break;
sl@0
   318
sl@0
   319
        case RCryptoDriver::EAesRead:
sl@0
   320
			r=iLddChanAes.AesRead(aStatus,(TDes8*)a1, (TUint32)a2);
sl@0
   321
            break;
sl@0
   322
sl@0
   323
        default:
sl@0
   324
            r=KErrNotSupported;
sl@0
   325
            break;
sl@0
   326
        }
sl@0
   327
sl@0
   328
    return r;
sl@0
   329
    }
sl@0
   330
sl@0
   331
sl@0
   332
/**
sl@0
   333
  Process cancelling of asynchronous requests
sl@0
   334
*/
sl@0
   335
void DCryptoLddChannel::DoCancel(TUint aMask)
sl@0
   336
    {
sl@0
   337
	TRACE_FUNCTION("DoCancel");
sl@0
   338
    if(aMask&(1<<RCryptoDriver::ERandom))
sl@0
   339
		{
sl@0
   340
		iLddChanRandom.RandomCancel();
sl@0
   341
		}
sl@0
   342
	
sl@0
   343
    if(aMask&(1<<RCryptoDriver::EAesRead))
sl@0
   344
		{
sl@0
   345
        iLddChanAes.CancelRead();
sl@0
   346
		}
sl@0
   347
sl@0
   348
    if(aMask&(1<<RCryptoDriver::EAesWrite))
sl@0
   349
		{
sl@0
   350
        iLddChanAes.CancelWrite();
sl@0
   351
		}
sl@0
   352
	
sl@0
   353
    }
sl@0
   354
sl@0
   355
sl@0
   356
/**
sl@0
   357
  Process a GetHwVersions control message. This writes the crypto h/w versions to a
sl@0
   358
  RCryptoDriver::THwVersionsBuf supplied by the client.
sl@0
   359
*/
sl@0
   360
TInt DCryptoLddChannel::GetHwVersions(TDes8* aHwVersionsBuf) const
sl@0
   361
    {
sl@0
   362
	TRACE_FUNCTION("GetHwVersions");
sl@0
   363
    // Create a structure giving the current configuration
sl@0
   364
    RCryptoDriver::THwVersions versions;
sl@0
   365
	
sl@0
   366
	PddChan()->GetHwVersions(versions);
sl@0
   367
sl@0
   368
    // Write the config to the client
sl@0
   369
    TPtrC8 ptr((const TUint8*)&versions,sizeof(versions));
sl@0
   370
    return Kern::ThreadDesWrite(iClient,aHwVersionsBuf,ptr,0,KTruncateToMaxLength,NULL);
sl@0
   371
    }
sl@0
   372
sl@0
   373
//
sl@0
   374
// Functions for processing configuration control messages
sl@0
   375
//
sl@0
   376
sl@0
   377
/**
sl@0
   378
  Process a GetConfig control message. This writes the current driver configuration to a
sl@0
   379
  RCryptoDriver::TConfigBuf supplied by the client.
sl@0
   380
*/
sl@0
   381
TInt DCryptoLddChannel::GetConfig(TDes8* aConfigBuf) const
sl@0
   382
    {
sl@0
   383
	TRACE_FUNCTION("GetConfig");
sl@0
   384
    // Create a structure giving the current configuration
sl@0
   385
    RCryptoDriver::TConfig config;
sl@0
   386
    CurrentConfig(config);
sl@0
   387
sl@0
   388
    // Write the config to the client
sl@0
   389
    TPtrC8 ptr((const TUint8*)&config,sizeof(config));
sl@0
   390
    return Kern::ThreadDesWrite(iClient,aConfigBuf,ptr,0,KTruncateToMaxLength,NULL);
sl@0
   391
    }
sl@0
   392
sl@0
   393
/**
sl@0
   394
  Process a SetConfig control message. This sets the driver configuration using a
sl@0
   395
  RCryptoDriver::TConfigBuf supplied by the client.
sl@0
   396
*/
sl@0
   397
TInt DCryptoLddChannel::SetConfig(const TDesC8* aConfigBuf)
sl@0
   398
    {
sl@0
   399
	TRACE_FUNCTION("SetConfig");
sl@0
   400
    // Don't allow configuration changes whilst we're busy
sl@0
   401
	//    if(iSendDataStatus || iReceiveDataStatus)
sl@0
   402
	//        return KErrInUse;
sl@0
   403
sl@0
   404
    // Create a config structure.
sl@0
   405
    RCryptoDriver::TConfig config;
sl@0
   406
    CurrentConfig(config);
sl@0
   407
sl@0
   408
    // Note: We have filled config with the current settings, this is to allow
sl@0
   409
    // backwards compatibility when a client gives us an old (and shorter) version
sl@0
   410
    // of the config structure.
sl@0
   411
sl@0
   412
    // Read the config structure from client
sl@0
   413
    TPtr8 ptr((TUint8*)&config,sizeof(config));
sl@0
   414
    TInt r=Kern::ThreadDesRead(iClient,aConfigBuf,ptr,0);
sl@0
   415
    if(r!=KErrNone)
sl@0
   416
        return r;
sl@0
   417
sl@0
   418
    // Use config data to setup the driver. Checking that parameters which aren't settable
sl@0
   419
    // either contain the correct values or are zero (meaning 'default')
sl@0
   420
	r=PddChan()->SetFakeDriverSetting(config.iFakeDriverSetting);
sl@0
   421
    if(r!=KErrNone)
sl@0
   422
        return r;
sl@0
   423
sl@0
   424
    return r;
sl@0
   425
    }
sl@0
   426
sl@0
   427
sl@0
   428
/**
sl@0
   429
  Fill a TConfig with the driver's current configuration.
sl@0
   430
*/
sl@0
   431
void DCryptoLddChannel::CurrentConfig(RCryptoDriver::TConfig& aConfig) const
sl@0
   432
    {
sl@0
   433
	TRACE_FUNCTION("TConfig");
sl@0
   434
    aConfig.iFakeDriverSetting = PddChan()->FakeDriverSetting();
sl@0
   435
    }
sl@0
   436
sl@0
   437
sl@0
   438
sl@0
   439
//
sl@0
   440
// Functions for processing 'Random'
sl@0
   441
//
sl@0
   442
sl@0
   443
DLddChanRandom::DLddChanRandom(DCryptoLddChannel &aParent)
sl@0
   444
	: iParent(aParent)
sl@0
   445
	{
sl@0
   446
	TRACE_FUNCTION("DLddChanRandom");
sl@0
   447
	}
sl@0
   448
sl@0
   449
sl@0
   450
/**
sl@0
   451
  Start processing a Random request.
sl@0
   452
*/
sl@0
   453
TInt DLddChanRandom::Random(TRequestStatus* aStatus,TDes8* aPtr)
sl@0
   454
    {
sl@0
   455
	TRACE_FUNCTION("Random");
sl@0
   456
    // Check that a 'Random' isn't already in progress
sl@0
   457
    if(iRandomStatus)
sl@0
   458
        {
sl@0
   459
        Kern::ThreadKill(iParent.iClient,EExitPanic,ERequestAlreadyPending,KCryptoPanicCategory);
sl@0
   460
        return KErrInUse;
sl@0
   461
        }
sl@0
   462
sl@0
   463
	// We only support a single outstanding Random request in this LDD
sl@0
   464
	// channel, but the PDD supports multiple requests.
sl@0
   465
sl@0
   466
    // Save the client request status and descriptor
sl@0
   467
    iRandomStatus = aStatus;
sl@0
   468
    iRandomDescriptor = aPtr;
sl@0
   469
sl@0
   470
	// Retrieve user request length (ie. CURRENT length of user descriptor) into iRequestLength
sl@0
   471
	TInt tmp;
sl@0
   472
	TUint8 *tmp2;
sl@0
   473
	TInt r=Kern::ThreadGetDesInfo(iParent.iClient, iRandomDescriptor, iRequestLength, tmp, tmp2, ETrue);
sl@0
   474
	if(r != KErrNone)
sl@0
   475
		{
sl@0
   476
		return r;
sl@0
   477
 		}
sl@0
   478
sl@0
   479
	// Set current offset into user descriptor
sl@0
   480
	iCurrentIndex = 0;
sl@0
   481
sl@0
   482
	iJob = iParent.PddChan()->GetJobRandom();
sl@0
   483
sl@0
   484
	// Setup PDD job
sl@0
   485
	iJob->SetDetails(&iParent.LddFactory()->iJSRandom, this, iRequestLength);
sl@0
   486
	// Register it, which will also (maybe later) call DoSlice to run it
sl@0
   487
	iParent.LddFactory()->iJSRandom.ScheduleJob(iJob);
sl@0
   488
		
sl@0
   489
	return KErrNone;
sl@0
   490
    }
sl@0
   491
sl@0
   492
sl@0
   493
sl@0
   494
TInt DLddChanRandom::DataRequired()
sl@0
   495
	{
sl@0
   496
	TRACE_FUNCTION("DataRequired");
sl@0
   497
	return KErrNone; // We never pass data to the h/w...
sl@0
   498
	}
sl@0
   499
sl@0
   500
TInt DLddChanRandom::DataAvailable()
sl@0
   501
	{
sl@0
   502
	TRACE_FUNCTION("DataAvailable");
sl@0
   503
	//	Kern::Printf("DLddChanRandom::DataAvailable()");
sl@0
   504
	TInt r = KErrNone;
sl@0
   505
	
sl@0
   506
	TUint8 *buf;
sl@0
   507
	TUint32 bufLen;
sl@0
   508
	TBool check = ETrue;
sl@0
   509
	while(check)
sl@0
   510
		{
sl@0
   511
		iJob->GetFromPddBuffer(buf, bufLen, check);
sl@0
   512
		if(bufLen)
sl@0
   513
			{
sl@0
   514
			TInt required = iRequestLength - iCurrentIndex;
sl@0
   515
			TInt toTransfer = bufLen;
sl@0
   516
			if(toTransfer > required)
sl@0
   517
				{
sl@0
   518
				toTransfer = required;
sl@0
   519
				}
sl@0
   520
			// Copy the current buffer to user land
sl@0
   521
			TPtr8 des(buf, toTransfer, toTransfer);
sl@0
   522
			r=Kern::ThreadDesWrite(iParent.iClient, iRandomDescriptor, des, iCurrentIndex);
sl@0
   523
			if(r != KErrNone)
sl@0
   524
				{
sl@0
   525
				break;
sl@0
   526
				}
sl@0
   527
			
sl@0
   528
			// Update our index into the user descriptor
sl@0
   529
			iCurrentIndex += toTransfer;
sl@0
   530
sl@0
   531
			// Update h/w with number of bytes actually read
sl@0
   532
			iJob->BytesReadFromPdd(toTransfer);
sl@0
   533
sl@0
   534
			if(toTransfer != bufLen)
sl@0
   535
				{
sl@0
   536
				// We did not read all the available data, so do not
sl@0
   537
				// re-query h/w
sl@0
   538
				check = EFalse;
sl@0
   539
				}
sl@0
   540
			}
sl@0
   541
		};
sl@0
   542
sl@0
   543
	return r;
sl@0
   544
	}
sl@0
   545
sl@0
   546
void DLddChanRandom::JobComplete(TInt aResult)
sl@0
   547
	{
sl@0
   548
	TRACE_FUNCTION("JobComplete");
sl@0
   549
	if(iRandomStatus)
sl@0
   550
		{
sl@0
   551
		// Finished with client descriptor, so NULL it to help detect coding errors
sl@0
   552
		iRandomDescriptor = NULL;
sl@0
   553
		// Complete client's request
sl@0
   554
		Kern::RequestComplete(iParent.iClient,iRandomStatus, aResult);
sl@0
   555
		}
sl@0
   556
	}
sl@0
   557
sl@0
   558
sl@0
   559
/**
sl@0
   560
  Cancel a Random request.
sl@0
   561
*/
sl@0
   562
void DLddChanRandom::RandomCancel()
sl@0
   563
    {
sl@0
   564
	TRACE_FUNCTION("RandomCancel");
sl@0
   565
    if(iRandomStatus)
sl@0
   566
        {
sl@0
   567
        // Tell PDD to stop processing the request
sl@0
   568
        iParent.LddFactory()->iJSRandom.DeScheduleJob(iParent.PddChan()->GetJobRandom());
sl@0
   569
        // Finished with client descriptor, so NULL it to help detect coding errors
sl@0
   570
        iRandomDescriptor = NULL;
sl@0
   571
        // Complete clients request
sl@0
   572
        Kern::RequestComplete(iParent.iClient,iRandomStatus,KErrCancel);
sl@0
   573
        }
sl@0
   574
    }
sl@0
   575
sl@0
   576
//
sl@0
   577
// Functions for processing 'Aes'
sl@0
   578
//
sl@0
   579
sl@0
   580
DLddChanAes::DLddChanAes(DCryptoLddChannel &aParent)
sl@0
   581
	: iParent(aParent)
sl@0
   582
	{
sl@0
   583
	TRACE_FUNCTION("DLddChanAes");
sl@0
   584
	}
sl@0
   585
sl@0
   586
sl@0
   587
TInt DLddChanAes::SetAesConfig(const TDesC8* aConfigBuf)
sl@0
   588
	{
sl@0
   589
	TRACE_FUNCTION("SetAesConfig");
sl@0
   590
	// Note we need to validate arguments kernel side otherwise
sl@0
   591
	// someone could easily crash the kernel...
sl@0
   592
sl@0
   593
	RCryptoDriver::TAesConfig config;
sl@0
   594
    // Read the config structure from client
sl@0
   595
    TPtr8 ptr((TUint8*)&config,sizeof(config));
sl@0
   596
    TInt r=Kern::ThreadDesRead(iParent.iClient,aConfigBuf,ptr,0);
sl@0
   597
    if(r!=KErrNone)
sl@0
   598
		{
sl@0
   599
		return r;
sl@0
   600
		}
sl@0
   601
sl@0
   602
	//	Kern::Printf("iEncrypt = 0x%x",config.iEncrypt);
sl@0
   603
	//	Kern::Printf("iMode = 0x%x",config.iMode);
sl@0
   604
	//	Kern::Printf("iKey = 0x%x",config.iKey);
sl@0
   605
	//	Kern::Printf("iIV = 0x%x",config.iIV);
sl@0
   606
sl@0
   607
sl@0
   608
	// Remember direction
sl@0
   609
	iEncrypt = config.iEncrypt;
sl@0
   610
sl@0
   611
	// Remember mode
sl@0
   612
	iMode = config.iMode;
sl@0
   613
sl@0
   614
	//
sl@0
   615
	// Handle key
sl@0
   616
	//
sl@0
   617
sl@0
   618
	// Retrieve user key length into iKeyLengthBytes
sl@0
   619
	TInt tmp;
sl@0
   620
	TUint8 *tmp2;
sl@0
   621
	r=Kern::ThreadGetDesInfo(iParent.iClient, (TAny *)config.iKey, iKeyLengthBytes, tmp, tmp2, EFalse);
sl@0
   622
    if(r!=KErrNone)
sl@0
   623
		{
sl@0
   624
		return r;
sl@0
   625
		}
sl@0
   626
sl@0
   627
	HBuf8 *embeddedKeyData = 0;
sl@0
   628
	if(iKeyLengthBytes == 4)
sl@0
   629
		{
sl@0
   630
		// Some form of embedded key so value is a 32 bit handle
sl@0
   631
		TPckgBuf<TKeyHandle> keyHandlePkg;	
sl@0
   632
		
sl@0
   633
		r=Kern::ThreadDesRead(iParent.iClient, (TAny *)config.iKey, keyHandlePkg, 0);
sl@0
   634
		if(r != KErrNone)
sl@0
   635
			{
sl@0
   636
			return r;
sl@0
   637
			}
sl@0
   638
sl@0
   639
		TKeyHandle &keyHandle = keyHandlePkg();
sl@0
   640
sl@0
   641
		r = HwKeyStore::ExtractKey(iParent.iClient->iOwningProcess, keyHandle, 0 /*operation*/, embeddedKeyData);
sl@0
   642
		if(r != KErrNone)
sl@0
   643
			{
sl@0
   644
			return r;
sl@0
   645
			}
sl@0
   646
sl@0
   647
		// Update key length
sl@0
   648
		iKeyLengthBytes = embeddedKeyData->Length();
sl@0
   649
		}
sl@0
   650
sl@0
   651
	switch(iKeyLengthBytes)
sl@0
   652
		{
sl@0
   653
		case 16: // 128 bits
sl@0
   654
			break;
sl@0
   655
		case 24: // 192 bits
sl@0
   656
			break;
sl@0
   657
		case 32: // 256 bits
sl@0
   658
			break;
sl@0
   659
		default: // Illegal length
sl@0
   660
			if(embeddedKeyData) delete embeddedKeyData;
sl@0
   661
			return KErrArgument;
sl@0
   662
		}
sl@0
   663
sl@0
   664
	// Make sure iJob is valid before we use it
sl@0
   665
	iJob = iParent.PddChan()->GetJobAes();
sl@0
   666
sl@0
   667
	TUint8 *keyBuffer = iJob->GetKeyBuffer();
sl@0
   668
	TPtr8 des(keyBuffer, iKeyLengthBytes);
sl@0
   669
sl@0
   670
	if(embeddedKeyData)
sl@0
   671
		{
sl@0
   672
		// Copy embedded key to PDD
sl@0
   673
		des = *embeddedKeyData;
sl@0
   674
		delete embeddedKeyData;
sl@0
   675
		embeddedKeyData = 0;
sl@0
   676
		}
sl@0
   677
	else
sl@0
   678
		{
sl@0
   679
		// Retrieve key from user
sl@0
   680
		r=Kern::ThreadDesRead(iParent.iClient, (TAny *)config.iKey, des, 0);
sl@0
   681
		if(r != KErrNone)
sl@0
   682
			{
sl@0
   683
			return r;
sl@0
   684
			}
sl@0
   685
		}
sl@0
   686
	
sl@0
   687
		
sl@0
   688
	//
sl@0
   689
	// Handle IV
sl@0
   690
	//
sl@0
   691
sl@0
   692
	// Retrieve IV length
sl@0
   693
	TInt ivLength;
sl@0
   694
	r=Kern::ThreadGetDesInfo(iParent.iClient, (TAny *)config.iIV, ivLength, tmp, tmp2, EFalse);
sl@0
   695
	//	Kern::Printf("DLddChanAes::SetAesConfig r=%d 5",r);
sl@0
   696
	if(r != KErrNone)
sl@0
   697
		{
sl@0
   698
		return r;
sl@0
   699
		}
sl@0
   700
	
sl@0
   701
	if((ivLength != 0) && (ivLength != 16))
sl@0
   702
		{
sl@0
   703
		return KErrArgument;
sl@0
   704
		}
sl@0
   705
sl@0
   706
	if(ivLength == 16)
sl@0
   707
		{
sl@0
   708
		TUint8 *ivBuffer = iJob->GetIVBuffer();
sl@0
   709
		TPtr8 des(ivBuffer, 16);
sl@0
   710
		r=Kern::ThreadDesRead(iParent.iClient, (TAny *)config.iIV, des, 0);
sl@0
   711
		if(r != KErrNone)
sl@0
   712
			{
sl@0
   713
			return r;
sl@0
   714
			}
sl@0
   715
		}
sl@0
   716
sl@0
   717
sl@0
   718
	// Set details
sl@0
   719
	r = iJob->SetDetails(&iParent.LddFactory()->iJSAes, this, iEncrypt, iKeyLengthBytes, iMode);
sl@0
   720
	if(r != KErrNone)
sl@0
   721
		{
sl@0
   722
		return r;
sl@0
   723
		}
sl@0
   724
	
sl@0
   725
	return KErrNone;
sl@0
   726
	}
sl@0
   727
sl@0
   728
/**
sl@0
   729
  Start processing a Aes request.
sl@0
   730
*/
sl@0
   731
TInt DLddChanAes::AesWrite(TRequestStatus* aStatus, TDesC8* aPtr)
sl@0
   732
    {
sl@0
   733
	TRACE_FUNCTION("AesWrite");
sl@0
   734
	//	Kern::Printf("DLddChanAes::AesWrite");
sl@0
   735
    // Check that an Aes Write isn't already in progress
sl@0
   736
    if(iAesWriteStatus)
sl@0
   737
        {
sl@0
   738
        Kern::ThreadKill(iParent.iClient,EExitPanic,ERequestAlreadyPending,KCryptoPanicCategory);
sl@0
   739
        return KErrInUse;
sl@0
   740
        }
sl@0
   741
sl@0
   742
	// We only support a single outstanding Aes Write request in this LDD
sl@0
   743
	// channel, but the PDD supports multiple requests.
sl@0
   744
sl@0
   745
    // Save the client request status and descriptor
sl@0
   746
    iAesWriteStatus = aStatus;
sl@0
   747
    iAesWriteDescriptor = aPtr;
sl@0
   748
sl@0
   749
sl@0
   750
	// Retrieve user request length (ie. current length of user descriptor) into iRequestLength
sl@0
   751
	TInt maxLen;
sl@0
   752
	TUint8 *aesWriteDescriptorBufferRaw;
sl@0
   753
	TInt r=Kern::ThreadGetDesInfo(iParent.iClient, iAesWriteDescriptor, iWriteRequestLength, maxLen, aesWriteDescriptorBufferRaw, EFalse);
sl@0
   754
	if(r != KErrNone)
sl@0
   755
		{
sl@0
   756
		iAesWriteStatus = 0;
sl@0
   757
		return r;
sl@0
   758
 		}
sl@0
   759
sl@0
   760
	// Set current offset into user descriptor
sl@0
   761
	iCurrentUserWriteIndex = 0;
sl@0
   762
sl@0
   763
	// Make sure iJob is valid before we use it
sl@0
   764
	iJob = iParent.PddChan()->GetJobAes();
sl@0
   765
sl@0
   766
sl@0
   767
#ifdef HW_PERF_CHECK
sl@0
   768
	iJob->HwPerfCheck();
sl@0
   769
#else
sl@0
   770
	// Feed some data to the PDD
sl@0
   771
	r = DataRequired(); // Fake PDD callback to get data from us.
sl@0
   772
	if(r != KErrNone)
sl@0
   773
		{
sl@0
   774
		iAesWriteStatus = 0;
sl@0
   775
		return r;
sl@0
   776
 		}
sl@0
   777
sl@0
   778
	// Make sure job is not stalled, and maybe (re)add to job list.
sl@0
   779
	iJob->Resume();
sl@0
   780
#endif
sl@0
   781
	
sl@0
   782
	return KErrNone;
sl@0
   783
    }
sl@0
   784
sl@0
   785
sl@0
   786
TInt DLddChanAes::AesRead(TRequestStatus* aStatus, TDes8* aPtr, TUint32 aLength)
sl@0
   787
    {
sl@0
   788
	TRACE_FUNCTION("AesRead");
sl@0
   789
	//	Kern::Printf("DLddChanAes::AesRead");
sl@0
   790
    // Check that an Aes Read isn't already in progress
sl@0
   791
    if(iAesReadStatus)
sl@0
   792
        {
sl@0
   793
        Kern::ThreadKill(iParent.iClient,EExitPanic,ERequestAlreadyPending,KCryptoPanicCategory);
sl@0
   794
        return KErrInUse;
sl@0
   795
        }
sl@0
   796
sl@0
   797
	// We only support a single outstanding Aes Read request in this LDD
sl@0
   798
	// channel, but the PDD supports multiple requests.
sl@0
   799
sl@0
   800
    // Save the client request status and descriptor
sl@0
   801
    iAesReadStatus = aStatus;
sl@0
   802
    iAesReadDescriptor = aPtr;
sl@0
   803
	iReadRequestLength = aLength;
sl@0
   804
sl@0
   805
	// Retrieve user request length (ie. current length of user descriptor) into iRequestLength
sl@0
   806
	//	TInt iOriginalUserReadDescLength;
sl@0
   807
	TUint8 *aesReadDescriptorBufferRaw;
sl@0
   808
	TInt maxLen;
sl@0
   809
	TInt r=Kern::ThreadGetDesInfo(iParent.iClient, iAesReadDescriptor, iOriginalUserReadDescLength, maxLen, aesReadDescriptorBufferRaw, ETrue);
sl@0
   810
	if(r != KErrNone)
sl@0
   811
		{
sl@0
   812
		iAesReadStatus = 0;
sl@0
   813
		return r;
sl@0
   814
 		}
sl@0
   815
sl@0
   816
	if(iReadRequestLength > (maxLen - iOriginalUserReadDescLength))
sl@0
   817
		{
sl@0
   818
		return KErrArgument;
sl@0
   819
		}
sl@0
   820
sl@0
   821
	// Set current offset into user descriptor
sl@0
   822
	iCurrentUserReadIndex = 0;
sl@0
   823
sl@0
   824
	// Tell PDD our request length so it can optimse returning the data to us.
sl@0
   825
	iJob->NotifyReadRequestLength(iReadRequestLength);
sl@0
   826
	
sl@0
   827
sl@0
   828
#ifndef HW_PERF_CHECK
sl@0
   829
	// Make sure iJob is valid before we use it
sl@0
   830
	iJob = iParent.PddChan()->GetJobAes();
sl@0
   831
sl@0
   832
	// Process any data already available
sl@0
   833
	r = DataAvailable(); // Fake PDD callback to read data from PDD
sl@0
   834
	if(r != KErrNone)
sl@0
   835
		{
sl@0
   836
		iAesReadStatus = 0;
sl@0
   837
		return r;
sl@0
   838
 		}
sl@0
   839
sl@0
   840
	// Make sure job is not stalled (and maybe re-add to job list) We
sl@0
   841
	// do this even if we completely satisified the read from the PDD
sl@0
   842
	// buffer because a write might be waiting for space in the
sl@0
   843
	// buffer...
sl@0
   844
	iJob->Resume();
sl@0
   845
#endif
sl@0
   846
sl@0
   847
	return KErrNone;
sl@0
   848
	}
sl@0
   849
sl@0
   850
sl@0
   851
sl@0
   852
TInt DLddChanAes::DataRequired()
sl@0
   853
	{
sl@0
   854
	TRACE_FUNCTION("DataRequired");
sl@0
   855
	//	Kern::Printf("DLddChanAes::DataRequired");
sl@0
   856
	if(!iAesWriteStatus)
sl@0
   857
		{
sl@0
   858
		return KErrNone;
sl@0
   859
		}
sl@0
   860
	
sl@0
   861
	TBool moreSpace = ETrue;
sl@0
   862
	TInt toWrite = (iWriteRequestLength - iCurrentUserWriteIndex);
sl@0
   863
	while(toWrite && moreSpace)
sl@0
   864
		{
sl@0
   865
		// Get details of PDD write buffer
sl@0
   866
		TUint8 *pddBuf; // always valid, though pddBufLen might be 0
sl@0
   867
		TUint32 pddBufLen; // maybe 0
sl@0
   868
		iJob->GetToPddBuffer(pddBuf, pddBufLen, moreSpace);
sl@0
   869
sl@0
   870
		if(toWrite > pddBufLen)
sl@0
   871
			{
sl@0
   872
			toWrite = pddBufLen;
sl@0
   873
			}
sl@0
   874
sl@0
   875
		// Make sure there is some data to write
sl@0
   876
		if(toWrite == 0)
sl@0
   877
			{
sl@0
   878
			break;
sl@0
   879
			}
sl@0
   880
sl@0
   881
		TPtr8 des(pddBuf, toWrite);
sl@0
   882
		TInt r=Kern::ThreadDesRead(iParent.iClient, iAesWriteDescriptor, des, iCurrentUserWriteIndex);
sl@0
   883
		//TInt r = 0;
sl@0
   884
		if(r!=KErrNone)
sl@0
   885
			return r;
sl@0
   886
		iCurrentUserWriteIndex += toWrite;
sl@0
   887
		// Tell the PDD how many bytes we wrote to it.
sl@0
   888
		// If we wrote data, and the job was not already queued, the
sl@0
   889
		// PDD will call ScheduleJob for it.
sl@0
   890
		iJob->BytesWrittenToPdd(toWrite);
sl@0
   891
sl@0
   892
		// Update count of bytes left to write
sl@0
   893
		toWrite = (iWriteRequestLength - iCurrentUserWriteIndex);
sl@0
   894
		};
sl@0
   895
sl@0
   896
	if((iWriteRequestLength - iCurrentUserWriteIndex) <= 0)
sl@0
   897
		{
sl@0
   898
		// Write request is complete
sl@0
   899
		// Finished with client descriptor, so NULL it to help detect coding errors
sl@0
   900
		iAesWriteDescriptor = NULL;
sl@0
   901
		// Complete client's request
sl@0
   902
		Kern::RequestComplete(iParent.iClient,iAesWriteStatus, KErrNone);
sl@0
   903
		return KErrNone;
sl@0
   904
		}
sl@0
   905
sl@0
   906
	return KErrNone;
sl@0
   907
	}
sl@0
   908
sl@0
   909
TInt DLddChanAes::DataAvailable()
sl@0
   910
	{
sl@0
   911
	TRACE_FUNCTION("DataAvailable");
sl@0
   912
	//	Kern::Printf("DLddChanAes::DataAvailable()");
sl@0
   913
sl@0
   914
	if(!iAesReadStatus)
sl@0
   915
		{
sl@0
   916
		return KErrNone;
sl@0
   917
		}
sl@0
   918
sl@0
   919
	TInt r = KErrNone;
sl@0
   920
sl@0
   921
	TUint8 *buf;
sl@0
   922
	TUint32 bufLen;
sl@0
   923
	TBool check = ETrue;
sl@0
   924
	while(check)
sl@0
   925
		{
sl@0
   926
		iJob->GetFromPddBuffer(buf, bufLen, check);
sl@0
   927
		if(bufLen)
sl@0
   928
			{
sl@0
   929
			TInt required = iReadRequestLength - iCurrentUserReadIndex;
sl@0
   930
			TInt toTransfer = bufLen;
sl@0
   931
			if(toTransfer > required)
sl@0
   932
				{
sl@0
   933
				toTransfer = required;
sl@0
   934
				}
sl@0
   935
			// Copy the current buffer to user land
sl@0
   936
			TPtr8 des(buf, toTransfer, toTransfer);
sl@0
   937
			r=Kern::ThreadDesWrite(iParent.iClient, iAesReadDescriptor, des, iOriginalUserReadDescLength + iCurrentUserReadIndex);
sl@0
   938
			//r  = 0;
sl@0
   939
			if(r != KErrNone)
sl@0
   940
				{
sl@0
   941
				break;
sl@0
   942
				}
sl@0
   943
			
sl@0
   944
			// Update our index into the user descriptor
sl@0
   945
			iCurrentUserReadIndex += toTransfer;
sl@0
   946
sl@0
   947
			// Update h/w with number of bytes actually read
sl@0
   948
			iJob->BytesReadFromPdd(toTransfer);
sl@0
   949
sl@0
   950
			if(toTransfer != bufLen)
sl@0
   951
				{
sl@0
   952
				// We did not read all the available data, so do not
sl@0
   953
				// re-query h/w
sl@0
   954
				check = EFalse;
sl@0
   955
				}
sl@0
   956
			}
sl@0
   957
		};
sl@0
   958
sl@0
   959
	if((iReadRequestLength - iCurrentUserReadIndex) <= 0)
sl@0
   960
		{
sl@0
   961
		// Read request is complete
sl@0
   962
		// Finished with client descriptor, so NULL it to help detect coding errors
sl@0
   963
		iAesReadDescriptor = NULL;
sl@0
   964
		// Complete client's request
sl@0
   965
		Kern::RequestComplete(iParent.iClient,iAesReadStatus, KErrNone);
sl@0
   966
		return KErrNone;
sl@0
   967
		}
sl@0
   968
sl@0
   969
	return KErrNone;
sl@0
   970
	}
sl@0
   971
sl@0
   972
sl@0
   973
sl@0
   974
sl@0
   975
sl@0
   976
/**
sl@0
   977
  Called by PDD from a DFC to indicate that a Aes operation has completed.
sl@0
   978
*/
sl@0
   979
void DLddChanAes::JobComplete(TInt aResult)
sl@0
   980
	{
sl@0
   981
	TRACE_FUNCTION("JobComplete");
sl@0
   982
	// Normally not used for AES, instead the job keeps running and
sl@0
   983
	// DataAvailable/DataRequired complete the AesRead/AesWrite
sl@0
   984
	// requests.
sl@0
   985
	// 
sl@0
   986
	// Will be called if xfer to/from user space fails (or if another
sl@0
   987
	// fatal error occurs).
sl@0
   988
    if(iAesReadStatus)
sl@0
   989
        {
sl@0
   990
        // Finished with client descriptor, so NULL it to help detect coding errors
sl@0
   991
        iAesReadDescriptor = NULL;
sl@0
   992
        // Complete clients request (nb following call set iAesReadStatus to 0)
sl@0
   993
        Kern::RequestComplete(iParent.iClient,iAesReadStatus, aResult);
sl@0
   994
        }
sl@0
   995
    if(iAesWriteStatus)
sl@0
   996
        {
sl@0
   997
        // Finished with client descriptor, so NULL it to help detect coding errors
sl@0
   998
        iAesWriteDescriptor = NULL;
sl@0
   999
        // Complete clients request (nb following call set iAesWriteStatus to 0)
sl@0
  1000
        Kern::RequestComplete(iParent.iClient,iAesWriteStatus, aResult);
sl@0
  1001
        }
sl@0
  1002
	}
sl@0
  1003
sl@0
  1004
sl@0
  1005
sl@0
  1006
/**
sl@0
  1007
  Cancel a Aes Read request.
sl@0
  1008
*/
sl@0
  1009
void DLddChanAes::CancelRead()
sl@0
  1010
    {
sl@0
  1011
	TRACE_FUNCTION("CancelRead");
sl@0
  1012
    if(iAesReadStatus)
sl@0
  1013
        {
sl@0
  1014
        // Finished with client descriptor, so NULL it to help detect coding errors
sl@0
  1015
        iAesReadDescriptor = NULL;
sl@0
  1016
        // Complete clients request (nb following call set iAesReadStatus to 0)
sl@0
  1017
        Kern::RequestComplete(iParent.iClient,iAesReadStatus,KErrCancel);
sl@0
  1018
        }
sl@0
  1019
    }
sl@0
  1020
sl@0
  1021
/**
sl@0
  1022
  Cancel a Aes Write request.
sl@0
  1023
*/
sl@0
  1024
void DLddChanAes::CancelWrite()
sl@0
  1025
    {
sl@0
  1026
	TRACE_FUNCTION("CancelWrite");
sl@0
  1027
    if(iAesWriteStatus)
sl@0
  1028
        {
sl@0
  1029
        // Finished with client descriptor, so NULL it to help detect coding errors
sl@0
  1030
        iAesWriteDescriptor = NULL;
sl@0
  1031
        // Complete clients request (nb following call set iAesWriteStatus to 0)
sl@0
  1032
        Kern::RequestComplete(iParent.iClient,iAesWriteStatus,KErrCancel);
sl@0
  1033
        }
sl@0
  1034
    }
sl@0
  1035
sl@0
  1036
// End of file