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