1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/crypto/weakcryptospi/test/tplugins/src/rsakeypairgenimpl.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,246 @@
1.4 +/*
1.5 +* Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +* RSA Keypair implementation
1.19 +* RSA keypair generation implementation
1.20 +*
1.21 +*/
1.22 +
1.23 +
1.24 +/**
1.25 + @file
1.26 +*/
1.27 +
1.28 +#include "rsakeypairgenimpl.h"
1.29 +#include "pluginconfig.h"
1.30 +
1.31 +#include <ct.h>
1.32 +#include <cryptospi/keypair.h>
1.33 +#include <cryptospi/cryptospidef.h>
1.34 +
1.35 +#include "../../../source/common/inlines.h" // For TClassSwap
1.36 +
1.37 +using namespace SoftwareCrypto;
1.38 +
1.39 +/* CRSAKeyPairGenImpl */
1.40 +CRSAKeyPairGenImpl::CRSAKeyPairGenImpl(TUid aImplementationUid) : CKeyPairGenImpl(aImplementationUid)
1.41 + {
1.42 + }
1.43 +
1.44 +CRSAKeyPairGenImpl::~CRSAKeyPairGenImpl()
1.45 + {
1.46 + }
1.47 +
1.48 +CRSAKeyPairGenImpl* CRSAKeyPairGenImpl::NewL(TUid aImplementationUid)
1.49 + {
1.50 + CRSAKeyPairGenImpl* self = CRSAKeyPairGenImpl::NewLC(aImplementationUid);
1.51 + CleanupStack::Pop(self);
1.52 + return self;
1.53 + }
1.54 +
1.55 +CRSAKeyPairGenImpl* CRSAKeyPairGenImpl::NewLC(TUid aImplementationUid)
1.56 + {
1.57 + CRSAKeyPairGenImpl* self = new(ELeave) CRSAKeyPairGenImpl(aImplementationUid);
1.58 + CleanupStack::PushL(self);
1.59 + self->ConstructL();
1.60 + return self;
1.61 + }
1.62 +
1.63 +void CRSAKeyPairGenImpl::ConstructL(void)
1.64 + {
1.65 + CKeyPairGenImpl::ConstructL();
1.66 + }
1.67 +
1.68 +CExtendedCharacteristics* CRSAKeyPairGenImpl::CreateExtendedCharacteristicsL()
1.69 + {
1.70 + // All Symbian software plug-ins have unlimited concurrency, cannot be reserved
1.71 + // for exclusive use and are not CERTIFIED to be standards compliant.
1.72 + return CExtendedCharacteristics::NewL(KMaxTInt, EFalse);
1.73 + }
1.74 +
1.75 +const CExtendedCharacteristics* CRSAKeyPairGenImpl::GetExtendedCharacteristicsL()
1.76 + {
1.77 + return CRSAKeyPairGenImpl::CreateExtendedCharacteristicsL();
1.78 + }
1.79 +
1.80 +TUid CRSAKeyPairGenImpl::ImplementationUid() const
1.81 + {
1.82 + return iImplementationUid;
1.83 + }
1.84 +
1.85 +void CRSAKeyPairGenImpl::Reset()
1.86 + {
1.87 + // does nothing in this plugin
1.88 + }
1.89 +
1.90 +void CRSAKeyPairGenImpl::GenerateKeyPairL(TInt aKeySize, const CCryptoParams& aKeyParameters, CKeyPair*& aKeyPair)
1.91 + {
1.92 + /*
1.93 + * extract e
1.94 + */
1.95 + const TInt aKeyType = aKeyParameters.GetTIntL(KRsaKeyTypeUid);
1.96 + const TInt aPublicExponent = aKeyParameters.GetTIntL(KRsaKeyParameterEUid);
1.97 +
1.98 + RInteger e = RInteger::NewL(aPublicExponent);
1.99 + CleanupStack::PushL(e);
1.100 +
1.101 + /*
1.102 + * calculate p, q, n & d
1.103 + */
1.104 + RInteger p;
1.105 + RInteger q;
1.106 +
1.107 + //these make sure n is a least aKeySize long
1.108 + TInt pbits=(aKeySize+1)/2;
1.109 + TInt qbits=aKeySize-pbits;
1.110 +
1.111 + //generate a prime p such that GCD(e,p-1) == 1
1.112 + for (;;)
1.113 + {
1.114 + p = RInteger::NewPrimeL(pbits,TInteger::ETop2BitsSet);
1.115 + CleanupStack::PushL(p);
1.116 + --p;
1.117 +
1.118 + RInteger gcd = e.GCDL(p);
1.119 + if( gcd == 1 )
1.120 + {
1.121 + ++p;
1.122 + gcd.Close();
1.123 + //p is still on cleanup stack
1.124 + break;
1.125 + }
1.126 + CleanupStack::PopAndDestroy(&p);
1.127 + gcd.Close();
1.128 + }
1.129 +
1.130 + //generate a prime q such that GCD(e,q-1) == 1 && (p != q)
1.131 + for (;;)
1.132 + {
1.133 + q = RInteger::NewPrimeL(qbits,TInteger::ETop2BitsSet);
1.134 + CleanupStack::PushL(q);
1.135 + --q;
1.136 +
1.137 + RInteger gcd = e.GCDL(q);
1.138 + if( gcd == 1 )
1.139 + {
1.140 + ++q;
1.141 + if( p != q )
1.142 + {
1.143 + gcd.Close();
1.144 + //q is still on cleanup stack
1.145 + break;
1.146 + }
1.147 + }
1.148 + CleanupStack::PopAndDestroy(&q);
1.149 + gcd.Close();
1.150 + }
1.151 +
1.152 + //make sure p > q
1.153 + if ( p < q)
1.154 + {
1.155 + TClassSwap(p,q);
1.156 + }
1.157 +
1.158 + //calculate n = p * q
1.159 + RInteger n = p.TimesL(q);
1.160 + CleanupStack::PushL(n);
1.161 +
1.162 + --p;
1.163 + --q;
1.164 +
1.165 + //temp = (p-1)(q-1)
1.166 + RInteger temp = p.TimesL(q);
1.167 + CleanupStack::PushL(temp);
1.168 +
1.169 + //e * d = 1 mod ((p-1)(q-1))
1.170 + //d = e^(-1) mod ((p-1)(q-1))
1.171 + RInteger d = e.InverseModL(temp);
1.172 + CleanupStack::PopAndDestroy(&temp); //temp
1.173 + CleanupStack::PushL(d);
1.174 +
1.175 + /*
1.176 + * create private key depending on aKeyType
1.177 + */
1.178 + CCryptoParams* privateKeyParameters = CCryptoParams::NewLC();
1.179 + privateKeyParameters->AddL(n, KRsaKeyParameterNUid);
1.180 + TKeyProperty* privateKeyProperties = NULL;
1.181 + TKeyProperty privateKeyProperties_RsaPrivateKeyCRT = {KRSAKeyPairGeneratorUid, iImplementationUid,
1.182 + KRsaPrivateKeyCRTUid, KNonEmbeddedKeyUid };
1.183 + TKeyProperty privateKeyProperties_RsaPrivateKeyStandard = {KRSAKeyPairGeneratorUid, iImplementationUid,
1.184 + KRsaPrivateKeyStandardUid, KNonEmbeddedKeyUid };
1.185 +
1.186 + CCryptoParams*publicKeyParameters = CCryptoParams::NewLC();
1.187 + publicKeyParameters->AddL(n, KRsaKeyParameterNUid);
1.188 + publicKeyParameters->AddL(e, KRsaKeyParameterEUid);
1.189 + TKeyProperty publicKeyProperties = {KRSAKeyPairGeneratorUid, iImplementationUid,
1.190 + KRsaPublicKeyUid, KNonEmbeddedKeyUid };
1.191 +
1.192 + if (aKeyType == KRsaPrivateKeyCRT) // cleanup stack contains e, p, q, n, d and privateKeyParameters
1.193 + {
1.194 +
1.195 + /*
1.196 + * calculate dP, dQ and qInv
1.197 + */
1.198 + //calculate dP = d mod (p-1)
1.199 + RInteger dP = d.ModuloL(p); //p is still p-1
1.200 + CleanupStack::PushL(dP);
1.201 + privateKeyParameters->AddL(dP, KRsaKeyParameterDPUid);
1.202 + CleanupStack::PopAndDestroy(&dP);
1.203 +
1.204 + //calculate dQ = d mod (q-1)
1.205 + RInteger dQ = d.ModuloL(q); //q is still q-1
1.206 + CleanupStack::PushL(dQ);
1.207 + privateKeyParameters->AddL(dQ, KRsaKeyParameterDQUid);
1.208 + CleanupStack::PopAndDestroy(&dQ);
1.209 +
1.210 + ++p;
1.211 + ++q;
1.212 + //calculate inverse of qInv = q^(-1)mod(p)
1.213 + RInteger qInv = q.InverseModL(p);
1.214 + CleanupStack::PushL(qInv);
1.215 + privateKeyParameters->AddL(qInv, KRsaKeyParameterQInvUid);
1.216 + CleanupStack::PopAndDestroy(&qInv);
1.217 +
1.218 + privateKeyParameters->AddL(p, KRsaKeyParameterPUid);
1.219 + privateKeyParameters->AddL(q, KRsaKeyParameterQUid);
1.220 +
1.221 + privateKeyProperties = &privateKeyProperties_RsaPrivateKeyCRT;
1.222 + }
1.223 + else if (aKeyType == KRsaPrivateKeyStandard)
1.224 + {
1.225 + privateKeyParameters->AddL(d, KRsaKeyParameterDUid);
1.226 + privateKeyProperties = &privateKeyProperties_RsaPrivateKeyStandard;
1.227 + }
1.228 + else
1.229 + {
1.230 + User::Leave(KErrNotSupported);
1.231 + }
1.232 + // cleanup stack contains e, p, q, n, d and privateKeyParameters
1.233 + CKey* privateKey = CKey::NewL(*privateKeyProperties, *privateKeyParameters);
1.234 + CleanupStack::PushL(privateKey);
1.235 +
1.236 + /*
1.237 + * create public key
1.238 + */
1.239 + CKey* publicKey = CKey::NewL(publicKeyProperties, *publicKeyParameters);
1.240 + CleanupStack::PushL(publicKey);
1.241 +
1.242 + /*
1.243 + * create the key pair
1.244 + */
1.245 + aKeyPair = CKeyPair::NewL(publicKey, privateKey);
1.246 +
1.247 + CleanupStack::Pop(2, privateKey); //privateKey and publicKey
1.248 + CleanupStack::PopAndDestroy(7, &e); //e, p, q, n, d, privateKeyParameters and publicKeyParameters
1.249 + }