sl@0: /* sl@0: * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: #include "dsasignerimpl.h" sl@0: #include "pluginconfig.h" sl@0: sl@0: using namespace SoftwareCrypto; sl@0: sl@0: // Implementation of CDSASignerImpl sl@0: CDSASignerImpl* CDSASignerImpl::NewL(const CKey& aKey) sl@0: { sl@0: CDSASignerImpl* self = CDSASignerImpl::NewLC(aKey); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: CDSASignerImpl* CDSASignerImpl::NewLC(const CKey& aKey) sl@0: { sl@0: CDSASignerImpl* self = new(ELeave) CDSASignerImpl(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aKey); sl@0: return self; sl@0: } sl@0: sl@0: CDSASignerImpl::CDSASignerImpl() sl@0: { sl@0: } sl@0: sl@0: CDSASignerImpl::~CDSASignerImpl() sl@0: { sl@0: } sl@0: sl@0: void CDSASignerImpl::ConstructL(const CKey& aKey) sl@0: { sl@0: CSignerImpl::ConstructL(aKey); sl@0: } sl@0: sl@0: CExtendedCharacteristics* CDSASignerImpl::CreateExtendedCharacteristicsL() sl@0: { sl@0: // All Symbian software plug-ins have unlimited concurrency, cannot be reserved sl@0: // for exclusive use and are not CERTIFIED to be standards compliant. sl@0: return CExtendedCharacteristics::NewL(KMaxTInt, EFalse); sl@0: } sl@0: sl@0: const CExtendedCharacteristics* CDSASignerImpl::GetExtendedCharacteristicsL() sl@0: { sl@0: return CDSASignerImpl::CreateExtendedCharacteristicsL(); sl@0: } sl@0: sl@0: TUid CDSASignerImpl::ImplementationUid() const sl@0: { sl@0: return KCryptoPluginDsaSignerUid; sl@0: } sl@0: sl@0: void CDSASignerImpl::SetKeyL(const CKey& aPrivateKey) sl@0: { sl@0: DoSetKeyL(aPrivateKey); sl@0: Reset(); sl@0: } sl@0: sl@0: TInt CDSASignerImpl::GetMaximumInputLengthL() const sl@0: { sl@0: return KSha1HashLength; sl@0: } sl@0: sl@0: void CDSASignerImpl::SignL(const TDesC8& aInput, CCryptoParams& aSignature) sl@0: { sl@0: sl@0: //see HAC 11.56 or DSS section 5 sl@0: //I'll follow HAC as I like its description better sl@0: //We don't check that r and s are non both non-null like the DSS sl@0: //states you _optionally_ can. The chances of this are _incredibly_ small. sl@0: //You've got a much better chance of a bit failure ocurring in the hardware sl@0: //than this. sl@0: sl@0: const TInteger& tQ=iKey->GetBigIntL(KDsaKeyParameterQUid); sl@0: sl@0: // a) Select a random secret integer (k | 0 < k < q) sl@0: RInteger qminus1 = RInteger::NewL(tQ); sl@0: CleanupStack::PushL(qminus1); sl@0: --qminus1; sl@0: RInteger k = RInteger::NewRandomL(TInteger::One(), qminus1); sl@0: CleanupStack::PopAndDestroy(&qminus1); sl@0: CleanupStack::PushL(k); sl@0: sl@0: sl@0: // b) compute r = (g^k mod p) mod q sl@0: sl@0: const TInteger& tG=iKey->GetBigIntL(KDsaKeyParameterGUid); sl@0: const TInteger& tP=iKey->GetBigIntL(KDsaKeyParameterPUid); sl@0: RInteger r = TInteger::ModularExponentiateL(tG, k, tP); sl@0: CleanupStack::PushL(r); sl@0: r %=tQ; sl@0: sl@0: sl@0: // c) compute k^(-1) mod q sl@0: sl@0: RInteger kinv = k.InverseModL(tQ); sl@0: CleanupStack::PushL(kinv); sl@0: sl@0: sl@0: // d) compute s = k^(-1) * {h(m) + xr} mod q sl@0: // Note that in order to be interoperable, compliant with the DSS, and sl@0: // secure, aInput must be the result of a SHA-1 hash sl@0: sl@0: RInteger hm = RInteger::NewL(aInput); sl@0: CleanupStack::PushL(hm); sl@0: sl@0: const TInteger& tX=iKey->GetBigIntL(KDsaKeyParameterXUid); sl@0: RInteger s = tX.TimesL(r); sl@0: CleanupStack::PushL(s); sl@0: s += hm; sl@0: s *= kinv; sl@0: s %= tQ; sl@0: sl@0: sl@0: // e) signature for m is the pair (r,s) sl@0: aSignature.AddL(r, KDsaSignatureParameterRUid); sl@0: aSignature.AddL(s, KDsaSignatureParameterSUid); sl@0: sl@0: CleanupStack::PopAndDestroy(5, &k); sl@0: }