| 19 |      1 | /*
 | 
|  |      2 | * Copyright (c) 2006-2009 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 | *
 | 
|  |     16 | */
 | 
|  |     17 | 
 | 
|  |     18 | 
 | 
|  |     19 | #include "dsasignerimpl.h"
 | 
|  |     20 | #include "pluginconfig.h"
 | 
|  |     21 | 
 | 
|  |     22 | using namespace SoftwareCrypto;
 | 
|  |     23 | 
 | 
|  |     24 | // Implementation of CDSASignerImpl 
 | 
|  |     25 | CDSASignerImpl* CDSASignerImpl::NewL(const CKey& aKey)
 | 
|  |     26 | 	{
 | 
|  |     27 | 	CDSASignerImpl* self = CDSASignerImpl::NewLC(aKey);
 | 
|  |     28 | 	CleanupStack::Pop(self);
 | 
|  |     29 | 	return self;
 | 
|  |     30 | 	}
 | 
|  |     31 | 	
 | 
|  |     32 | CDSASignerImpl* CDSASignerImpl::NewLC(const CKey& aKey)
 | 
|  |     33 | 	{
 | 
|  |     34 | 	CDSASignerImpl* self = new(ELeave) CDSASignerImpl();
 | 
|  |     35 | 	CleanupStack::PushL(self);
 | 
|  |     36 | 	self->ConstructL(aKey);
 | 
|  |     37 | 	return self;
 | 
|  |     38 | 	}
 | 
|  |     39 | 
 | 
|  |     40 | CDSASignerImpl::CDSASignerImpl() 
 | 
|  |     41 | 	{
 | 
|  |     42 | 	}
 | 
|  |     43 | 	
 | 
|  |     44 | CDSASignerImpl::~CDSASignerImpl()
 | 
|  |     45 | 	{
 | 
|  |     46 | 	}
 | 
|  |     47 | 	
 | 
|  |     48 | void CDSASignerImpl::ConstructL(const CKey& aKey)
 | 
|  |     49 | 	{
 | 
|  |     50 | 	CSignerImpl::ConstructL(aKey);
 | 
|  |     51 | 	}
 | 
|  |     52 | 
 | 
|  |     53 | CExtendedCharacteristics* CDSASignerImpl::CreateExtendedCharacteristicsL()
 | 
|  |     54 | 	{
 | 
|  |     55 | 	// All Symbian software plug-ins have unlimited concurrency, cannot be reserved
 | 
|  |     56 | 	// for exclusive use and are not CERTIFIED to be standards compliant.
 | 
|  |     57 | 	return CExtendedCharacteristics::NewL(KMaxTInt, EFalse);
 | 
|  |     58 | 	}
 | 
|  |     59 | 
 | 
|  |     60 | const CExtendedCharacteristics* CDSASignerImpl::GetExtendedCharacteristicsL()
 | 
|  |     61 | 	{
 | 
|  |     62 | 	return CDSASignerImpl::CreateExtendedCharacteristicsL();
 | 
|  |     63 | 	}
 | 
|  |     64 | 
 | 
|  |     65 | TUid CDSASignerImpl::ImplementationUid() const
 | 
|  |     66 | 	{
 | 
|  |     67 | 	return KCryptoPluginDsaSignerUid;
 | 
|  |     68 | 	}
 | 
|  |     69 | 	
 | 
|  |     70 | void CDSASignerImpl::SetKeyL(const CKey& aPrivateKey) 
 | 
|  |     71 | 	{
 | 
|  |     72 | 	DoSetKeyL(aPrivateKey);
 | 
|  |     73 | 	Reset();
 | 
|  |     74 | 	}
 | 
|  |     75 | 
 | 
|  |     76 | TInt CDSASignerImpl::GetMaximumInputLengthL() const 
 | 
|  |     77 | 	{
 | 
|  |     78 | 	return KSha1HashLength;
 | 
|  |     79 | 	}
 | 
|  |     80 | 
 | 
|  |     81 | void CDSASignerImpl::SignL(const TDesC8& aInput, CCryptoParams& aSignature) 
 | 
|  |     82 | 	{
 | 
|  |     83 | 	
 | 
|  |     84 | 	//see HAC 11.56 or DSS section 5
 | 
|  |     85 | 	//I'll follow HAC as I like its description better
 | 
|  |     86 | 	//We don't check that r and s are non both non-null like the DSS
 | 
|  |     87 | 	//states you _optionally_ can.  The chances of this are _incredibly_ small.
 | 
|  |     88 | 	//You've got a much better chance of a bit failure ocurring in the hardware
 | 
|  |     89 | 	//than this.
 | 
|  |     90 | 
 | 
|  |     91 | 	const TInteger& tQ=iKey->GetBigIntL(KDsaKeyParameterQUid);
 | 
|  |     92 | 		
 | 
|  |     93 | 	// a) Select a random secret integer (k | 0 < k < q)
 | 
|  |     94 | 	RInteger qminus1 = RInteger::NewL(tQ);
 | 
|  |     95 | 	CleanupStack::PushL(qminus1);
 | 
|  |     96 | 	--qminus1;
 | 
|  |     97 | 	RInteger k = RInteger::NewRandomL(TInteger::One(), qminus1);
 | 
|  |     98 | 	CleanupStack::PopAndDestroy(&qminus1);
 | 
|  |     99 | 	CleanupStack::PushL(k);
 | 
|  |    100 | 	
 | 
|  |    101 | 	
 | 
|  |    102 | 	// b) compute r = (g^k mod p) mod q
 | 
|  |    103 | 	
 | 
|  |    104 | 	const TInteger& tG=iKey->GetBigIntL(KDsaKeyParameterGUid);
 | 
|  |    105 | 	const TInteger& tP=iKey->GetBigIntL(KDsaKeyParameterPUid);
 | 
|  |    106 | 	RInteger r = TInteger::ModularExponentiateL(tG, k, tP);
 | 
|  |    107 | 	CleanupStack::PushL(r);
 | 
|  |    108 | 	r %=tQ;
 | 
|  |    109 | 	
 | 
|  |    110 | 	
 | 
|  |    111 | 	// c) compute k^(-1) mod q
 | 
|  |    112 | 
 | 
|  |    113 | 	RInteger kinv = k.InverseModL(tQ);
 | 
|  |    114 | 	CleanupStack::PushL(kinv);
 | 
|  |    115 | 
 | 
|  |    116 | 
 | 
|  |    117 | 	// d) compute s = k^(-1) * {h(m) + xr} mod q
 | 
|  |    118 | 	// Note that in order to be interoperable, compliant with the DSS, and
 | 
|  |    119 | 	// secure, aInput must be the result of a SHA-1 hash
 | 
|  |    120 | 
 | 
|  |    121 | 	RInteger hm = RInteger::NewL(aInput);
 | 
|  |    122 | 	CleanupStack::PushL(hm);
 | 
|  |    123 | 	
 | 
|  |    124 | 	const TInteger& tX=iKey->GetBigIntL(KDsaKeyParameterXUid);	
 | 
|  |    125 | 	RInteger s = tX.TimesL(r);
 | 
|  |    126 | 	CleanupStack::PushL(s);
 | 
|  |    127 | 	s += hm;
 | 
|  |    128 | 	s *= kinv;
 | 
|  |    129 | 	s %= tQ;
 | 
|  |    130 | 
 | 
|  |    131 | 
 | 
|  |    132 | 	// e) signature for m is the pair (r,s)
 | 
|  |    133 | 	aSignature.AddL(r, KDsaSignatureParameterRUid);
 | 
|  |    134 | 	aSignature.AddL(s, KDsaSignatureParameterSUid);
 | 
|  |    135 | 	
 | 
|  |    136 | 	CleanupStack::PopAndDestroy(5, &k);
 | 
|  |    137 | 	}
 |