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