1*5c591343SA. Cody Schuffelen /* Microsoft Reference Implementation for TPM 2.0
2*5c591343SA. Cody Schuffelen *
3*5c591343SA. Cody Schuffelen * The copyright in this software is being made available under the BSD License,
4*5c591343SA. Cody Schuffelen * included below. This software may be subject to other third party and
5*5c591343SA. Cody Schuffelen * contributor rights, including patent rights, and no such rights are granted
6*5c591343SA. Cody Schuffelen * under this license.
7*5c591343SA. Cody Schuffelen *
8*5c591343SA. Cody Schuffelen * Copyright (c) Microsoft Corporation
9*5c591343SA. Cody Schuffelen *
10*5c591343SA. Cody Schuffelen * All rights reserved.
11*5c591343SA. Cody Schuffelen *
12*5c591343SA. Cody Schuffelen * BSD License
13*5c591343SA. Cody Schuffelen *
14*5c591343SA. Cody Schuffelen * Redistribution and use in source and binary forms, with or without modification,
15*5c591343SA. Cody Schuffelen * are permitted provided that the following conditions are met:
16*5c591343SA. Cody Schuffelen *
17*5c591343SA. Cody Schuffelen * Redistributions of source code must retain the above copyright notice, this list
18*5c591343SA. Cody Schuffelen * of conditions and the following disclaimer.
19*5c591343SA. Cody Schuffelen *
20*5c591343SA. Cody Schuffelen * Redistributions in binary form must reproduce the above copyright notice, this
21*5c591343SA. Cody Schuffelen * list of conditions and the following disclaimer in the documentation and/or
22*5c591343SA. Cody Schuffelen * other materials provided with the distribution.
23*5c591343SA. Cody Schuffelen *
24*5c591343SA. Cody Schuffelen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
25*5c591343SA. Cody Schuffelen * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26*5c591343SA. Cody Schuffelen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27*5c591343SA. Cody Schuffelen * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28*5c591343SA. Cody Schuffelen * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29*5c591343SA. Cody Schuffelen * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30*5c591343SA. Cody Schuffelen * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31*5c591343SA. Cody Schuffelen * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32*5c591343SA. Cody Schuffelen * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33*5c591343SA. Cody Schuffelen * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*5c591343SA. Cody Schuffelen */
35*5c591343SA. Cody Schuffelen //** Introduction
36*5c591343SA. Cody Schuffelen // This file contains the code for prime validation.
37*5c591343SA. Cody Schuffelen
38*5c591343SA. Cody Schuffelen #include "Tpm.h"
39*5c591343SA. Cody Schuffelen #include "CryptPrime_fp.h"
40*5c591343SA. Cody Schuffelen
41*5c591343SA. Cody Schuffelen //#define CPRI_PRIME
42*5c591343SA. Cody Schuffelen //#include "PrimeTable.h"
43*5c591343SA. Cody Schuffelen
44*5c591343SA. Cody Schuffelen #include "CryptPrimeSieve_fp.h"
45*5c591343SA. Cody Schuffelen
46*5c591343SA. Cody Schuffelen extern const uint32_t s_LastPrimeInTable;
47*5c591343SA. Cody Schuffelen extern const uint32_t s_PrimeTableSize;
48*5c591343SA. Cody Schuffelen extern const uint32_t s_PrimesInTable;
49*5c591343SA. Cody Schuffelen extern const unsigned char s_PrimeTable[];
50*5c591343SA. Cody Schuffelen extern bigConst s_CompositeOfSmallPrimes;
51*5c591343SA. Cody Schuffelen
52*5c591343SA. Cody Schuffelen //** Functions
53*5c591343SA. Cody Schuffelen
54*5c591343SA. Cody Schuffelen //*** Root2()
55*5c591343SA. Cody Schuffelen // This finds ceil(sqrt(n)) to use as a stopping point for searching the prime
56*5c591343SA. Cody Schuffelen // table.
57*5c591343SA. Cody Schuffelen static uint32_t
Root2(uint32_t n)58*5c591343SA. Cody Schuffelen Root2(
59*5c591343SA. Cody Schuffelen uint32_t n
60*5c591343SA. Cody Schuffelen )
61*5c591343SA. Cody Schuffelen {
62*5c591343SA. Cody Schuffelen int32_t last = (int32_t)(n >> 2);
63*5c591343SA. Cody Schuffelen int32_t next = (int32_t)(n >> 1);
64*5c591343SA. Cody Schuffelen int32_t diff;
65*5c591343SA. Cody Schuffelen int32_t stop = 10;
66*5c591343SA. Cody Schuffelen //
67*5c591343SA. Cody Schuffelen // get a starting point
68*5c591343SA. Cody Schuffelen for(; next != 0; last >>= 1, next >>= 2);
69*5c591343SA. Cody Schuffelen last++;
70*5c591343SA. Cody Schuffelen do
71*5c591343SA. Cody Schuffelen {
72*5c591343SA. Cody Schuffelen next = (last + (n / last)) >> 1;
73*5c591343SA. Cody Schuffelen diff = next - last;
74*5c591343SA. Cody Schuffelen last = next;
75*5c591343SA. Cody Schuffelen if(stop-- == 0)
76*5c591343SA. Cody Schuffelen FAIL(FATAL_ERROR_INTERNAL);
77*5c591343SA. Cody Schuffelen } while(diff < -1 || diff > 1);
78*5c591343SA. Cody Schuffelen if((n / next) > (unsigned)next)
79*5c591343SA. Cody Schuffelen next++;
80*5c591343SA. Cody Schuffelen pAssert(next != 0);
81*5c591343SA. Cody Schuffelen pAssert(((n / next) <= (unsigned)next) && (n / (next + 1) < (unsigned)next));
82*5c591343SA. Cody Schuffelen return next;
83*5c591343SA. Cody Schuffelen }
84*5c591343SA. Cody Schuffelen
85*5c591343SA. Cody Schuffelen //*** IsPrimeInt()
86*5c591343SA. Cody Schuffelen // This will do a test of a word of up to 32-bits in size.
87*5c591343SA. Cody Schuffelen BOOL
IsPrimeInt(uint32_t n)88*5c591343SA. Cody Schuffelen IsPrimeInt(
89*5c591343SA. Cody Schuffelen uint32_t n
90*5c591343SA. Cody Schuffelen )
91*5c591343SA. Cody Schuffelen {
92*5c591343SA. Cody Schuffelen uint32_t i;
93*5c591343SA. Cody Schuffelen uint32_t stop;
94*5c591343SA. Cody Schuffelen if(n < 3 || ((n & 1) == 0))
95*5c591343SA. Cody Schuffelen return (n == 2);
96*5c591343SA. Cody Schuffelen if(n <= s_LastPrimeInTable)
97*5c591343SA. Cody Schuffelen {
98*5c591343SA. Cody Schuffelen n >>= 1;
99*5c591343SA. Cody Schuffelen return ((s_PrimeTable[n >> 3] >> (n & 7)) & 1);
100*5c591343SA. Cody Schuffelen }
101*5c591343SA. Cody Schuffelen // Need to search
102*5c591343SA. Cody Schuffelen stop = Root2(n) >> 1;
103*5c591343SA. Cody Schuffelen // starting at 1 is equivalent to staring at (1 << 1) + 1 = 3
104*5c591343SA. Cody Schuffelen for(i = 1; i < stop; i++)
105*5c591343SA. Cody Schuffelen {
106*5c591343SA. Cody Schuffelen if((s_PrimeTable[i >> 3] >> (i & 7)) & 1)
107*5c591343SA. Cody Schuffelen // see if this prime evenly divides the number
108*5c591343SA. Cody Schuffelen if((n % ((i << 1) + 1)) == 0)
109*5c591343SA. Cody Schuffelen return FALSE;
110*5c591343SA. Cody Schuffelen }
111*5c591343SA. Cody Schuffelen return TRUE;
112*5c591343SA. Cody Schuffelen }
113*5c591343SA. Cody Schuffelen
114*5c591343SA. Cody Schuffelen //*** BnIsProbablyPrime()
115*5c591343SA. Cody Schuffelen // This function is used when the key sieve is not implemented. This function
116*5c591343SA. Cody Schuffelen // Will try to eliminate some of the obvious things before going on
117*5c591343SA. Cody Schuffelen // to perform MillerRabin as a final verification of primeness.
118*5c591343SA. Cody Schuffelen BOOL
BnIsProbablyPrime(bigNum prime,RAND_STATE * rand)119*5c591343SA. Cody Schuffelen BnIsProbablyPrime(
120*5c591343SA. Cody Schuffelen bigNum prime, // IN:
121*5c591343SA. Cody Schuffelen RAND_STATE *rand // IN: the random state just
122*5c591343SA. Cody Schuffelen // in case Miller-Rabin is required
123*5c591343SA. Cody Schuffelen )
124*5c591343SA. Cody Schuffelen {
125*5c591343SA. Cody Schuffelen #if RADIX_BITS > 32
126*5c591343SA. Cody Schuffelen if(BnUnsignedCmpWord(prime, UINT32_MAX) <= 0)
127*5c591343SA. Cody Schuffelen #else
128*5c591343SA. Cody Schuffelen if(BnGetSize(prime) == 1)
129*5c591343SA. Cody Schuffelen #endif
130*5c591343SA. Cody Schuffelen return IsPrimeInt((uint32_t)prime->d[0]);
131*5c591343SA. Cody Schuffelen
132*5c591343SA. Cody Schuffelen if(BnIsEven(prime))
133*5c591343SA. Cody Schuffelen return FALSE;
134*5c591343SA. Cody Schuffelen if(BnUnsignedCmpWord(prime, s_LastPrimeInTable) <= 0)
135*5c591343SA. Cody Schuffelen {
136*5c591343SA. Cody Schuffelen crypt_uword_t temp = prime->d[0] >> 1;
137*5c591343SA. Cody Schuffelen return ((s_PrimeTable[temp >> 3] >> (temp & 7)) & 1);
138*5c591343SA. Cody Schuffelen }
139*5c591343SA. Cody Schuffelen {
140*5c591343SA. Cody Schuffelen BN_VAR(n, LARGEST_NUMBER_BITS);
141*5c591343SA. Cody Schuffelen BnGcd(n, prime, s_CompositeOfSmallPrimes);
142*5c591343SA. Cody Schuffelen if(!BnEqualWord(n, 1))
143*5c591343SA. Cody Schuffelen return FALSE;
144*5c591343SA. Cody Schuffelen }
145*5c591343SA. Cody Schuffelen return MillerRabin(prime, rand);
146*5c591343SA. Cody Schuffelen }
147*5c591343SA. Cody Schuffelen
148*5c591343SA. Cody Schuffelen //*** MillerRabinRounds()
149*5c591343SA. Cody Schuffelen // Function returns the number of Miller-Rabin rounds necessary to give an
150*5c591343SA. Cody Schuffelen // error probability equal to the security strength of the prime. These values
151*5c591343SA. Cody Schuffelen // are from FIPS 186-3.
152*5c591343SA. Cody Schuffelen UINT32
MillerRabinRounds(UINT32 bits)153*5c591343SA. Cody Schuffelen MillerRabinRounds(
154*5c591343SA. Cody Schuffelen UINT32 bits // IN: Number of bits in the RSA prime
155*5c591343SA. Cody Schuffelen )
156*5c591343SA. Cody Schuffelen {
157*5c591343SA. Cody Schuffelen if(bits < 511) return 8; // don't really expect this
158*5c591343SA. Cody Schuffelen if(bits < 1536) return 5; // for 512 and 1K primes
159*5c591343SA. Cody Schuffelen return 4; // for 3K public modulus and greater
160*5c591343SA. Cody Schuffelen }
161*5c591343SA. Cody Schuffelen
162*5c591343SA. Cody Schuffelen //*** MillerRabin()
163*5c591343SA. Cody Schuffelen // This function performs a Miller-Rabin test from FIPS 186-3. It does
164*5c591343SA. Cody Schuffelen // 'iterations' trials on the number. In all likelihood, if the number
165*5c591343SA. Cody Schuffelen // is not prime, the first test fails.
166*5c591343SA. Cody Schuffelen // Return Type: BOOL
167*5c591343SA. Cody Schuffelen // TRUE(1) probably prime
168*5c591343SA. Cody Schuffelen // FALSE(0) composite
169*5c591343SA. Cody Schuffelen BOOL
MillerRabin(bigNum bnW,RAND_STATE * rand)170*5c591343SA. Cody Schuffelen MillerRabin(
171*5c591343SA. Cody Schuffelen bigNum bnW,
172*5c591343SA. Cody Schuffelen RAND_STATE *rand
173*5c591343SA. Cody Schuffelen )
174*5c591343SA. Cody Schuffelen {
175*5c591343SA. Cody Schuffelen BN_MAX(bnWm1);
176*5c591343SA. Cody Schuffelen BN_PRIME(bnM);
177*5c591343SA. Cody Schuffelen BN_PRIME(bnB);
178*5c591343SA. Cody Schuffelen BN_PRIME(bnZ);
179*5c591343SA. Cody Schuffelen BOOL ret = FALSE; // Assumed composite for easy exit
180*5c591343SA. Cody Schuffelen unsigned int a;
181*5c591343SA. Cody Schuffelen unsigned int j;
182*5c591343SA. Cody Schuffelen int wLen;
183*5c591343SA. Cody Schuffelen int i;
184*5c591343SA. Cody Schuffelen int iterations = MillerRabinRounds(BnSizeInBits(bnW));
185*5c591343SA. Cody Schuffelen //
186*5c591343SA. Cody Schuffelen INSTRUMENT_INC(MillerRabinTrials[PrimeIndex]);
187*5c591343SA. Cody Schuffelen
188*5c591343SA. Cody Schuffelen pAssert(bnW->size > 1);
189*5c591343SA. Cody Schuffelen // Let a be the largest integer such that 2^a divides w1.
190*5c591343SA. Cody Schuffelen BnSubWord(bnWm1, bnW, 1);
191*5c591343SA. Cody Schuffelen pAssert(bnWm1->size != 0);
192*5c591343SA. Cody Schuffelen
193*5c591343SA. Cody Schuffelen // Since w is odd (w-1) is even so start at bit number 1 rather than 0
194*5c591343SA. Cody Schuffelen // Get the number of bits in bnWm1 so that it doesn't have to be recomputed
195*5c591343SA. Cody Schuffelen // on each iteration.
196*5c591343SA. Cody Schuffelen i = (int)(bnWm1->size * RADIX_BITS);
197*5c591343SA. Cody Schuffelen // Now find the largest power of 2 that divides w1
198*5c591343SA. Cody Schuffelen for(a = 1;
199*5c591343SA. Cody Schuffelen (a < (bnWm1->size * RADIX_BITS)) &&
200*5c591343SA. Cody Schuffelen (BnTestBit(bnWm1, a) == 0);
201*5c591343SA. Cody Schuffelen a++);
202*5c591343SA. Cody Schuffelen // 2. m = (w1) / 2^a
203*5c591343SA. Cody Schuffelen BnShiftRight(bnM, bnWm1, a);
204*5c591343SA. Cody Schuffelen // 3. wlen = len (w).
205*5c591343SA. Cody Schuffelen wLen = BnSizeInBits(bnW);
206*5c591343SA. Cody Schuffelen // 4. For i = 1 to iterations do
207*5c591343SA. Cody Schuffelen for(i = 0; i < iterations; i++)
208*5c591343SA. Cody Schuffelen {
209*5c591343SA. Cody Schuffelen // 4.1 Obtain a string b of wlen bits from an RBG.
210*5c591343SA. Cody Schuffelen // Ensure that 1 < b < w1.
211*5c591343SA. Cody Schuffelen // 4.2 If ((b <= 1) or (b >= w1)), then go to step 4.1.
212*5c591343SA. Cody Schuffelen while(BnGetRandomBits(bnB, wLen, rand) && ((BnUnsignedCmpWord(bnB, 1) <= 0)
213*5c591343SA. Cody Schuffelen || (BnUnsignedCmp(bnB, bnWm1) >= 0)));
214*5c591343SA. Cody Schuffelen if(g_inFailureMode)
215*5c591343SA. Cody Schuffelen return FALSE;
216*5c591343SA. Cody Schuffelen
217*5c591343SA. Cody Schuffelen // 4.3 z = b^m mod w.
218*5c591343SA. Cody Schuffelen // if ModExp fails, then say this is not
219*5c591343SA. Cody Schuffelen // prime and bail out.
220*5c591343SA. Cody Schuffelen BnModExp(bnZ, bnB, bnM, bnW);
221*5c591343SA. Cody Schuffelen
222*5c591343SA. Cody Schuffelen // 4.4 If ((z == 1) or (z = w == 1)), then go to step 4.7.
223*5c591343SA. Cody Schuffelen if((BnUnsignedCmpWord(bnZ, 1) == 0)
224*5c591343SA. Cody Schuffelen || (BnUnsignedCmp(bnZ, bnWm1) == 0))
225*5c591343SA. Cody Schuffelen goto step4point7;
226*5c591343SA. Cody Schuffelen // 4.5 For j = 1 to a 1 do.
227*5c591343SA. Cody Schuffelen for(j = 1; j < a; j++)
228*5c591343SA. Cody Schuffelen {
229*5c591343SA. Cody Schuffelen // 4.5.1 z = z^2 mod w.
230*5c591343SA. Cody Schuffelen BnModMult(bnZ, bnZ, bnZ, bnW);
231*5c591343SA. Cody Schuffelen // 4.5.2 If (z = w1), then go to step 4.7.
232*5c591343SA. Cody Schuffelen if(BnUnsignedCmp(bnZ, bnWm1) == 0)
233*5c591343SA. Cody Schuffelen goto step4point7;
234*5c591343SA. Cody Schuffelen // 4.5.3 If (z = 1), then go to step 4.6.
235*5c591343SA. Cody Schuffelen if(BnEqualWord(bnZ, 1))
236*5c591343SA. Cody Schuffelen goto step4point6;
237*5c591343SA. Cody Schuffelen }
238*5c591343SA. Cody Schuffelen // 4.6 Return COMPOSITE.
239*5c591343SA. Cody Schuffelen step4point6:
240*5c591343SA. Cody Schuffelen INSTRUMENT_INC(failedAtIteration[i]);
241*5c591343SA. Cody Schuffelen goto end;
242*5c591343SA. Cody Schuffelen // 4.7 Continue. Comment: Increment i for the do-loop in step 4.
243*5c591343SA. Cody Schuffelen step4point7:
244*5c591343SA. Cody Schuffelen continue;
245*5c591343SA. Cody Schuffelen }
246*5c591343SA. Cody Schuffelen // 5. Return PROBABLY PRIME
247*5c591343SA. Cody Schuffelen ret = TRUE;
248*5c591343SA. Cody Schuffelen end:
249*5c591343SA. Cody Schuffelen return ret;
250*5c591343SA. Cody Schuffelen }
251*5c591343SA. Cody Schuffelen
252*5c591343SA. Cody Schuffelen #if ALG_RSA
253*5c591343SA. Cody Schuffelen
254*5c591343SA. Cody Schuffelen //*** RsaCheckPrime()
255*5c591343SA. Cody Schuffelen // This will check to see if a number is prime and appropriate for an
256*5c591343SA. Cody Schuffelen // RSA prime.
257*5c591343SA. Cody Schuffelen //
258*5c591343SA. Cody Schuffelen // This has different functionality based on whether we are using key
259*5c591343SA. Cody Schuffelen // sieving or not. If not, the number checked to see if it is divisible by
260*5c591343SA. Cody Schuffelen // the public exponent, then the number is adjusted either up or down
261*5c591343SA. Cody Schuffelen // in order to make it a better candidate. It is then checked for being
262*5c591343SA. Cody Schuffelen // probably prime.
263*5c591343SA. Cody Schuffelen //
264*5c591343SA. Cody Schuffelen // If sieving is used, the number is used to root a sieving process.
265*5c591343SA. Cody Schuffelen //
266*5c591343SA. Cody Schuffelen TPM_RC
RsaCheckPrime(bigNum prime,UINT32 exponent,RAND_STATE * rand)267*5c591343SA. Cody Schuffelen RsaCheckPrime(
268*5c591343SA. Cody Schuffelen bigNum prime,
269*5c591343SA. Cody Schuffelen UINT32 exponent,
270*5c591343SA. Cody Schuffelen RAND_STATE *rand
271*5c591343SA. Cody Schuffelen )
272*5c591343SA. Cody Schuffelen {
273*5c591343SA. Cody Schuffelen #if !RSA_KEY_SIEVE
274*5c591343SA. Cody Schuffelen TPM_RC retVal = TPM_RC_SUCCESS;
275*5c591343SA. Cody Schuffelen UINT32 modE = BnModWord(prime, exponent);
276*5c591343SA. Cody Schuffelen
277*5c591343SA. Cody Schuffelen NOT_REFERENCED(rand);
278*5c591343SA. Cody Schuffelen
279*5c591343SA. Cody Schuffelen if(modE == 0)
280*5c591343SA. Cody Schuffelen // evenly divisible so add two keeping the number odd
281*5c591343SA. Cody Schuffelen BnAddWord(prime, prime, 2);
282*5c591343SA. Cody Schuffelen // want 0 != (p - 1) mod e
283*5c591343SA. Cody Schuffelen // which is 1 != p mod e
284*5c591343SA. Cody Schuffelen else if(modE == 1)
285*5c591343SA. Cody Schuffelen // subtract 2 keeping number odd and insuring that
286*5c591343SA. Cody Schuffelen // 0 != (p - 1) mod e
287*5c591343SA. Cody Schuffelen BnSubWord(prime, prime, 2);
288*5c591343SA. Cody Schuffelen
289*5c591343SA. Cody Schuffelen if(BnIsProbablyPrime(prime, rand) == 0)
290*5c591343SA. Cody Schuffelen ERROR_RETURN(g_inFailureMode ? TPM_RC_FAILURE : TPM_RC_VALUE);
291*5c591343SA. Cody Schuffelen Exit:
292*5c591343SA. Cody Schuffelen return retVal;
293*5c591343SA. Cody Schuffelen #else
294*5c591343SA. Cody Schuffelen return PrimeSelectWithSieve(prime, exponent, rand);
295*5c591343SA. Cody Schuffelen #endif
296*5c591343SA. Cody Schuffelen }
297*5c591343SA. Cody Schuffelen
298*5c591343SA. Cody Schuffelen //*** RsaAdjustPrimeCandiate()
299*5c591343SA. Cody Schuffelen // For this math, we assume that the RSA numbers are fixed-point numbers with
300*5c591343SA. Cody Schuffelen // the decimal point to the "left" of the most significant bit. This approach helps
301*5c591343SA. Cody Schuffelen // make it clear what is happening with the MSb of the values.
302*5c591343SA. Cody Schuffelen // The two RSA primes have to be large enough so that their product will be a number
303*5c591343SA. Cody Schuffelen // with the necessary number of significant bits. For example, we want to be able
304*5c591343SA. Cody Schuffelen // to multiply two 1024-bit numbers to produce a number with 2028 significant bits. If
305*5c591343SA. Cody Schuffelen // we accept any 1024-bit prime that has its MSb set, then it is possible to produce a
306*5c591343SA. Cody Schuffelen // product that does not have the MSb SET. For example, if we use tiny keys of 16 bits
307*5c591343SA. Cody Schuffelen // and have two 8-bit 'primes' of 0x80, then the public key would be 0x4000 which is
308*5c591343SA. Cody Schuffelen // only 15-bits. So, what we need to do is made sure that each of the primes is large
309*5c591343SA. Cody Schuffelen // enough so that the product of the primes is twice as large as each prime. A little
310*5c591343SA. Cody Schuffelen // arithmetic will show that the only way to do this is to make sure that each of the
311*5c591343SA. Cody Schuffelen // primes is no less than root(2)/2. That's what this functions does.
312*5c591343SA. Cody Schuffelen // This function adjusts the candidate prime so that it is odd and >= root(2)/2.
313*5c591343SA. Cody Schuffelen // This allows the product of these two numbers to be .5, which, in fixed point
314*5c591343SA. Cody Schuffelen // notation means that the most significant bit is 1.
315*5c591343SA. Cody Schuffelen // For this routine, the root(2)/2 (0.7071067811865475) approximated with 0xB505
316*5c591343SA. Cody Schuffelen // which is, in fixed point, 0.7071075439453125 or an error of 0.000108%. Just setting
317*5c591343SA. Cody Schuffelen // the upper two bits would give a value > 0.75 which is an error of > 6%. Given the
318*5c591343SA. Cody Schuffelen // amount of time all the other computations take, reducing the error is not much of
319*5c591343SA. Cody Schuffelen // a cost, but it isn't totally required either.
320*5c591343SA. Cody Schuffelen //
321*5c591343SA. Cody Schuffelen // This function can be replaced with a function that just sets the two most
322*5c591343SA. Cody Schuffelen // significant bits of each prime candidate without introducing any computational
323*5c591343SA. Cody Schuffelen // issues.
324*5c591343SA. Cody Schuffelen //
325*5c591343SA. Cody Schuffelen LIB_EXPORT void
RsaAdjustPrimeCandidate(bigNum prime)326*5c591343SA. Cody Schuffelen RsaAdjustPrimeCandidate(
327*5c591343SA. Cody Schuffelen bigNum prime
328*5c591343SA. Cody Schuffelen )
329*5c591343SA. Cody Schuffelen {
330*5c591343SA. Cody Schuffelen UINT32 msw;
331*5c591343SA. Cody Schuffelen UINT32 adjusted;
332*5c591343SA. Cody Schuffelen
333*5c591343SA. Cody Schuffelen // If the radix is 32, the compiler should turn this into a simple assignment
334*5c591343SA. Cody Schuffelen msw = prime->d[prime->size - 1] >> ((RADIX_BITS == 64) ? 32 : 0);
335*5c591343SA. Cody Schuffelen // Multiplying 0xff...f by 0x4AFB gives 0xff..f - 0xB5050...0
336*5c591343SA. Cody Schuffelen adjusted = (msw >> 16) * 0x4AFB;
337*5c591343SA. Cody Schuffelen adjusted += ((msw & 0xFFFF) * 0x4AFB) >> 16;
338*5c591343SA. Cody Schuffelen adjusted += 0xB5050000UL;
339*5c591343SA. Cody Schuffelen #if RADIX_BITS == 64
340*5c591343SA. Cody Schuffelen // Save the low-order 32 bits
341*5c591343SA. Cody Schuffelen prime->d[prime->size - 1] &= 0xFFFFFFFFUL;
342*5c591343SA. Cody Schuffelen // replace the upper 32-bits
343*5c591343SA. Cody Schuffelen prime->d[prime->size -1] |= ((crypt_uword_t)adjusted << 32);
344*5c591343SA. Cody Schuffelen #else
345*5c591343SA. Cody Schuffelen prime->d[prime->size - 1] = (crypt_uword_t)adjusted;
346*5c591343SA. Cody Schuffelen #endif
347*5c591343SA. Cody Schuffelen // make sure the number is odd
348*5c591343SA. Cody Schuffelen prime->d[0] |= 1;
349*5c591343SA. Cody Schuffelen }
350*5c591343SA. Cody Schuffelen
351*5c591343SA. Cody Schuffelen //***BnGeneratePrimeForRSA()
352*5c591343SA. Cody Schuffelen // Function to generate a prime of the desired size with the proper attributes
353*5c591343SA. Cody Schuffelen // for an RSA prime.
354*5c591343SA. Cody Schuffelen TPM_RC
BnGeneratePrimeForRSA(bigNum prime,UINT32 bits,UINT32 exponent,RAND_STATE * rand)355*5c591343SA. Cody Schuffelen BnGeneratePrimeForRSA(
356*5c591343SA. Cody Schuffelen bigNum prime, // IN/OUT: points to the BN that will get the
357*5c591343SA. Cody Schuffelen // random value
358*5c591343SA. Cody Schuffelen UINT32 bits, // IN: number of bits to get
359*5c591343SA. Cody Schuffelen UINT32 exponent, // IN: the exponent
360*5c591343SA. Cody Schuffelen RAND_STATE *rand // IN: the random state
361*5c591343SA. Cody Schuffelen )
362*5c591343SA. Cody Schuffelen {
363*5c591343SA. Cody Schuffelen BOOL found = FALSE;
364*5c591343SA. Cody Schuffelen //
365*5c591343SA. Cody Schuffelen // Make sure that the prime is large enough
366*5c591343SA. Cody Schuffelen pAssert(prime->allocated >= BITS_TO_CRYPT_WORDS(bits));
367*5c591343SA. Cody Schuffelen // Only try to handle specific sizes of keys in order to save overhead
368*5c591343SA. Cody Schuffelen pAssert((bits % 32) == 0);
369*5c591343SA. Cody Schuffelen
370*5c591343SA. Cody Schuffelen prime->size = BITS_TO_CRYPT_WORDS(bits);
371*5c591343SA. Cody Schuffelen
372*5c591343SA. Cody Schuffelen while(!found)
373*5c591343SA. Cody Schuffelen {
374*5c591343SA. Cody Schuffelen // The change below is to make sure that all keys that are generated from the same
375*5c591343SA. Cody Schuffelen // seed value will be the same regardless of the endianess or word size of the CPU.
376*5c591343SA. Cody Schuffelen // DRBG_Generate(rand, (BYTE *)prime->d, (UINT16)BITS_TO_BYTES(bits));// old
377*5c591343SA. Cody Schuffelen // if(g_inFailureMode) // old
378*5c591343SA. Cody Schuffelen if(!BnGetRandomBits(prime, bits, rand)) // new
379*5c591343SA. Cody Schuffelen return TPM_RC_FAILURE;
380*5c591343SA. Cody Schuffelen RsaAdjustPrimeCandidate(prime);
381*5c591343SA. Cody Schuffelen found = RsaCheckPrime(prime, exponent, rand) == TPM_RC_SUCCESS;
382*5c591343SA. Cody Schuffelen }
383*5c591343SA. Cody Schuffelen return TPM_RC_SUCCESS;
384*5c591343SA. Cody Schuffelen }
385*5c591343SA. Cody Schuffelen
386*5c591343SA. Cody Schuffelen #endif // ALG_RSA