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