From b4ff6345a6b1533f907ed1922d884acae62d2501 Mon Sep 17 00:00:00 2001
From: jiangfangjie 00559066 <jiangfangjie@huawei.com>
Date: Tue, 11 May 2021 11:52:44 +0800
Subject: [PATCH 4/7] tpm2: rev155: Add new RsaAdjustPrimeCandidate code  but
 do not use

Add in the new RsaAdjustPrimeCandidate() function but do not use it
so far since it creates slightly different primes than the previous
code and we would get different derived keys if we were to use it with
'old' seeds.

Adjust the code to return the same results for 64 bit and 32 bit machines.
---
 src/tpm2/crypto/openssl/CryptPrime.c | 110 ++++++++++++++++++++++-----
 1 file changed, 89 insertions(+), 21 deletions(-)

diff --git a/src/tpm2/crypto/openssl/CryptPrime.c b/src/tpm2/crypto/openssl/CryptPrime.c
index 662c762..9a5ee7d 100644
--- a/src/tpm2/crypto/openssl/CryptPrime.c
+++ b/src/tpm2/crypto/openssl/CryptPrime.c
@@ -3,7 +3,7 @@
 /*			    Code for prime validation. 				*/
 /*			     Written by Ken Goldman				*/
 /*		       IBM Thomas J. Watson Research Center			*/
-/*            $Id: CryptPrime.c 1262 2018-07-11 21:03:43Z kgoldman $		*/
+/*            $Id: CryptPrime.c 1476 2019-06-10 19:32:03Z kgoldman $		*/
 /*										*/
 /*  Licenses and Notices							*/
 /*										*/
@@ -55,7 +55,7 @@
 /*    arising in any way out of use or reliance upon this specification or any 	*/
 /*    information herein.							*/
 /*										*/
-/*  (c) Copyright IBM Corp. and others, 2016 - 2018				*/
+/*  (c) Copyright IBM Corp. and others, 2016 - 2019				*/
 /*										*/
 /********************************************************************************/
 
@@ -292,19 +292,14 @@ RsaCheckPrime(
     return PrimeSelectWithSieve(prime, exponent, rand);
 #endif
 }
-/* 10.2.16.1.7 AdjustPrimeCandiate() */
-/* This function adjusts the candidate prime so that it is odd and > root(2)/2. This allows the
-   product of these two numbers to be .5, which, in fixed point notation means that the most
-   significant bit is 1. For this routine, the root(2)/2 is approximated with 0xB505 which is, in
-   fixed point is 0.7071075439453125 or an error of 0.0001%. Just setting the upper two bits would
-   give a value > 0.75 which is an error of > 6%. Given the amount of time all the other
-   computations take, reducing the error is not much of a cost, but it isn't totally required
-   either. */
-/* The function also puts the number on a field boundary. */
-LIB_EXPORT void
-RsaAdjustPrimeCandidate(
-			bigNum          prime
-			)
+/*
+ * RsaAdjustPrimeCandidate_PreRev155 is the pre-rev.155 algorithm used; we
+ * still have to use it for old seeds to maintain backwards compatibility.
+ */
+static void
+RsaAdjustPrimeCandidate_PreRev155(
+                            bigNum      prime
+                           )
 {
     UINT16  highBytes;
     crypt_uword_t       *msw = &prime->d[prime->size - 1];
@@ -316,14 +311,74 @@ RsaAdjustPrimeCandidate(
     *msw = ((crypt_uword_t)(highBytes) << (RADIX_BITS - 16)) + (*msw & MASK);
     prime->d[0] |= 1;
 }
-/* 10.2.16.1.8 BnGeneratePrimeForRSA() */
+
+/* 10.2.14.1.7 RsaAdjustPrimeCandidate() */
+
+/* For this math, we assume that the RSA numbers are fixed-point numbers with the decimal point to
+   the left of the most significant bit. This approach helps make it clear what is happening with
+   the MSb of the values. The two RSA primes have to be large enough so that their product will be a
+   number with the necessary number of significant bits. For example, we want to be able to multiply
+   two 1024-bit numbers to produce a number with 2028 significant bits. If we accept any 1024-bit
+   prime that has its MSb set, then it is possible to produce a product that does not have the MSb
+   SET. For example, if we use tiny keys of 16 bits and have two 8-bit primes of 0x80, then the
+   public key would be 0x4000 which is only 15-bits. So, what we need to do is made sure that each
+   of the primes is large enough so that the product of the primes is twice as large as each
+   prime. A little arithmetic will show that the only way to do this is to make sure that each of
+   the primes is no less than root(2)/2. That's what this functions does. This function adjusts the
+   candidate prime so that it is odd and >= root(2)/2. This allows the product of these two numbers
+   to be .5, which, in fixed point notation means that the most significant bit is 1. For this
+   routine, the root(2)/2 (0.7071067811865475) approximated with 0xB505 which is, in fixed point,
+   0.7071075439453125 or an error of 0.000108%. Just setting the upper two bits would give a value >
+   0.75 which is an error of > 6%. Given the amount of time all the other computations take,
+   reducing the error is not much of a cost, but it isn't totally required either. */
+/* This function can be replaced with a function that just sets the two most significant bits of
+   each prime candidate without introducing any computational issues. */
+
+static void
+RsaAdjustPrimeCandidate_New(
+			    bigNum          prime
+			   )
+{
+    UINT32          msw;
+    UINT32          adjusted;
+    
+    // If the radix is 32, the compiler should turn this into a simple assignment
+    msw = prime->d[prime->size - 1] >> ((RADIX_BITS == 64) ? 32 : 0);
+    // Multiplying 0xff...f by 0x4AFB gives 0xff..f - 0xB5050...0
+    adjusted = (msw >> 16) * 0x4AFB;
+    adjusted += ((msw & 0xFFFF) * 0x4AFB) >> 16;
+    adjusted += 0xB5050000UL;
+#if RADIX_BITS == 64
+    // Save the low-order 32 bits
+    prime->d[prime->size - 1] &= 0xFFFFFFFFUL;
+    // replace the upper 32-bits
+    prime->d[prime->size -1] |= ((crypt_uword_t)adjusted << 32);
+#else
+    prime->d[prime->size - 1] = (crypt_uword_t)adjusted;
+#endif
+    // make sure the number is odd
+    prime->d[0] |= 1;
+}
+LIB_EXPORT void
+RsaAdjustPrimeCandidate(
+			bigNum          prime
+			)
+{
+    if (1)
+        RsaAdjustPrimeCandidate_PreRev155(prime);
+    else
+        RsaAdjustPrimeCandidate_New(prime);
+}
+/* 10.2.14.1.8 BnGeneratePrimeForRSA() */
+
 /* Function to generate a prime of the desired size with the proper attributes for an RSA prime. */
 void
 BnGeneratePrimeForRSA(
-		      bigNum          prime,
-		      UINT32          bits,
-		      UINT32          exponent,
-		      RAND_STATE      *rand
+		      bigNum          prime,            // IN/OUT: points to the BN that will get the
+			  // random value
+		      UINT32          bits,             // IN: number of bits to get             
+		      UINT32          exponent,         // IN: the exponent
+		      RAND_STATE      *rand             // IN: the random state
 		      )
 {
     BOOL            found = FALSE;
@@ -335,8 +390,21 @@ BnGeneratePrimeForRSA(
     prime->size = BITS_TO_CRYPT_WORDS(bits);
     while(!found)
 	{
-	    DRBG_Generate(rand, (BYTE *)prime->d, (UINT16)BITS_TO_BYTES(bits));
+        // The change below is to make sure that all keys that are generated from the same
+	    // seed value will be the same regardless of the endianess or word size of the CPU.
+	    //       DRBG_Generate(rand, (BYTE *)prime->d, (UINT16)BITS_TO_BYTES(bits));// old
+	    //       if(g_inFailureMode)                                                // old
+	// libtpms changed begin
+	    if (1) {
+		DRBG_Generate(rand, (BYTE *)prime->d, (UINT16)BITS_TO_BYTES(bits));
+		if (g_inFailureMode)
+		    return;
+	    } else {
+		if(!BnGetRandomBits(prime, bits, rand))                              // new
+		    return;
+	    }
 	    RsaAdjustPrimeCandidate(prime);
+	// libtpms changed end
 	    found = RsaCheckPrime(prime, exponent, rand) == TPM_RC_SUCCESS;
 	}
 }
-- 
2.21.0.windows.1

