aboutsummaryrefslogtreecommitdiff
path: root/TPMCmd/tpm/src/crypt/wolf/TpmToWolfMath.c
diff options
context:
space:
mode:
Diffstat (limited to 'TPMCmd/tpm/src/crypt/wolf/TpmToWolfMath.c')
-rw-r--r--TPMCmd/tpm/src/crypt/wolf/TpmToWolfMath.c489
1 files changed, 205 insertions, 284 deletions
diff --git a/TPMCmd/tpm/src/crypt/wolf/TpmToWolfMath.c b/TPMCmd/tpm/src/crypt/wolf/TpmToWolfMath.c
index 8cbea96..8941d6b 100644
--- a/TPMCmd/tpm/src/crypt/wolf/TpmToWolfMath.c
+++ b/TPMCmd/tpm/src/crypt/wolf/TpmToWolfMath.c
@@ -36,124 +36,91 @@
//** Introduction
//
// This file contains the math functions that are not implemented in the BnMath
-// library (yet). These math functions will call the OpenSSL library to execute
+// library (yet). These math functions will call the wolfcrypt library to execute
// the operations. There is a difference between the internal format and the
-// OpenSSL format. To call the OpenSSL function, a BIGNUM structure is created
-// for each passed variable. The sizes in the bignum_t are copied and the 'd'
-// pointer in the BIGNUM is set to point to the 'd' parameter of the bignum_t.
-// On return, SetSizeOsslToTpm is used for each returned variable to make sure that
-// the pointers are not changed. The size of the returned BIGGNUM is copied to
-// bignum_t.
+// wolfcrypt format. To call the wolfcrypt function, a mp_int structure is created
+// for each passed variable. We define USE_FAST_MATH wolfcrypt option, which allocates
+// mp_int on the stack. We must copy each word to the new structure, and set the used
+// size.
+//
+// Not using USE_FAST_MATH would allow for a simple pointer swap for the big integer
+// buffer 'd', however wolfcrypt expects to manage this memory, and will swap out
+// the pointer to and from temporary variables and free the reference underneath us.
+// Using USE_FAST_MATH also instructs wolfcrypt to use the stack for all these
+// intermediate variables
+
//** Includes and Defines
#include "Tpm.h"
#if MATH_LIB == WOLF
-#include "TpmToOsslMath_fp.h"
+#include "BnConvert_fp.h"
+#include "TpmToWolfMath_fp.h"
//** Functions
-//*** OsslToTpmBn()
-// This function converts an OpenSSL BIGNUM to a TPM bignum. In this implementation
-// it is assumed that OpenSSL used the same format for a big number as does the
+//*** BnFromWolf()
+// This function converts a wolfcrypt mp_int to a TPM bignum. In this implementation
+// it is assumed that wolfcrypt used the same format for a big number as does the
// TPM -- an array of native-endian words in little-endian order.
-//
-// If the array allocated for the OpenSSL BIGNUM is not the space within the TPM
-// bignum, then the data is copied. Otherwise, just the size field of the BIGNUM
-// is copied.
void
-OsslToTpmBn(
+BnFromWolf(
bigNum bn,
- BIGNUM *osslBn
+ mp_int *wolfBn
)
{
if(bn != NULL)
{
- if((crypt_uword_t *)osslBn->d != bn->d)
- {
- int i;
- pAssert((unsigned)osslBn->top <= BnGetAllocated(bn));
- for(i = 0; i < osslBn->top; i++)
- bn->d[i] = osslBn->d[i];
- }
- BnSetTop(bn, osslBn->top);
+ int i;
+ pAssert((unsigned)wolfBn->used <= BnGetAllocated(bn));
+ for(i = 0; i < wolfBn->used; i++)
+ bn->d[i] = wolfBn->dp[i];
+
+ BnSetTop(bn, wolfBn->used);
}
}
-//*** BigInitialized()
-// This function initializes an OSSL BIGNUM from a TPM bignum.
-BIGNUM *
-BigInitialized(
- BIGNUM *toInit,
+//*** BnToWolf()
+// This function converts a TPM bignum to a wolfcrypt mp_init, and has the same
+// assumptions as made by BnFromWolf()
+void
+BnToWolf(
+ mp_int *toInit,
bigConst initializer
)
{
- if(toInit == NULL || initializer == NULL)
- return NULL;
- toInit->d = (BN_ULONG *)&initializer->d[0];
- toInit->dmax = initializer->allocated;
- toInit->top = initializer->size;
- toInit->neg = 0;
- toInit->flags = 0;
- return toInit;
+ uint32_t i;
+ if (toInit != NULL && initializer != NULL)
+ {
+ for (i = 0; i < initializer->size; i++)
+ toInit->dp[i] = initializer->d[i];
+
+ toInit->used = initializer->size;
+ toInit->sign = 0;
+ }
}
-#ifndef OSSL_DEBUG
-# define BIGNUM_PRINT(label, bn, eol)
-# define DEBUG_PRINT(x)
-#else
-# define DEBUG_PRINT(x) printf("%s", x)
-# define BIGNUM_PRINT(label, bn, eol) BIGNUM_print((label), (bn), (eol))
-static
-void BIGNUM_print(
- const char *label,
- const BIGNUM *a,
- BOOL eol
- )
+//*** MpInitialize()
+// This function initializes an wolfcrypt mp_int.
+mp_int *
+MpInitialize(
+ mp_int *toInit
+)
{
- BN_ULONG *d;
- int i;
- int notZero = FALSE;
-
- if(label != NULL)
- printf("%s", label);
- if(a == NULL)
- {
- printf("NULL");
- goto done;
- }
- if (a->neg)
- printf("-");
- for(i = a->top, d = &a->d[i - 1]; i > 0; i--)
- {
- int j;
- BN_ULONG l = *d--;
- for(j = BN_BITS2 - 8; j >= 0; j -= 8)
- {
- BYTE b = (BYTE)((l >> j) & 0xFF);
- notZero = notZero || (b != 0);
- if(notZero)
- printf("%02x", b);
- }
- if(!notZero)
- printf("0");
- }
-done:
- if(eol)
- printf("\n");
- return;
+ mp_init( toInit );
+ return toInit;
}
-#endif
#ifdef LIBRARY_COMPATIBILITY_CHECK
+//** MathLibraryCompatibililtyCheck()
+// This function is only used during development to make sure that the library
+// that is being referenced is using the same size of data structures as the TPM.
void
MathLibraryCompatibilityCheck(
void
)
{
- OSSL_ENTER();
- BIGNUM *osslTemp = BN_CTX_get(CTX);
BN_VAR(tpmTemp, 64 * 8); // allocate some space for a test value
crypt_uword_t i;
TPM2B_TYPE(TEST, 16);
@@ -163,13 +130,12 @@ MathLibraryCompatibilityCheck(
0x03, 0x02, 0x01, 0x00}}};
// Convert the test TPM2B to a bigNum
BnFrom2B(tpmTemp, &test.b);
- // Convert the test TPM2B to an OpenSSL BIGNUM
- BN_bin2bn(test.t.buffer, test.t.size, osslTemp);
+ MP_INITIALIZED(wolfTemp, tpmTemp);
+ (wolfTemp); // compiler warning
// Make sure the values are consistent
- cAssert(osslTemp->top == (int)tpmTemp->size);
+ cAssert(wolfTemp->used == (int)tpmTemp->size);
for(i = 0; i < tpmTemp->size; i++)
- cAssert(osslTemp->d[0] == tpmTemp->d[0]);
- OSSL_LEAVE();
+ cAssert(wolfTemp->d[i] == tpmTemp->d[i]);
}
#endif
@@ -183,22 +149,23 @@ BnModMult(
bigConst modulus
)
{
- OSSL_ENTER();
- BIG_INITIALIZED(bnResult, result);
- BIG_INITIALIZED(bnOp1, op1);
- BIG_INITIALIZED(bnOp2, op2);
- BIG_INITIALIZED(bnMod, modulus);
- BIG_VAR(bnTemp, (LARGEST_NUMBER_BITS * 4));
+ WOLF_ENTER();
BOOL OK;
+ MP_INITIALIZED(bnOp1, op1);
+ MP_INITIALIZED(bnOp2, op2);
+ MP_INITIALIZED(bnTemp, NULL);
+ BN_VAR(temp, LARGEST_NUMBER_BITS * 2);
+
pAssert(BnGetAllocated(result) >= BnGetSize(modulus));
- OK = BN_mul(bnTemp, bnOp1, bnOp2, CTX);
- OK = OK && BN_div(NULL, bnResult, bnTemp, bnMod, CTX);
+
+ OK = (mp_mul( bnOp1, bnOp2, bnTemp ) == MP_OKAY);
if(OK)
{
- result->size = bnResult->top;
- OsslToTpmBn(result, bnResult);
+ BnFromWolf(temp, bnTemp);
+ OK = BnDiv(NULL, result, temp, modulus);
}
- OSSL_LEAVE();
+
+ WOLF_LEAVE();
return OK;
}
@@ -211,22 +178,23 @@ BnMult(
bigConst multiplier
)
{
- OSSL_ENTER();
- BN_VAR(temp, (LARGEST_NUMBER_BITS * 2));
- BIG_INITIALIZED(bnTemp, temp);
- BIG_INITIALIZED(bnA, multiplicand);
- BIG_INITIALIZED(bnB, multiplier);
+ WOLF_ENTER();
BOOL OK;
+ MP_INITIALIZED(bnTemp, NULL);
+ MP_INITIALIZED(bnA, multiplicand);
+ MP_INITIALIZED(bnB, multiplier);
+
pAssert(result->allocated >=
(BITS_TO_CRYPT_WORDS(BnSizeInBits(multiplicand)
+ BnSizeInBits(multiplier))));
- OK = BN_mul(bnTemp, bnA, bnB, CTX);
+
+ OK = (mp_mul( bnA, bnB, bnTemp ) == MP_OKAY);
if(OK)
{
- OsslToTpmBn(temp, bnTemp);
- BnCopy(result, temp);
+ BnFromWolf(result, bnTemp);
}
- OSSL_LEAVE();
+
+ WOLF_LEAVE();
return OK;
}
@@ -241,12 +209,12 @@ BnDiv(
bigConst divisor
)
{
- OSSL_ENTER();
- BIG_INITIALIZED(bnQ, quotient);
- BIG_INITIALIZED(bnR, remainder);
- BIG_INITIALIZED(bnDend, dividend);
- BIG_INITIALIZED(bnSor, divisor);
+ WOLF_ENTER();
BOOL OK;
+ MP_INITIALIZED(bnQ, quotient);
+ MP_INITIALIZED(bnR, remainder);
+ MP_INITIALIZED(bnDend, dividend);
+ MP_INITIALIZED(bnSor, divisor);
pAssert(!BnEqualZero(divisor));
if(BnGetSize(dividend) < BnGetSize(divisor))
{
@@ -263,19 +231,15 @@ BnDiv(
- divisor->size)));
pAssert((remainder == NULL)
|| (remainder->allocated >= divisor->size));
- OK = BN_div(bnQ, bnR, bnDend, bnSor, CTX);
+ OK = (mp_div(bnDend , bnSor, bnQ, bnR) == MP_OKAY);
if(OK)
{
- OsslToTpmBn(quotient, bnQ);
- OsslToTpmBn(remainder, bnR);
+ BnFromWolf(quotient, bnQ);
+ BnFromWolf(remainder, bnR);
}
}
- DEBUG_PRINT("In BnDiv:\n");
- BIGNUM_PRINT(" bnDividend: ", bnDend, TRUE);
- BIGNUM_PRINT(" bnDivisor: ", bnSor, TRUE);
- BIGNUM_PRINT(" bnQuotient: ", bnQ, TRUE);
- BIGNUM_PRINT(" bnRemainder: ", bnR, TRUE);
- OSSL_LEAVE();
+
+ WOLF_LEAVE();
return OK;
}
@@ -289,24 +253,23 @@ BnGcd(
bigConst number2 // IN:
)
{
- OSSL_ENTER();
- BIG_INITIALIZED(bnGcd, gcd);
- BIG_INITIALIZED(bn1, number1);
- BIG_INITIALIZED(bn2, number2);
+ WOLF_ENTER();
BOOL OK;
+ MP_INITIALIZED(bnGcd, gcd);
+ MP_INITIALIZED(bn1, number1);
+ MP_INITIALIZED(bn2, number2);
pAssert(gcd != NULL);
- OK = BN_gcd(bnGcd, bn1, bn2, CTX);
+ OK = (mp_gcd( bn1, bn2, bnGcd ) == MP_OKAY);
if(OK)
{
- OsslToTpmBn(gcd, bnGcd);
- gcd->size = bnGcd->top;
+ BnFromWolf(gcd, bnGcd);
}
- OSSL_LEAVE();
+ WOLF_LEAVE();
return OK;
}
//***BnModExp()
-// Do modular exponentiation using bigNum values. The conversion from a bignum_t to
+// Do modular exponentiation using bigNum values. The conversion from a mp_int to
// a bigNum is trivial as they are based on the same structure
LIB_EXPORT BOOL
BnModExp(
@@ -316,19 +279,19 @@ BnModExp(
bigConst modulus // IN:
)
{
- OSSL_ENTER();
- BIG_INITIALIZED(bnResult, result);
- BIG_INITIALIZED(bnN, number);
- BIG_INITIALIZED(bnE, exponent);
- BIG_INITIALIZED(bnM, modulus);
+ WOLF_ENTER();
BOOL OK;
-//
- OK = BN_mod_exp(bnResult, bnN, bnE, bnM, CTX);
+ MP_INITIALIZED(bnResult, result);
+ MP_INITIALIZED(bnN, number);
+ MP_INITIALIZED(bnE, exponent);
+ MP_INITIALIZED(bnM, modulus);
+ OK = (mp_exptmod( bnN, bnE, bnM, bnResult ) == MP_OKAY);
if(OK)
{
- OsslToTpmBn(result, bnResult);
+ BnFromWolf(result, bnResult);
}
- OSSL_LEAVE();
+
+ WOLF_LEAVE();
return OK;
}
@@ -341,137 +304,70 @@ BnModInverse(
bigConst modulus
)
{
- OSSL_ENTER();
- BIG_INITIALIZED(bnResult, result);
- BIG_INITIALIZED(bnN, number);
- BIG_INITIALIZED(bnM, modulus);
- BOOL OK;
+ WOLF_ENTER();
+ BOOL OK;
+ MP_INITIALIZED(bnResult, result);
+ MP_INITIALIZED(bnN, number);
+ MP_INITIALIZED(bnM, modulus);
- OK = (BN_mod_inverse(bnResult, bnN, bnM, CTX) != NULL);
+ OK = (mp_invmod(bnN, bnM, bnResult) == MP_OKAY);
if(OK)
{
- OsslToTpmBn(result, bnResult);
+ BnFromWolf(result, bnResult);
}
- OSSL_LEAVE();
+
+ WOLF_LEAVE();
return OK;
}
#endif // TPM_ALG_RSA
#ifdef TPM_ALG_ECC
-//*** PointFromOssl()
-// Function to copy the point result from an OSSL function to a bigNum
-static BOOL
-PointFromOssl(
+//*** PointFromWolf()
+// Function to copy the point result from a wolf ecc_point to a bigNum
+void
+PointFromWolf(
bigPoint pOut, // OUT: resulting point
- EC_POINT *pIn, // IN: the point to return
- bigCurve E // IN: the curve
+ ecc_point *pIn // IN: the point to return
)
{
- BIGNUM *x = NULL;
- BIGNUM *y = NULL;
- BOOL OK;
- BN_CTX_start(E->CTX);
-//
- x = BN_CTX_get(E->CTX);
- y = BN_CTX_get(E->CTX);
+ BnFromWolf(pOut->x, pIn->x);
+ BnFromWolf(pOut->y, pIn->y);
+ BnFromWolf(pOut->z, pIn->z);
+}
- if(y == NULL)
- FAIL(FATAL_ERROR_ALLOCATION);
- // If this returns false, then the point is at infinity
- OK = EC_POINT_get_affine_coordinates_GFp(E->G, pIn, x, y, E->CTX);
- if(OK)
- {
- OsslToTpmBn(pOut->x, x);
- OsslToTpmBn(pOut->y, y);
- BnSetWord(pOut->z, 1);
- }
- else
- BnSetWord(pOut->z, 0);
- BN_CTX_end(E->CTX);
- return OK;
+//*** PointToWolf()
+// Function to copy the point result from a bigNum to a wolf ecc_point
+void
+PointToWolf(
+ ecc_point *pOut, // OUT: resulting point
+ pointConst pIn // IN: the point to return
+ )
+{
+ BnToWolf(pOut->x, pIn->x);
+ BnToWolf(pOut->y, pIn->y);
+ BnToWolf(pOut->z, pIn->z);
}
//*** EcPointInitialized()
// Allocate and initialize a point.
-static EC_POINT *
+static ecc_point *
EcPointInitialized(
- pointConst initializer,
- bigCurve E
+ pointConst initializer
)
{
- BIG_INITIALIZED(bnX, (initializer != NULL) ? initializer->x : NULL);
- BIG_INITIALIZED(bnY, (initializer != NULL) ? initializer->y : NULL);
-
- EC_POINT *P = (initializer != NULL && E != NULL)
- ? EC_POINT_new(E->G) : NULL;
- pAssert(E != NULL);
- if(P != NULL)
- EC_POINT_set_affine_coordinates_GFp(E->G, P, bnX, bnY, E->CTX);
- return P;
-}
+ ecc_point *P;
-//*** BnCurveInitialize()
-// This function initializes the OpenSSL group definition
-//
-// It is a fatal error if 'groupContext' is not provided.
-// return type: bigCurve *
-// NULL the TPM_ECC_CURVE is not valid
-// non-NULL points to a structure in 'groupContext'
-bigCurve
-BnCurveInitialize(
- bigCurve E, // IN: curve structure to initialize
- TPM_ECC_CURVE curveId // IN: curve identifier
- )
-{
- EC_GROUP *group = NULL;
- EC_POINT *P = NULL;
- const ECC_CURVE_DATA *C = GetCurveData(curveId);
- BN_CTX *CTX = NULL;
- BIG_INITIALIZED(bnP, C != NULL ? C->prime : NULL);
- BIG_INITIALIZED(bnA, C != NULL ? C->a : NULL);
- BIG_INITIALIZED(bnB, C != NULL ? C->b : NULL);
- BIG_INITIALIZED(bnX, C != NULL ? C->base.x : NULL);
- BIG_INITIALIZED(bnY, C != NULL ? C->base.y : NULL);
- BIG_INITIALIZED(bnN, C != NULL ? C->order : NULL);
- BIG_INITIALIZED(bnH, C != NULL ? C->h : NULL);
- int OK = (C != NULL);
-//
- OK = OK && ((CTX = OsslContextEnter()) != NULL);
-
- // initialize EC group, associate a generator point and initialize the point
- // from the parameter data
- // Create a group structure
- OK = OK && (group = EC_GROUP_new_curve_GFp(bnP, bnA, bnB, CTX)) != NULL;
-
- // Allocate a point in the group that will be used in setting the
- // generator. This is not needed after the generator is set.
- OK = OK && ((P = EC_POINT_new(group)) != NULL);
- // Need to use this in case Montgomery method is being used
- OK = OK
- && EC_POINT_set_affine_coordinates_GFp(group, P, bnX, bnY, CTX);
- // Now set the generator
- OK = OK && EC_GROUP_set_generator(group, P, bnN, bnH);
-
- if(P != NULL)
- EC_POINT_free(P);
-
- if(!OK && group != NULL)
+ P = wc_ecc_new_point();
+ pAssert(P != NULL);
+ // mp_int x,y,z are stack allocated.
+ // initializer is not required
+ if (P != NULL && initializer != NULL)
{
- EC_GROUP_free(group);
- group = NULL;
+ PointToWolf( P, initializer );
}
- if(!OK && CTX != NULL)
- {
- OsslContextLeave(CTX);
- CTX = NULL;
- }
-
- E->G = group;
- E->CTX = CTX;
- E->C = C;
- return OK ? E : NULL;
+ return P;
}
//*** BnEccModMult()
@@ -486,17 +382,28 @@ BnEccModMult(
bigCurve E
)
{
- EC_POINT *pR = EC_POINT_new(E->G);
- EC_POINT *pS = EcPointInitialized(S, E);
- BIG_INITIALIZED(bnD, d);
+ WOLF_ENTER();
+ BOOL OK;
+ MP_INITIALIZED(bnD, d);
+ MP_INITIALIZED(bnPrime, CurveGetPrime(E));
+ POINT_CREATE(pS, NULL);
+ POINT_CREATE(pR, NULL);
if(S == NULL)
- EC_POINT_mul(E->G, pR, bnD, NULL, NULL, E->CTX);
- else
- EC_POINT_mul(E->G, pR, NULL, pS, bnD, E->CTX);
- PointFromOssl(R, pR, E);
- EC_POINT_free(pR);
- EC_POINT_free(pS);
+ S = CurveGetG(AccessCurveData(E));
+
+ PointToWolf(pS, S);
+
+ OK = (wc_ecc_mulmod(bnD, pS, pR, NULL, bnPrime, 1 ) == MP_OKAY);
+ if(OK)
+ {
+ PointFromWolf(R, pR);
+ }
+
+ POINT_DELETE(pR);
+ POINT_DELETE(pS);
+
+ WOLF_LEAVE();
return !BnEqualZero(R->z);
}
@@ -514,28 +421,31 @@ BnEccModMult2(
bigCurve E // IN: curve
)
{
- EC_POINT *pR = EC_POINT_new(E->G);
- EC_POINT *pS = EcPointInitialized(S, E);
- BIG_INITIALIZED(bnD, d);
- EC_POINT *pQ = EcPointInitialized(Q, E);
- BIG_INITIALIZED(bnU, u);
-
- if(S == NULL || S == (pointConst)&E->C->base)
- EC_POINT_mul(E->G, pR, bnD, pQ, bnU, E->CTX);
- else
+ WOLF_ENTER();
+ BOOL OK;
+ POINT_CREATE(pR, NULL);
+ POINT_CREATE(pS, NULL);
+ POINT_CREATE(pQ, Q);
+ MP_INITIALIZED(bnD, d);
+ MP_INITIALIZED(bnU, u);
+ MP_INITIALIZED(bnPrime, CurveGetPrime(E));
+ MP_INITIALIZED(bnA, CurveGet_a(E));
+
+ if(S == NULL)
+ S = CurveGetG(AccessCurveData(E));
+ PointToWolf( pS, S );
+
+ OK = (ecc_mul2add(pS, bnD, pQ, bnU, pR, bnA, bnPrime, NULL) == MP_OKAY);
+ if(OK)
{
- const EC_POINT *points[2];
- const BIGNUM *scalars[2];
- points[0] = pS;
- points[1] = pQ;
- scalars[0] = bnD;
- scalars[1] = bnU;
- EC_POINTs_mul(E->G, pR, NULL, 2, points, scalars, E->CTX);
+ PointFromWolf(R, pR);
}
- PointFromOssl(R, pR, E);
- EC_POINT_free(pR);
- EC_POINT_free(pS);
- EC_POINT_free(pQ);
+
+ POINT_DELETE(pS);
+ POINT_DELETE(pQ);
+ POINT_DELETE(pR);
+
+ WOLF_LEAVE();
return !BnEqualZero(R->z);
}
@@ -551,16 +461,27 @@ BnEccAdd(
bigCurve E // IN: curve
)
{
- EC_POINT *pR = EC_POINT_new(E->G);
- EC_POINT *pS = EcPointInitialized(S, E);
- EC_POINT *pQ = EcPointInitialized(Q, E);
+ WOLF_ENTER();
+ BOOL OK;
+ mp_digit mp;
+ POINT_CREATE(pR, NULL);
+ POINT_CREATE(pS, S);
+ POINT_CREATE(pQ, Q);
+ MP_INITIALIZED(bnA, CurveGet_a(E));
+ MP_INITIALIZED(bnMod, CurveGetPrime(E));
//
- EC_POINT_add(E->G, pR, pS, pQ, E->CTX);
+ OK = (mp_montgomery_setup(bnMod, &mp) == MP_OKAY);
+ OK = OK && (ecc_projective_add_point(pS, pQ, pR, bnA, bnMod, mp ) == MP_OKAY);
+ if(OK)
+ {
+ PointFromWolf(R, pR);
+ }
+
+ POINT_DELETE(pS);
+ POINT_DELETE(pQ);
+ POINT_DELETE(pR);
- PointFromOssl(R, pR, E);
- EC_POINT_free(pR);
- EC_POINT_free(pS);
- EC_POINT_free(pQ);
+ WOLF_LEAVE();
return !BnEqualZero(R->z);
}