/*
* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
#include "dhkeypairgenimpl.h"
#include "pluginconfig.h"
#include "keypair.h"
using namespace SoftwareCrypto;
using namespace CryptoSpi;
/* CDHKeyPairGenImpl */
CDHKeyPairGenImpl::CDHKeyPairGenImpl()
{
}
CDHKeyPairGenImpl::~CDHKeyPairGenImpl()
{
}
CDHKeyPairGenImpl* CDHKeyPairGenImpl::NewL(void)
{
CDHKeyPairGenImpl* self = CDHKeyPairGenImpl::NewLC();
CleanupStack::Pop(self);
return self;
}
CDHKeyPairGenImpl* CDHKeyPairGenImpl::NewLC(void)
{
CDHKeyPairGenImpl* self = new(ELeave) CDHKeyPairGenImpl();
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
void CDHKeyPairGenImpl::ConstructL(void)
{
CKeyPairGenImpl::ConstructL();
}
CExtendedCharacteristics* CDHKeyPairGenImpl::CreateExtendedCharacteristicsL()
{
// All Symbian software plug-ins have unlimited concurrency, cannot be reserved
// for exclusive use and are not CERTIFIED to be standards compliant.
return CExtendedCharacteristics::NewL(KMaxTInt, EFalse);
}
const CExtendedCharacteristics* CDHKeyPairGenImpl::GetExtendedCharacteristicsL()
{
return CDHKeyPairGenImpl::CreateExtendedCharacteristicsL();
}
TUid CDHKeyPairGenImpl::ImplementationUid() const
{
return KCryptoPluginDhKeyPairGenUid;
}
void CDHKeyPairGenImpl::Reset()
{
// does nothing in this plugin
}
void CDHKeyPairGenImpl::GenerateKeyPairL(TInt /*aKeySize*/, const CCryptoParams& aKeyParameters, CKeyPair*& aKeyPair)
{
/*
* unpack the parameters, we're expecting the N and G parameters and if present the x parameter (aka private key)
*/
const TInteger& N = aKeyParameters.GetBigIntL(KDhKeyParameterNUid);
const TInteger& G = aKeyParameters.GetBigIntL(KDhKeyParameterGUid);
/*
* do some sanity checking
*/
RInteger nminus2 = RInteger::NewL(N);
CleanupStack::PushL(nminus2);
--nminus2;
--nminus2;
if ((G < TInteger::Two()) || (G > nminus2))
{
User::Leave(KErrArgument);
}
/*
* has a private key x been supplied? if not then generate it
*/
RInteger x;
if (aKeyParameters.IsPresent(KDhKeyParameterxUid))
{
x = RInteger::NewL(aKeyParameters.GetBigIntL(KDhKeyParameterxUid));
}
else
{
// find a random x | 1 <= x <= n-2
x = RInteger::NewRandomL(TInteger::One(), nminus2);
}
CleanupClosePushL(x);
/*
* generate the public key with X = G^(x) mod N
*/
RInteger X = TInteger::ModularExponentiateL(G, x, N);
CleanupClosePushL(X);
/*
* create the keys parameters
*/
CCryptoParams* publicKeyParameters = CCryptoParams::NewLC();
publicKeyParameters->AddL(X, KDhKeyParameterXUid);
TKeyProperty publicKeyProperties = {KDHKeyPairGeneratorUid, KCryptoPluginDhKeyPairGenUid,
KDHPublicKeyUid, KNonEmbeddedKeyUid };
CCryptoParams* privateKeyParameters = CCryptoParams::NewLC();
privateKeyParameters->AddL(x, KDhKeyParameterxUid);
TKeyProperty privateKeyProperties = {KDHKeyPairGeneratorUid, KCryptoPluginDhKeyPairGenUid,
KDHPrivateKeyUid, KNonEmbeddedKeyUid };
/*
* create the public key
*/
CKey* publicKey = CKey::NewL(publicKeyProperties, *publicKeyParameters);
CleanupStack::PushL(publicKey);
/*
* create the private key
*/
CKey* privateKey = CKey::NewL(privateKeyProperties, *privateKeyParameters);
CleanupStack::PushL(privateKey);
/*
* create the key pair
*/
aKeyPair = CKeyPair::NewL(publicKey, privateKey);
/*
* cleanup stack - it should contain nminus2, x (if allocated here), X, publicKeyParameters, privateKeyParameters, publicKey and privateKey
*/
CleanupStack::Pop(2, publicKey);
CleanupStack::PopAndDestroy(5, &nminus2);
}