Update contrib.
2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
19 #include <asymmetrickeys.h>
23 #include "../common/inlines.h"
24 #include "../bigint/mont.h"
25 #include "dsakeypairshim.h"
27 const TUint SHASIZE = 20;
28 const TUint KMinPrimeLength = 512;
29 const TUint KMaxPrimeLength = 1024;
30 const TUint KPrimeLengthMultiple = 64;
34 EXPORT_C const TInteger& CDSAParameters::P(void) const
39 EXPORT_C const TInteger& CDSAParameters::Q(void) const
44 EXPORT_C const TInteger& CDSAParameters::G(void) const
49 EXPORT_C CDSAParameters::~CDSAParameters(void)
56 EXPORT_C CDSAParameters* CDSAParameters::NewL(RInteger& aP, RInteger& aQ,
59 CDSAParameters* me = new (ELeave) CDSAParameters(aP, aQ, aG);
63 EXPORT_C TBool CDSAParameters::ValidatePrimesL(const CDSAPrimeCertificate& aCert)
66 TBool result = EFalse;
69 //Regenerate primes using aCert's seed and counter
70 TUint counter = aCert.Counter();
71 if(!CDSAParameters::GeneratePrimesL(aCert.Seed(), counter, p,
72 P().BitCount(), q, ETrue))
76 //this doesn't leave, no need to push p and q
77 if(p == P() && q == Q() && counter == aCert.Counter())
86 EXPORT_C TBool CDSAParameters::ValidPrimeLength(TUint aPrimeBits)
88 return (aPrimeBits >= KMinPrimeLength &&
89 aPrimeBits <= KMaxPrimeLength &&
90 aPrimeBits % KPrimeLengthMultiple == 0);
93 EXPORT_C CDSAParameters::CDSAParameters(RInteger& aP, RInteger& aQ,
94 RInteger& aG) : iP(aP), iQ(aQ), iG(aG)
98 EXPORT_C CDSAParameters::CDSAParameters(void)
102 TBool CDSAParameters::GeneratePrimesL(const TDesC8& aSeed, TUint& aCounter,
103 RInteger& aP, TUint aL, RInteger& aQ, TBool aUseInputCounter)
105 //This follows the steps in FIPS 186-2
106 //See DSS Appendix 2.2
107 //Note. Step 1 is performed prior to calling GeneratePrimesL, so that this
108 //routine can be used for both generation and validation.
109 //Step 1. Choose an arbitrary sequence of at least 160 bits and call it
110 //SEED. Let g be the length of SEED in bits.
112 if(!CDSAParameters::ValidPrimeLength(aL))
114 User::Leave(KErrNotSupported);
117 CSHA1* sha1 = CSHA1::NewL();
118 CleanupStack::PushL(sha1);
120 HBufC8* seedBuf = aSeed.AllocLC();
121 TPtr8 seed = seedBuf->Des();
122 TUint gBytes = aSeed.Size();
123 //Note that the DSS's g = BytesToBits(gBytes) ie. the number of random bits
125 //This function has made the assumption (for ease of computation) that g%8
126 //is 0. Ie the seed is a whole number of random bytes.
129 const TUint n = (aL-1)/160;
130 const TUint b = (aL-1)%160;
131 HBufC8* Wbuf = HBufC8::NewMaxLC((n+1) * SHASIZE);
132 TUint8* W = const_cast<TUint8*>(Wbuf->Ptr());
134 U.Copy(sha1->Final(seed));
136 //Step 2. U = SHA-1[SEED] XOR SHA-1[(SEED+1) mod 2^g]
137 for(TInt i=gBytes - 1, carry=ETrue; i>=0 && carry; i--)
139 //!++(TUint) adds one to the current word which if it overflows to zero
140 //sets carry to 1 thus letting the loop continue. It's a poor man's
141 //multi-word addition. Swift eh?
142 carry = !++(seed[i]);
145 temp.Copy(sha1->Final(seed));
146 XorBuf(const_cast<TUint8*>(U.Ptr()), temp.Ptr(), SHASIZE);
148 //Step 3. Form q from U by setting the most significant bit (2^159)
149 //and the least significant bit to 1.
153 aQ = RInteger::NewL(U);
154 CleanupStack::PushL(aQ);
156 //Step 4. Use a robust primality testing algo to test if q is prime
157 //The robust part is the calling codes problem. This will use whatever
158 //random number generator you set for the thread. To attempt FIPS 186-2
159 //compliance, set a FIPS 186-2 compliant RNG.
162 //Step 5. If not exit and get a new seed
163 CleanupStack::PopAndDestroy(&aQ);
164 CleanupStack::PopAndDestroy(Wbuf);
165 CleanupStack::PopAndDestroy(seedBuf);
166 CleanupStack::PopAndDestroy(sha1);
170 TUint counterEnd = aUseInputCounter ? aCounter+1 : 4096;
172 //Step 6. Let counter = 0 and offset = 2
173 //Note 1. that the DSS speaks of SEED + offset + k because they always
174 //refer to a constant SEED. We update our seed as we go so the offset
175 //variable has already been added to seed in the previous iterations.
176 //Note 2. We've already added 1 to our seed, so the first time through this
177 //the offset in DSS speak will be 2.
178 for(TUint counter=0; counter < counterEnd; counter++)
180 //Step 7. For k=0, ..., n let
181 // Vk = SHA-1[(SEED + offset + k) mod 2^g]
182 //I'm storing the Vk's inside of a big W buffer.
183 for(TUint k=0; k<=n; k++)
185 for(TInt i=gBytes-1, carry=ETrue; i>=0 && carry; i--)
187 carry = !++(seed[i]);
189 if(!aUseInputCounter || counter == aCounter)
191 TPtr8 Wptr(W+(n-k)*SHASIZE, gBytes);
192 Wptr.Copy(sha1->Final(seed));
195 if(!aUseInputCounter || counter == aCounter)
197 //Step 8. Let W be the integer... and let X = W + 2^(L-1)
198 const_cast<TUint8&>((*Wbuf)[SHASIZE - 1 - b/8]) |= 0x80;
199 TPtr8 Wptr(W + SHASIZE - 1 - b/8, aL/8, aL/8);
200 RInteger X = RInteger::NewL(Wptr);
201 CleanupStack::PushL(X);
202 //Step 9. Let c = X mod 2q and set p = X - (c-1)
203 RInteger twoQ = aQ.TimesL(TInteger::Two());
204 CleanupStack::PushL(twoQ);
205 RInteger c = X.ModuloL(twoQ);
206 CleanupStack::PushL(c);
209 CleanupStack::PopAndDestroy(3, &X); //twoQ, c, X
210 CleanupStack::PushL(aP);
212 //Step 10 and 11: if p >= 2^(L-1) and p is prime
213 if( aP.Bit(aL-1) && aP.IsPrimeL() )
216 CleanupStack::Pop(&aP);
217 CleanupStack::Pop(&aQ);
218 CleanupStack::PopAndDestroy(Wbuf);
219 CleanupStack::PopAndDestroy(seedBuf);
220 CleanupStack::PopAndDestroy(sha1);
223 CleanupStack::PopAndDestroy(&aP);
226 CleanupStack::PopAndDestroy(&aQ);
227 CleanupStack::PopAndDestroy(Wbuf);
228 CleanupStack::PopAndDestroy(seedBuf);
229 CleanupStack::PopAndDestroy(sha1);
235 EXPORT_C CDSAPublicKey* CDSAPublicKey::NewL(RInteger& aP, RInteger& aQ,
236 RInteger& aG, RInteger& aY)
238 CDSAPublicKey* self = new(ELeave) CDSAPublicKey(aP, aQ, aG, aY);
242 EXPORT_C CDSAPublicKey* CDSAPublicKey::NewLC(RInteger& aP, RInteger& aQ,
243 RInteger& aG, RInteger& aY)
245 CDSAPublicKey* self = NewL(aP, aQ, aG, aY);
246 CleanupStack::PushL(self);
250 EXPORT_C const TInteger& CDSAPublicKey::Y(void) const
255 EXPORT_C CDSAPublicKey::CDSAPublicKey(void)
259 EXPORT_C CDSAPublicKey::CDSAPublicKey(RInteger& aP, RInteger& aQ, RInteger& aG,
260 RInteger& aY) : CDSAParameters(aP, aQ, aG), iY(aY)
264 EXPORT_C CDSAPublicKey::~CDSAPublicKey(void)
271 EXPORT_C CDSAPrivateKey* CDSAPrivateKey::NewL(RInteger& aP, RInteger& aQ,
272 RInteger& aG, RInteger& aX)
274 CDSAPrivateKey* self = new(ELeave) CDSAPrivateKey(aP, aQ, aG, aX);
278 EXPORT_C CDSAPrivateKey* CDSAPrivateKey::NewLC(RInteger& aP, RInteger& aQ,
279 RInteger& aG, RInteger& aX)
281 CDSAPrivateKey* self = NewL(aP, aQ, aG, aX);
282 CleanupStack::PushL(self);
286 EXPORT_C const TInteger& CDSAPrivateKey::X(void) const
291 EXPORT_C CDSAPrivateKey::CDSAPrivateKey(RInteger& aP, RInteger& aQ, RInteger& aG,
292 RInteger& aX) : CDSAParameters(aP, aQ, aG), iX(aX)
296 EXPORT_C CDSAPrivateKey::~CDSAPrivateKey(void)
303 EXPORT_C CDSAKeyPair* CDSAKeyPair::NewL(TUint aKeyBits)
305 CDSAKeyPairShim* self = CDSAKeyPairShim::NewLC(aKeyBits);
310 EXPORT_C CDSAKeyPair* CDSAKeyPair::NewLC(TUint aKeyBits)
312 CDSAKeyPairShim* self = CDSAKeyPairShim::NewLC(aKeyBits);
316 EXPORT_C const CDSAPublicKey& CDSAKeyPair::PublicKey(void) const
321 EXPORT_C const CDSAPrivateKey& CDSAKeyPair::PrivateKey(void) const
326 EXPORT_C CDSAKeyPair::~CDSAKeyPair(void)
330 delete iPrimeCertificate;
333 EXPORT_C CDSAKeyPair::CDSAKeyPair(void)
337 EXPORT_C const CDSAPrimeCertificate& CDSAKeyPair::PrimeCertificate(void) const
339 return *iPrimeCertificate;
342 /* CDSAPrimeCertificate */
344 EXPORT_C CDSAPrimeCertificate* CDSAPrimeCertificate::NewL(const TDesC8& aSeed,
347 CDSAPrimeCertificate* self = NewLC(aSeed, aCounter);
352 EXPORT_C CDSAPrimeCertificate* CDSAPrimeCertificate::NewLC(const TDesC8& aSeed,
355 CDSAPrimeCertificate* self = new(ELeave) CDSAPrimeCertificate(aCounter);
356 CleanupStack::PushL(self);
357 self->ConstructL(aSeed);
361 EXPORT_C const TDesC8& CDSAPrimeCertificate::Seed(void) const
366 EXPORT_C TUint CDSAPrimeCertificate::Counter(void) const
371 EXPORT_C CDSAPrimeCertificate::~CDSAPrimeCertificate(void)
373 delete const_cast<HBufC8*>(iSeed);
376 void CDSAPrimeCertificate::ConstructL(const TDesC8& aSeed)
378 iSeed = aSeed.AllocL();
381 EXPORT_C CDSAPrimeCertificate::CDSAPrimeCertificate(TUint aCounter)
386 // Over taken by shim version. so, exclude it from coverage.
387 #ifdef _BullseyeCoverage
388 #pragma suppress_warnings on
389 #pragma BullseyeCoverage off
390 #pragma suppress_warnings off
392 void CDSAKeyPair::ConstructL(TUint /*aPBits*/)
396 // Unused exported and protected method can be excluded from coverage.
397 EXPORT_C CDSAPrimeCertificate::CDSAPrimeCertificate(void)
401 EXPORT_C CDSAPrivateKey::CDSAPrivateKey(void)