os/security/crypto/weakcryptospi/test/tplugins/src/rsakeypairgenimpl.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2006-2010 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 * RSA Keypair implementation
    16 * RSA keypair generation implementation
    17 *
    18 */
    19 
    20 
    21 /**
    22  @file
    23 */
    24 
    25 #include "rsakeypairgenimpl.h"
    26 #include "pluginconfig.h"
    27 
    28 #include <ct.h>
    29 #include <cryptospi/keypair.h>
    30 #include <cryptospi/cryptospidef.h>
    31 
    32 #include "../../../source/common/inlines.h"    // For TClassSwap
    33 
    34 using namespace SoftwareCrypto;
    35 
    36 /* CRSAKeyPairGenImpl */
    37 CRSAKeyPairGenImpl::CRSAKeyPairGenImpl(TUid aImplementationUid) : CKeyPairGenImpl(aImplementationUid)
    38 	{
    39 	}
    40 
    41 CRSAKeyPairGenImpl::~CRSAKeyPairGenImpl()
    42 	{
    43 	}
    44 
    45 CRSAKeyPairGenImpl* CRSAKeyPairGenImpl::NewL(TUid aImplementationUid)
    46 	{
    47 	CRSAKeyPairGenImpl* self = CRSAKeyPairGenImpl::NewLC(aImplementationUid);
    48 	CleanupStack::Pop(self);
    49 	return self;
    50 	}
    51 
    52 CRSAKeyPairGenImpl* CRSAKeyPairGenImpl::NewLC(TUid aImplementationUid)
    53 	{
    54 	CRSAKeyPairGenImpl* self = new(ELeave) CRSAKeyPairGenImpl(aImplementationUid);
    55 	CleanupStack::PushL(self);
    56 	self->ConstructL();
    57 	return self;
    58 	}
    59 
    60 void CRSAKeyPairGenImpl::ConstructL(void)
    61 	{
    62 	CKeyPairGenImpl::ConstructL();
    63 	}
    64 	
    65 CExtendedCharacteristics* CRSAKeyPairGenImpl::CreateExtendedCharacteristicsL()
    66 	{
    67 	// All Symbian software plug-ins have unlimited concurrency, cannot be reserved
    68 	// for exclusive use and are not CERTIFIED to be standards compliant.
    69 	return CExtendedCharacteristics::NewL(KMaxTInt, EFalse);
    70 	}
    71 
    72 const CExtendedCharacteristics* CRSAKeyPairGenImpl::GetExtendedCharacteristicsL()
    73 	{
    74 	return CRSAKeyPairGenImpl::CreateExtendedCharacteristicsL();
    75 	}
    76 
    77 TUid CRSAKeyPairGenImpl::ImplementationUid() const
    78 	{
    79 	return iImplementationUid;
    80 	}
    81 
    82 void CRSAKeyPairGenImpl::Reset()
    83 	{
    84 	// does nothing in this plugin
    85 	}
    86 
    87 void CRSAKeyPairGenImpl::GenerateKeyPairL(TInt aKeySize, const CCryptoParams& aKeyParameters, CKeyPair*& aKeyPair)
    88 	{
    89 	/*
    90 	 * extract e
    91 	 */ 
    92 	const TInt aKeyType = aKeyParameters.GetTIntL(KRsaKeyTypeUid);
    93 	const TInt aPublicExponent = aKeyParameters.GetTIntL(KRsaKeyParameterEUid);
    94 
    95 	RInteger e = RInteger::NewL(aPublicExponent);
    96 	CleanupStack::PushL(e);
    97 
    98 	/*
    99 	 * calculate p, q, n & d
   100 	 */ 
   101 	RInteger p;
   102 	RInteger q;
   103 	
   104 	//these make sure n is a least aKeySize long
   105 	TInt pbits=(aKeySize+1)/2;
   106 	TInt qbits=aKeySize-pbits;
   107 
   108 	//generate a prime p such that GCD(e,p-1) == 1
   109 	for (;;)
   110 		{
   111 		p = RInteger::NewPrimeL(pbits,TInteger::ETop2BitsSet);
   112 		CleanupStack::PushL(p);
   113 		--p;
   114 
   115 		RInteger gcd = e.GCDL(p);
   116 		if( gcd == 1 )
   117 			{
   118 			++p;
   119 			gcd.Close();
   120 			//p is still on cleanup stack
   121 			break;
   122 			}
   123 		CleanupStack::PopAndDestroy(&p);
   124 		gcd.Close();
   125 		}
   126 
   127 	//generate a prime q such that GCD(e,q-1) == 1 && (p != q)
   128 	for (;;)
   129 		{
   130 		q = RInteger::NewPrimeL(qbits,TInteger::ETop2BitsSet);
   131 		CleanupStack::PushL(q);
   132 		--q;
   133 
   134 		RInteger gcd = e.GCDL(q);
   135 		if( gcd == 1 )
   136 			{
   137 			++q;
   138 			if( p != q )
   139 				{
   140 				gcd.Close();
   141 				//q is still on cleanup stack
   142 				break;
   143 				}
   144 			}
   145 		CleanupStack::PopAndDestroy(&q);
   146 		gcd.Close();
   147 		}
   148 		
   149 	//make sure p > q
   150 	if ( p < q)
   151 		{
   152 		TClassSwap(p,q);
   153 		}
   154 
   155 	//calculate n = p * q
   156 	RInteger n = p.TimesL(q);
   157 	CleanupStack::PushL(n);
   158 
   159 	--p;
   160 	--q;
   161 
   162 	//temp = (p-1)(q-1)
   163 	RInteger temp = p.TimesL(q);
   164 	CleanupStack::PushL(temp);
   165 
   166 	//e * d = 1 mod ((p-1)(q-1))
   167 	//d = e^(-1) mod ((p-1)(q-1))
   168 	RInteger d = e.InverseModL(temp);
   169 	CleanupStack::PopAndDestroy(&temp); //temp
   170 	CleanupStack::PushL(d);
   171 
   172 	/*
   173 	 * create private key depending on aKeyType
   174 	 */ 
   175 	CCryptoParams* privateKeyParameters = CCryptoParams::NewLC();
   176 	privateKeyParameters->AddL(n, KRsaKeyParameterNUid);
   177 	TKeyProperty* privateKeyProperties = NULL;
   178 	TKeyProperty privateKeyProperties_RsaPrivateKeyCRT = {KRSAKeyPairGeneratorUid, iImplementationUid,
   179 									KRsaPrivateKeyCRTUid, KNonEmbeddedKeyUid };
   180 	TKeyProperty privateKeyProperties_RsaPrivateKeyStandard = {KRSAKeyPairGeneratorUid, iImplementationUid,
   181 									KRsaPrivateKeyStandardUid, KNonEmbeddedKeyUid };
   182 
   183 	CCryptoParams*publicKeyParameters = CCryptoParams::NewLC();
   184 	publicKeyParameters->AddL(n, KRsaKeyParameterNUid);
   185 	publicKeyParameters->AddL(e, KRsaKeyParameterEUid);
   186 	TKeyProperty publicKeyProperties = {KRSAKeyPairGeneratorUid, iImplementationUid,
   187 									KRsaPublicKeyUid, KNonEmbeddedKeyUid };
   188 
   189 	if (aKeyType == KRsaPrivateKeyCRT)			// cleanup stack contains e, p, q, n, d and privateKeyParameters
   190 	{
   191 
   192 		/*
   193 		 * calculate dP, dQ and qInv
   194 		 */ 
   195 		//calculate dP = d mod (p-1)
   196 		RInteger dP = d.ModuloL(p); //p is still p-1
   197 		CleanupStack::PushL(dP);
   198 		privateKeyParameters->AddL(dP, KRsaKeyParameterDPUid);
   199 		CleanupStack::PopAndDestroy(&dP);
   200 
   201 		//calculate dQ = d mod (q-1)
   202 		RInteger dQ = d.ModuloL(q); //q is still q-1
   203 		CleanupStack::PushL(dQ);
   204 		privateKeyParameters->AddL(dQ, KRsaKeyParameterDQUid);
   205 		CleanupStack::PopAndDestroy(&dQ);
   206 
   207 		++p;
   208 		++q;
   209 		//calculate inverse of qInv = q^(-1)mod(p)
   210 		RInteger qInv = q.InverseModL(p);
   211 		CleanupStack::PushL(qInv);
   212 		privateKeyParameters->AddL(qInv, KRsaKeyParameterQInvUid);
   213 		CleanupStack::PopAndDestroy(&qInv);
   214 		
   215 		privateKeyParameters->AddL(p, KRsaKeyParameterPUid);
   216 		privateKeyParameters->AddL(q, KRsaKeyParameterQUid);
   217 		
   218 		privateKeyProperties = &privateKeyProperties_RsaPrivateKeyCRT;
   219 	}
   220 	else if (aKeyType == KRsaPrivateKeyStandard)
   221 	{
   222 		privateKeyParameters->AddL(d, KRsaKeyParameterDUid);
   223 		privateKeyProperties = &privateKeyProperties_RsaPrivateKeyStandard;
   224 	}
   225 	else
   226 	{
   227 		User::Leave(KErrNotSupported);
   228 	}
   229 	// cleanup stack contains e, p, q, n, d and privateKeyParameters
   230 	CKey* privateKey = CKey::NewL(*privateKeyProperties, *privateKeyParameters);
   231 	CleanupStack::PushL(privateKey);
   232 
   233 	/*
   234 	 * create public key
   235 	 */
   236 	CKey* publicKey = CKey::NewL(publicKeyProperties, *publicKeyParameters);
   237 	CleanupStack::PushL(publicKey);
   238 
   239 	/*
   240 	* create the key pair
   241 	*/
   242 	aKeyPair = CKeyPair::NewL(publicKey, privateKey);
   243 
   244 	CleanupStack::Pop(2, privateKey); //privateKey and publicKey
   245 	CleanupStack::PopAndDestroy(7, &e); //e, p, q, n, d, privateKeyParameters and publicKeyParameters
   246 	}