xref: /aosp_15_r20/external/ms-tpm-20-ref/TPMCmd/tpm/src/crypt/CryptPrime.c (revision 5c591343844d1f9da7da26467c4bf7efc8a7a413)
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