| sl@0 |      1 | /*
 | 
| sl@0 |      2 | * Copyright (c) 2003-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 | #include <asymmetrickeys.h>
 | 
| sl@0 |     20 | #include <bigint.h>
 | 
| sl@0 |     21 | #include "../common/inlines.h"
 | 
| sl@0 |     22 | 
 | 
| sl@0 |     23 | const TUint KFermat4 = 65537;
 | 
| sl@0 |     24 | 
 | 
| sl@0 |     25 | /* CRSAParameters */
 | 
| sl@0 |     26 | 
 | 
| sl@0 |     27 | EXPORT_C const TInteger& CRSAParameters::N(void) const
 | 
| sl@0 |     28 | 	{
 | 
| sl@0 |     29 | 	return iN;
 | 
| sl@0 |     30 | 	}
 | 
| sl@0 |     31 | 
 | 
| sl@0 |     32 | EXPORT_C CRSAParameters::~CRSAParameters(void)
 | 
| sl@0 |     33 | 	{
 | 
| sl@0 |     34 | 	iN.Close();
 | 
| sl@0 |     35 | 	}
 | 
| sl@0 |     36 | 
 | 
| sl@0 |     37 | EXPORT_C CRSAParameters::CRSAParameters(RInteger& aN) : iN(aN)
 | 
| sl@0 |     38 | 	{
 | 
| sl@0 |     39 | 	}
 | 
| sl@0 |     40 | 
 | 
| sl@0 |     41 | EXPORT_C CRSAParameters::CRSAParameters(void)
 | 
| sl@0 |     42 | 	{
 | 
| sl@0 |     43 | 	}
 | 
| sl@0 |     44 | 
 | 
| sl@0 |     45 | /* CRSAPublicKey */
 | 
| sl@0 |     46 | 
 | 
| sl@0 |     47 | EXPORT_C CRSAPublicKey* CRSAPublicKey::NewL(RInteger& aN, RInteger& aE)
 | 
| sl@0 |     48 | 	{
 | 
| sl@0 |     49 | 	CRSAPublicKey* self = NewLC(aN, aE);
 | 
| sl@0 |     50 | 	CleanupStack::Pop();
 | 
| sl@0 |     51 | 	return self;
 | 
| sl@0 |     52 | 	}
 | 
| sl@0 |     53 | 
 | 
| sl@0 |     54 | EXPORT_C CRSAPublicKey* CRSAPublicKey::NewLC(RInteger& aN, RInteger& aE)
 | 
| sl@0 |     55 | 	{
 | 
| sl@0 |     56 | 	CRSAPublicKey* self = new(ELeave) CRSAPublicKey(aN, aE);
 | 
| sl@0 |     57 | 	CleanupStack::PushL(self);
 | 
| sl@0 |     58 | 	self->ConstructL();
 | 
| sl@0 |     59 | 	return self;
 | 
| sl@0 |     60 | 	}
 | 
| sl@0 |     61 | 
 | 
| sl@0 |     62 | 
 | 
| sl@0 |     63 | void CRSAPublicKey::ConstructL()
 | 
| sl@0 |     64 | 	{ 
 | 
| sl@0 |     65 | 	// Check that the modulus and exponent are positive integers 
 | 
| sl@0 |     66 | 	// as specified by RSA
 | 
| sl@0 |     67 | 	if(!N().IsPositive() || !E().IsPositive() || (E() <= 1))
 | 
| sl@0 |     68 | 		{
 | 
| sl@0 |     69 | 		// If we need to leave during construction we must release ownership
 | 
| sl@0 |     70 | 		// of the RInteger parameters that were passed in.
 | 
| sl@0 |     71 | 		// These parameters should be on the cleanup stack so if we don't 
 | 
| sl@0 |     72 | 		// release ownership they will be deleted twice, causing a panic
 | 
| sl@0 |     73 | 		iN = RInteger();
 | 
| sl@0 |     74 | 		iE = RInteger();
 | 
| sl@0 |     75 | 		User::Leave(KErrArgument);
 | 
| sl@0 |     76 | 		}
 | 
| sl@0 |     77 | 	}
 | 
| sl@0 |     78 | 
 | 
| sl@0 |     79 | 
 | 
| sl@0 |     80 | EXPORT_C const TInteger& CRSAPublicKey::E(void) const
 | 
| sl@0 |     81 | 	{
 | 
| sl@0 |     82 | 	return iE;
 | 
| sl@0 |     83 | 	}
 | 
| sl@0 |     84 | 
 | 
| sl@0 |     85 | EXPORT_C CRSAPublicKey::CRSAPublicKey()
 | 
| sl@0 |     86 | 	{
 | 
| sl@0 |     87 | 	}
 | 
| sl@0 |     88 | 
 | 
| sl@0 |     89 | EXPORT_C CRSAPublicKey::CRSAPublicKey(RInteger& aN, RInteger& aE)
 | 
| sl@0 |     90 | 	: CRSAParameters(aN), iE(aE)
 | 
| sl@0 |     91 | 	{
 | 
| sl@0 |     92 | 	}
 | 
| sl@0 |     93 | 
 | 
| sl@0 |     94 | EXPORT_C CRSAPublicKey::~CRSAPublicKey(void)
 | 
| sl@0 |     95 | 	{
 | 
| sl@0 |     96 | 	iE.Close();
 | 
| sl@0 |     97 | 	}
 | 
| sl@0 |     98 | 
 | 
| sl@0 |     99 | /* CRSAPrivateKeyType */
 | 
| sl@0 |    100 | 
 | 
| sl@0 |    101 | CRSAPrivateKey::CRSAPrivateKey(const TRSAPrivateKeyType aKeyType, RInteger& aN)
 | 
| sl@0 |    102 | :	CRSAParameters(aN), iKeyType(aKeyType)
 | 
| sl@0 |    103 | {}
 | 
| sl@0 |    104 | 
 | 
| sl@0 |    105 | 
 | 
| sl@0 |    106 | /* CRSAPrivateKeyStandard */
 | 
| sl@0 |    107 | 
 | 
| sl@0 |    108 | EXPORT_C CRSAPrivateKeyStandard* CRSAPrivateKeyStandard::NewL(RInteger& aN, 
 | 
| sl@0 |    109 | 	RInteger& aD)
 | 
| sl@0 |    110 | 	{
 | 
| sl@0 |    111 | 	CRSAPrivateKeyStandard* self = NewLC(aN, aD);
 | 
| sl@0 |    112 | 	CleanupStack::Pop();
 | 
| sl@0 |    113 | 	return self;
 | 
| sl@0 |    114 | 	}
 | 
| sl@0 |    115 | 
 | 
| sl@0 |    116 | EXPORT_C CRSAPrivateKeyStandard* CRSAPrivateKeyStandard::NewLC(RInteger& aN,
 | 
| sl@0 |    117 | 	RInteger& aD)
 | 
| sl@0 |    118 | 	{
 | 
| sl@0 |    119 | 	CRSAPrivateKeyStandard* self = new(ELeave) CRSAPrivateKeyStandard(aN, aD);
 | 
| sl@0 |    120 | 	CleanupStack::PushL(self);
 | 
| sl@0 |    121 | 	self->ConstructL();
 | 
| sl@0 |    122 | 	return self;
 | 
| sl@0 |    123 | 	}
 | 
| sl@0 |    124 | 
 | 
| sl@0 |    125 | void CRSAPrivateKeyStandard::ConstructL()
 | 
| sl@0 |    126 | 	{
 | 
| sl@0 |    127 | 	// Check that the modulus and exponent are positive integers
 | 
| sl@0 |    128 | 	if(!N().IsPositive() || !D().IsPositive() || (D() <= 1))
 | 
| sl@0 |    129 | 		{
 | 
| sl@0 |    130 | 		// If we need to leave during construction we must release ownership
 | 
| sl@0 |    131 | 		// of the RInteger parameters that were passed in.
 | 
| sl@0 |    132 | 		// These parameters should be on the cleanup stack so if we don't 
 | 
| sl@0 |    133 | 		// release ownership they will be deleted twice, causing a panic
 | 
| sl@0 |    134 | 		iN = RInteger();
 | 
| sl@0 |    135 | 		iD = RInteger();
 | 
| sl@0 |    136 | 		User::Leave(KErrArgument);
 | 
| sl@0 |    137 | 		}
 | 
| sl@0 |    138 | 	}
 | 
| sl@0 |    139 | 
 | 
| sl@0 |    140 | EXPORT_C const TInteger& CRSAPrivateKeyStandard::D(void) const
 | 
| sl@0 |    141 | 	{
 | 
| sl@0 |    142 | 	return iD;
 | 
| sl@0 |    143 | 	}
 | 
| sl@0 |    144 | 
 | 
| sl@0 |    145 | EXPORT_C CRSAPrivateKeyStandard::CRSAPrivateKeyStandard(RInteger& aN, 
 | 
| sl@0 |    146 | 	RInteger& aD) : CRSAPrivateKey(EStandard, aN), iD(aD)
 | 
| sl@0 |    147 | 	{
 | 
| sl@0 |    148 | 	}
 | 
| sl@0 |    149 | 
 | 
| sl@0 |    150 | EXPORT_C CRSAPrivateKeyStandard::~CRSAPrivateKeyStandard()
 | 
| sl@0 |    151 | 	{	
 | 
| sl@0 |    152 | 	iD.Close();
 | 
| sl@0 |    153 | 	}
 | 
| sl@0 |    154 | 
 | 
| sl@0 |    155 | /* CRSAPrivateKeyCRT */
 | 
| sl@0 |    156 | 
 | 
| sl@0 |    157 | EXPORT_C CRSAPrivateKeyCRT* CRSAPrivateKeyCRT::NewL(RInteger& aN, RInteger& aP,
 | 
| sl@0 |    158 | 	RInteger& aQ, RInteger& aDP, RInteger& aDQ, RInteger& aQInv)
 | 
| sl@0 |    159 | 	{
 | 
| sl@0 |    160 | 	CRSAPrivateKeyCRT* self = NewLC(aN, aP, aQ, aDP, aDQ, aQInv);
 | 
| sl@0 |    161 | 	CleanupStack::Pop();
 | 
| sl@0 |    162 | 	return self;
 | 
| sl@0 |    163 | 	}
 | 
| sl@0 |    164 | 
 | 
| sl@0 |    165 | EXPORT_C CRSAPrivateKeyCRT* CRSAPrivateKeyCRT::NewLC(RInteger& aN, RInteger& aP, 
 | 
| sl@0 |    166 | 	RInteger& aQ, RInteger& aDP, RInteger& aDQ, RInteger& aQInv)
 | 
| sl@0 |    167 | 	{
 | 
| sl@0 |    168 | 	CRSAPrivateKeyCRT* self = new(ELeave) CRSAPrivateKeyCRT(aN, aP, aQ, 
 | 
| sl@0 |    169 | 		aDP, aDQ, aQInv);
 | 
| sl@0 |    170 | 	CleanupStack::PushL(self);
 | 
| sl@0 |    171 | 	self->ConstructL();
 | 
| sl@0 |    172 | 	return self;
 | 
| sl@0 |    173 | 	}
 | 
| sl@0 |    174 | 
 | 
| sl@0 |    175 | EXPORT_C CRSAPrivateKeyCRT::CRSAPrivateKeyCRT(RInteger& aN, RInteger& aP, 
 | 
| sl@0 |    176 | 	RInteger& aQ, RInteger& aDP, RInteger& aDQ, RInteger& aQInv) 
 | 
| sl@0 |    177 | 	: CRSAPrivateKey(EStandardCRT, aN), iP(aP), iQ(aQ), iDP(aDP), iDQ(aDQ), 
 | 
| sl@0 |    178 | 		iQInv(aQInv)
 | 
| sl@0 |    179 | 	{
 | 
| sl@0 |    180 | 	}
 | 
| sl@0 |    181 | 
 | 
| sl@0 |    182 | void CRSAPrivateKeyCRT::ConstructL()
 | 
| sl@0 |    183 | 	{
 | 
| sl@0 |    184 | 	// Check that all parameters are positive integers
 | 
| sl@0 |    185 | 	if(!P().IsPositive() || !Q().IsPositive() || !DP().IsPositive() 
 | 
| sl@0 |    186 | 		|| !DQ().IsPositive() || !QInv().IsPositive())
 | 
| sl@0 |    187 | 		{
 | 
| sl@0 |    188 | 		// If we need to leave during construction we must release ownership
 | 
| sl@0 |    189 | 		// of the RInteger parameters that were passed in.
 | 
| sl@0 |    190 | 		// These parameters should be on the cleanup stack so if we don't 
 | 
| sl@0 |    191 | 		// release ownership they will be deleted twice, causing a panic
 | 
| sl@0 |    192 | 		iN = RInteger();
 | 
| sl@0 |    193 | 		iP = RInteger();
 | 
| sl@0 |    194 | 		iQ = RInteger();
 | 
| sl@0 |    195 | 		iDP = RInteger();
 | 
| sl@0 |    196 | 		iDQ = RInteger();
 | 
| sl@0 |    197 | 		iQInv = RInteger();
 | 
| sl@0 |    198 | 		User::Leave(KErrArgument);
 | 
| sl@0 |    199 | 		}
 | 
| sl@0 |    200 | 	}
 | 
| sl@0 |    201 | 
 | 
| sl@0 |    202 | 
 | 
| sl@0 |    203 | EXPORT_C CRSAPrivateKeyCRT::~CRSAPrivateKeyCRT()
 | 
| sl@0 |    204 | 	{	
 | 
| sl@0 |    205 | 	iP.Close();
 | 
| sl@0 |    206 | 	iQ.Close();
 | 
| sl@0 |    207 | 	iDP.Close();
 | 
| sl@0 |    208 | 	iDQ.Close();
 | 
| sl@0 |    209 | 	iQInv.Close();
 | 
| sl@0 |    210 | 	}
 | 
| sl@0 |    211 | 
 | 
| sl@0 |    212 | EXPORT_C const TInteger& CRSAPrivateKeyCRT::P(void) const
 | 
| sl@0 |    213 | 	{
 | 
| sl@0 |    214 | 	return iP;
 | 
| sl@0 |    215 | 	}
 | 
| sl@0 |    216 | 
 | 
| sl@0 |    217 | EXPORT_C const TInteger& CRSAPrivateKeyCRT::Q(void) const
 | 
| sl@0 |    218 | 	{
 | 
| sl@0 |    219 | 	return iQ;
 | 
| sl@0 |    220 | 	}
 | 
| sl@0 |    221 | 
 | 
| sl@0 |    222 | EXPORT_C const TInteger& CRSAPrivateKeyCRT::DP(void) const
 | 
| sl@0 |    223 | 	{
 | 
| sl@0 |    224 | 	return iDP;
 | 
| sl@0 |    225 | 	}
 | 
| sl@0 |    226 | 
 | 
| sl@0 |    227 | EXPORT_C const TInteger& CRSAPrivateKeyCRT::DQ(void) const
 | 
| sl@0 |    228 | 	{
 | 
| sl@0 |    229 | 	return iDQ;
 | 
| sl@0 |    230 | 	}
 | 
| sl@0 |    231 | 
 | 
| sl@0 |    232 | EXPORT_C const TInteger& CRSAPrivateKeyCRT::QInv(void) const
 | 
| sl@0 |    233 | 	{
 | 
| sl@0 |    234 | 	return iQInv;
 | 
| sl@0 |    235 | 	}
 | 
| sl@0 |    236 | 
 | 
| sl@0 |    237 | /* CRSAKeyPair */
 | 
| sl@0 |    238 | 
 | 
| sl@0 |    239 | EXPORT_C CRSAKeyPair* CRSAKeyPair::NewL(TUint aModulusBits, 
 | 
| sl@0 |    240 | 	TRSAPrivateKeyType aKeyType /*= EStandardCRT*/)
 | 
| sl@0 |    241 | 	{
 | 
| sl@0 |    242 | 	CRSAKeyPair* self = NewLC(aModulusBits, aKeyType);
 | 
| sl@0 |    243 | 	CleanupStack::Pop();
 | 
| sl@0 |    244 | 	return self;
 | 
| sl@0 |    245 | 	}
 | 
| sl@0 |    246 | 
 | 
| sl@0 |    247 | EXPORT_C CRSAKeyPair* CRSAKeyPair::NewLC(TUint aModulusBits, 
 | 
| sl@0 |    248 | 	TRSAPrivateKeyType aKeyType /*= EStandardCRT*/)
 | 
| sl@0 |    249 | 	{
 | 
| sl@0 |    250 | 	CRSAKeyPair* self = new(ELeave) CRSAKeyPair();
 | 
| sl@0 |    251 | 	CleanupStack::PushL(self);
 | 
| sl@0 |    252 | 	self->ConstructL(aModulusBits, aKeyType, KFermat4);
 | 
| sl@0 |    253 | 	return self;
 | 
| sl@0 |    254 | 	}
 | 
| sl@0 |    255 | 
 | 
| sl@0 |    256 | EXPORT_C const CRSAPublicKey& CRSAKeyPair::PublicKey(void) const
 | 
| sl@0 |    257 | 	{
 | 
| sl@0 |    258 | 	return *iPublic;
 | 
| sl@0 |    259 | 	}
 | 
| sl@0 |    260 | 	
 | 
| sl@0 |    261 | EXPORT_C const CRSAPrivateKey& CRSAKeyPair::PrivateKey(void) const
 | 
| sl@0 |    262 | 	{
 | 
| sl@0 |    263 | 	return *iPrivate;
 | 
| sl@0 |    264 | 	}
 | 
| sl@0 |    265 | 
 | 
| sl@0 |    266 | EXPORT_C CRSAKeyPair::~CRSAKeyPair(void) 
 | 
| sl@0 |    267 | 	{
 | 
| sl@0 |    268 | 	delete iPublic;
 | 
| sl@0 |    269 | 	delete iPrivate;
 | 
| sl@0 |    270 | 	}
 | 
| sl@0 |    271 | 
 | 
| sl@0 |    272 | EXPORT_C CRSAKeyPair::CRSAKeyPair(void)
 | 
| sl@0 |    273 | 	{
 | 
| sl@0 |    274 | 	}
 | 
| sl@0 |    275 | 
 | 
| sl@0 |    276 | void CRSAKeyPair::ConstructL(TUint aModulusBits, 
 | 
| sl@0 |    277 | 	TRSAPrivateKeyType aKeyType, TUint aPublicExponent)
 | 
| sl@0 |    278 | 	{
 | 
| sl@0 |    279 | 	RInteger e = RInteger::NewL(aPublicExponent);
 | 
| sl@0 |    280 | 	CleanupStack::PushL(e);
 | 
| sl@0 |    281 | 
 | 
| sl@0 |    282 | 	RInteger p;
 | 
| sl@0 |    283 | 	RInteger q;
 | 
| sl@0 |    284 | 	
 | 
| sl@0 |    285 | 	//these make sure n is a least aModulusBits long
 | 
| sl@0 |    286 |     TInt pbits=(aModulusBits+1)/2;
 | 
| sl@0 |    287 |     TInt qbits=aModulusBits-pbits;
 | 
| sl@0 |    288 | 
 | 
| sl@0 |    289 | 	//generate a prime p such that GCD(e,p-1) == 1
 | 
| sl@0 |    290 | 	for (;;)
 | 
| sl@0 |    291 | 		{
 | 
| sl@0 |    292 | 		p = RInteger::NewPrimeL(pbits,TInteger::ETop2BitsSet);
 | 
| sl@0 |    293 | 		CleanupStack::PushL(p);
 | 
| sl@0 |    294 | 		--p;
 | 
| sl@0 |    295 | 
 | 
| sl@0 |    296 | 		RInteger gcd = e.GCDL(p);
 | 
| sl@0 |    297 | 		if( gcd == 1 )
 | 
| sl@0 |    298 | 			{
 | 
| sl@0 |    299 | 			++p;
 | 
| sl@0 |    300 | 			gcd.Close();
 | 
| sl@0 |    301 | 			//p is still on cleanup stack
 | 
| sl@0 |    302 | 			break;
 | 
| sl@0 |    303 | 			}
 | 
| sl@0 |    304 | 		CleanupStack::PopAndDestroy(&p);
 | 
| sl@0 |    305 | 		gcd.Close();
 | 
| sl@0 |    306 | 		}
 | 
| sl@0 |    307 | 
 | 
| sl@0 |    308 | 	//generate a prime q such that GCD(e,q-1) == 1 && (p != q)
 | 
| sl@0 |    309 | 	for (;;)
 | 
| sl@0 |    310 | 		{
 | 
| sl@0 |    311 | 		q = RInteger::NewPrimeL(qbits,TInteger::ETop2BitsSet);
 | 
| sl@0 |    312 | 		CleanupStack::PushL(q);
 | 
| sl@0 |    313 | 		--q;
 | 
| sl@0 |    314 | 
 | 
| sl@0 |    315 | 		RInteger gcd = e.GCDL(q);
 | 
| sl@0 |    316 | 		if( gcd == 1 )
 | 
| sl@0 |    317 | 			{
 | 
| sl@0 |    318 | 			++q;
 | 
| sl@0 |    319 | 			if( p != q )
 | 
| sl@0 |    320 | 				{
 | 
| sl@0 |    321 | 				gcd.Close();
 | 
| sl@0 |    322 | 				//q is still on cleanup stack
 | 
| sl@0 |    323 | 				break;
 | 
| sl@0 |    324 | 				}
 | 
| sl@0 |    325 | 			}
 | 
| sl@0 |    326 | 		CleanupStack::PopAndDestroy(&q);
 | 
| sl@0 |    327 | 		gcd.Close();
 | 
| sl@0 |    328 | 		}
 | 
| sl@0 |    329 | 		
 | 
| sl@0 |    330 | 	//make sure p > q
 | 
| sl@0 |    331 |     if ( p < q)
 | 
| sl@0 |    332 |         {
 | 
| sl@0 |    333 | 		TClassSwap(p,q);
 | 
| sl@0 |    334 |         }
 | 
| sl@0 |    335 | 
 | 
| sl@0 |    336 | 	//calculate n = p * q 
 | 
| sl@0 |    337 | 	RInteger n = p.TimesL(q);
 | 
| sl@0 |    338 | 	CleanupStack::PushL(n);
 | 
| sl@0 |    339 | 
 | 
| sl@0 |    340 | 	--p;
 | 
| sl@0 |    341 | 	--q;
 | 
| sl@0 |    342 | 
 | 
| sl@0 |    343 | 	//temp = (p-1)(q-1)
 | 
| sl@0 |    344 | 	RInteger temp = p.TimesL(q);
 | 
| sl@0 |    345 | 	CleanupStack::PushL(temp);
 | 
| sl@0 |    346 | 
 | 
| sl@0 |    347 | 	//e * d = 1 mod ((p-1)(q-1)) 
 | 
| sl@0 |    348 | 	//d = e^(-1) mod ((p-1)(q-1))
 | 
| sl@0 |    349 | 	RInteger d = e.InverseModL(temp);
 | 
| sl@0 |    350 | 	CleanupStack::PopAndDestroy(&temp); //temp
 | 
| sl@0 |    351 | 	CleanupStack::PushL(d);
 | 
| sl@0 |    352 | 
 | 
| sl@0 |    353 | 	if (aKeyType==EStandardCRT)
 | 
| sl@0 |    354 | 	{
 | 
| sl@0 |    355 | 		//calculate dP = d mod (p-1) 
 | 
| sl@0 |    356 | 		RInteger dP = d.ModuloL(p); //p is still p-1
 | 
| sl@0 |    357 | 		CleanupStack::PushL(dP);
 | 
| sl@0 |    358 | 
 | 
| sl@0 |    359 | 		//calculate dQ = d mod (q-1) 
 | 
| sl@0 |    360 | 		RInteger dQ = d.ModuloL(q); //q is still q-1
 | 
| sl@0 |    361 | 		CleanupStack::PushL(dQ);
 | 
| sl@0 |    362 | 
 | 
| sl@0 |    363 | 		++p;
 | 
| sl@0 |    364 | 		++q;
 | 
| sl@0 |    365 | 		//calculate inverse of qInv = q^(-1)mod(p)
 | 
| sl@0 |    366 | 		RInteger qInv = q.InverseModL(p);
 | 
| sl@0 |    367 | 		CleanupStack::PushL(qInv);
 | 
| sl@0 |    368 | 
 | 
| sl@0 |    369 | 		iPrivate = CRSAPrivateKeyCRT::NewL(n,p,q,dP,dQ,qInv);
 | 
| sl@0 |    370 | 		
 | 
| sl@0 |    371 | 		CleanupStack::Pop(3, &dP); //qInv, dQ, dP
 | 
| sl@0 |    372 | 		CleanupStack::PopAndDestroy(&d); //d	
 | 
| sl@0 |    373 | 		CleanupStack::Pop(3, &p); //n, q, p
 | 
| sl@0 |    374 | 		//e is still on cleanup stack
 | 
| sl@0 |    375 | 	}
 | 
| sl@0 |    376 | 	else if (aKeyType==EStandard)
 | 
| sl@0 |    377 | 	{
 | 
| sl@0 |    378 | 		iPrivate = CRSAPrivateKeyStandard::NewL(n,d);
 | 
| sl@0 |    379 | 
 | 
| sl@0 |    380 | 		CleanupStack::Pop(2, &n); //d, n
 | 
| sl@0 |    381 | 		CleanupStack::PopAndDestroy(2, &p); //q, p
 | 
| sl@0 |    382 | 		//e is still on cleanup stack
 | 
| sl@0 |    383 | 	}
 | 
| sl@0 |    384 | 	else
 | 
| sl@0 |    385 | 	{
 | 
| sl@0 |    386 | 		User::Leave(KErrNotSupported);
 | 
| sl@0 |    387 | 	}
 | 
| sl@0 |    388 | 
 | 
| sl@0 |    389 | 	//make a copy of n for the public parameters
 | 
| sl@0 |    390 | 	RInteger n1 = RInteger::NewL(PrivateKey().N());
 | 
| sl@0 |    391 | 	CleanupStack::PushL(n1);
 | 
| sl@0 |    392 | 	iPublic = CRSAPublicKey::NewL(n1,e); 
 | 
| sl@0 |    393 | 	CleanupStack::Pop(2, &e); //n1, e
 | 
| sl@0 |    394 | 	}
 | 
| sl@0 |    395 | 
 |