diff options
Diffstat (limited to 'src/tpm2/crypto/openssl/TpmToOsslMath.c')
-rw-r--r-- | src/tpm2/crypto/openssl/TpmToOsslMath.c | 736 |
1 files changed, 736 insertions, 0 deletions
diff --git a/src/tpm2/crypto/openssl/TpmToOsslMath.c b/src/tpm2/crypto/openssl/TpmToOsslMath.c new file mode 100644 index 0000000..18e6c23 --- /dev/null +++ b/src/tpm2/crypto/openssl/TpmToOsslMath.c @@ -0,0 +1,736 @@ +/********************************************************************************/ +/* */ +/* TPM to OpenSSL BigNum Shim Layer */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* $Id: TpmToOsslMath.c 1598 2020-03-27 21:59:49Z kgoldman $ */ +/* */ +/* Licenses and Notices */ +/* */ +/* 1. Copyright Licenses: */ +/* */ +/* - Trusted Computing Group (TCG) grants to the user of the source code in */ +/* this specification (the "Source Code") a worldwide, irrevocable, */ +/* nonexclusive, royalty free, copyright license to reproduce, create */ +/* derivative works, distribute, display and perform the Source Code and */ +/* derivative works thereof, and to grant others the rights granted herein. */ +/* */ +/* - The TCG grants to the user of the other parts of the specification */ +/* (other than the Source Code) the rights to reproduce, distribute, */ +/* display, and perform the specification solely for the purpose of */ +/* developing products based on such documents. */ +/* */ +/* 2. Source Code Distribution Conditions: */ +/* */ +/* - Redistributions of Source Code must retain the above copyright licenses, */ +/* this list of conditions and the following disclaimers. */ +/* */ +/* - Redistributions in binary form must reproduce the above copyright */ +/* licenses, this list of conditions and the following disclaimers in the */ +/* documentation and/or other materials provided with the distribution. */ +/* */ +/* 3. Disclaimers: */ +/* */ +/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */ +/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */ +/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */ +/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */ +/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */ +/* information on specification licensing rights available through TCG */ +/* membership agreements. */ +/* */ +/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */ +/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */ +/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */ +/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */ +/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */ +/* */ +/* - Without limitation, TCG and its members and licensors disclaim all */ +/* liability, including liability for infringement of any proprietary */ +/* rights, relating to use of information in this specification and to the */ +/* implementation of this specification, and TCG disclaims all liability for */ +/* cost of procurement of substitute goods or services, lost profits, loss */ +/* of use, loss of data or any incidental, consequential, direct, indirect, */ +/* or special damages, whether under contract, tort, warranty or otherwise, */ +/* arising in any way out of use or reliance upon this specification or any */ +/* information herein. */ +/* */ +/* (c) Copyright IBM Corp. and others, 2016 - 2020 */ +/* */ +/********************************************************************************/ + +/* B.2.3.2. TpmToOsslMath.c */ +/* B.2.3.2.1. Introduction */ + +/* The functions in this file provide the low-level interface between the TPM code and the big + number and elliptic curve math routines in OpenSSL. */ +/* Most math on big numbers require a context. The context contains the memory in which OpenSSL + creates and manages the big number values. When a OpenSSL math function will be called that + modifies a BIGNUM value, that value must be created in an OpenSSL context. The first line of code + in such a function must be: OSSL_ENTER(); and the last operation before returning must be + OSSL_LEAVE(). OpenSSL variables can then be created with BnNewVariable(). Constant values to be + used by OpenSSL are created from the bigNum values passed to the functions in this file. Space + for the BIGNUM control block is allocated in the stack of the function and then it is initialized + by calling BigInitialized(). That function sets up the values in the BIGNUM structure and sets + the data pointer to point to the data in the bignum_t. This is only used when the value is known + to be a constant in the called function. */ +/* Because the allocations of constants is on the local stack and the OSSL_ENTER()/OSSL_LEAVE() pair + flushes everything created in OpenSSL memory, there should be no chance of a memory leak. */ + + +#include "Tpm.h" +#ifdef MATH_LIB_OSSL +#include "TpmToOsslMath_fp.h" + +/* B.2.3.2.3.1. OsslToTpmBn() */ +/* This function converts an OpenSSL BIGNUM to a TPM bignum. In this implementation it is assumed + that OpenSSL uses a different control structure but the same data layout -- an array of + native-endian words in little-endian order. */ +/* Return Value Meaning */ +/* TRUE(1) success */ +/* FALSE(0) failure because value will not fit or OpenSSL variable doesn't exist */ +BOOL +OsslToTpmBn( + bigNum bn, + const BIGNUM *osslBn // libtpms: added 'const' + ) +{ + VERIFY(osslBn != NULL); + // If the bn is NULL, it means that an output value pointer was NULL meaning that + // the results is simply to be discarded. + unsigned char buffer[LARGEST_NUMBER + 1]; // libtpms added + int buffer_len; // libtpms added + + if(bn != NULL) + { +#if 1 //libtpms added begin + int num_bytes; + + num_bytes = BN_num_bytes(osslBn); + VERIFY(num_bytes >= 0 && sizeof(buffer) >= (size_t)num_bytes); + buffer_len = BN_bn2bin(osslBn, buffer); /* ossl to bin */ + BnFromBytes(bn, buffer, buffer_len); /* bin to TPM */ +#else // libtpms added end + int i; + // + VERIFY((unsigned)osslBn->top <= BnGetAllocated(bn)); + for(i = 0; i < osslBn->top; i++) + bn->d[i] = osslBn->d[i]; + BnSetTop(bn, osslBn->top); +#endif // libtpms added + } + return TRUE; + Error: + return FALSE; +} + +/* B.2.3.2.3.2. BigInitialized() */ +/* This function initializes an OSSL BIGNUM from a TPM bigConst. Do not use this for values that are + passed to OpenSLL when they are not declared as const in the function prototype. Instead, use + BnNewVariable(). */ +BIGNUM * +BigInitialized( + BIGNUM *toInit, + bigConst initializer + ) +{ +#if 1 // libtpms added begin + BIGNUM *_toInit; + unsigned char buffer[LARGEST_NUMBER + 1]; + NUMBYTES buffer_len = (NUMBYTES )sizeof(buffer); +#endif // libtpms added end + + if(initializer == NULL) + FAIL(FATAL_ERROR_PARAMETER); + if(toInit == NULL || initializer == NULL) + return NULL; + +#if 1 // libtpms added begin + BnToBytes(initializer, buffer, &buffer_len); /* TPM to bin */ + _toInit = BN_bin2bn(buffer, buffer_len, NULL); /* bin to ossl */ + BN_set_flags(_toInit, BN_FLG_CONSTTIME); + BN_copy(toInit, _toInit); + BN_clear_free(_toInit); +#else // libtpms added end + toInit->d = (BN_ULONG *)&initializer->d[0]; + toInit->dmax = (int)initializer->allocated; + toInit->top = (int)initializer->size; + toInit->neg = 0; + toInit->flags = 0; +#endif + return toInit; +} + +#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 + ) +{ + 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; +} +#endif + +/* B.2.3.2.3.4. BnNewVariable() */ +/* This function allocates a new variable in the provided context. If the context does not exist or + the allocation fails, it is a catastrophic failure. */ +static BIGNUM * +BnNewVariable( + BN_CTX *CTX + ) +{ + BIGNUM *new; + // + // This check is intended to protect against calling this function without + // having initialized the CTX. + if((CTX == NULL) || ((new = BN_CTX_get(CTX)) == NULL)) + FAIL(FATAL_ERROR_ALLOCATION); + return new; +} + +#if LIBRARY_COMPATIBILITY_CHECK + +BOOL +MathLibraryCompatibilityCheck( + void + ) +{ + OSSL_ENTER(); + BIGNUM *osslTemp = BnNewVariable(CTX); +#if 0 + crypt_uword_t i; +#endif + BYTE test[] = {0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, + 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00}; + BN_VAR(tpmTemp, sizeof(test) * 8); // allocate some space for a test value + // + // Convert the test data to a bigNum + BnFromBytes(tpmTemp, test, sizeof(test)); + // Convert the test data to an OpenSSL BIGNUM + BN_bin2bn(test, sizeof(test), osslTemp); + // Make sure the values are consistent +#if 0 + VERIFY(osslTemp->top == (int)tpmTemp->size); + for(i = 0; i < tpmTemp->size; i++) + VERIFY(osslTemp->d[i] == tpmTemp->d[i]); +#endif + OSSL_LEAVE(); + return 1; +#if 0 + Error: + return 0; +#endif +} + +#endif + +/* B.2.3.2.3.3. BnModMult() */ +/* Does multiply and divide returning the remainder of the divide. */ +/* Return Value Meaning */ +/* TRUE(1) success */ +/* FALSE(0) failure in operation */ + +LIB_EXPORT BOOL +BnModMult( + bigNum result, + bigConst op1, + bigConst op2, + bigConst modulus + ) +{ + OSSL_ENTER(); + BOOL OK = TRUE; + BIGNUM *bnResult = BN_NEW(); + BIGNUM *bnTemp = BN_NEW(); + BIG_INITIALIZED(bnOp1, op1); + BIG_INITIALIZED(bnOp2, op2); + BIG_INITIALIZED(bnMod, modulus); + // + VERIFY(BN_mul(bnTemp, bnOp1, bnOp2, CTX)); + VERIFY(BN_div(NULL, bnResult, bnTemp, bnMod, CTX)); + VERIFY(OsslToTpmBn(result, bnResult)); + goto Exit; + Error: + OK = FALSE; + Exit: + BN_clear_free(bnMod); // libtpms added + BN_clear_free(bnOp2); // libtpms added + BN_clear_free(bnOp1); // libtpms added + OSSL_LEAVE(); + return OK; +} + +/* B.2.3.2.3.4. BnMult() */ +/* Multiplies two numbers */ +/* Return Value Meaning */ +/* TRUE(1) success */ +/* FALSE(0) failure in operation */ + +LIB_EXPORT BOOL +BnMult( + bigNum result, + bigConst multiplicand, + bigConst multiplier + ) +{ + OSSL_ENTER(); + BIGNUM *bnTemp = BN_NEW(); + BOOL OK = TRUE; + BIG_INITIALIZED(bnA, multiplicand); + BIG_INITIALIZED(bnB, multiplier); + // + VERIFY(BN_mul(bnTemp, bnA, bnB, CTX)); + VERIFY(OsslToTpmBn(result, bnTemp)); + goto Exit; + Error: + OK = FALSE; + Exit: + BN_clear_free(bnB); // libtpms added + BN_clear_free(bnA); // libtpms added + OSSL_LEAVE(); + return OK; +} + +/* B.2.3.2.3.5. BnDiv() */ +/* This function divides two bigNum values. The function returns FALSE if there is an error in the + operation. */ +/* Return Value Meaning */ +/* TRUE(1) success */ +/* FALSE(0) failure in operation */ + +LIB_EXPORT BOOL +BnDiv( + bigNum quotient, + bigNum remainder, + bigConst dividend, + bigConst divisor + ) +{ + OSSL_ENTER(); + BIGNUM *bnQ = BN_NEW(); + BIGNUM *bnR = BN_NEW(); + BOOL OK = TRUE; + BIG_INITIALIZED(bnDend, dividend); + BIG_INITIALIZED(bnSor, divisor); + // + if(BnEqualZero(divisor)) + FAIL(FATAL_ERROR_DIVIDE_ZERO); + VERIFY(BN_div(bnQ, bnR, bnDend, bnSor, CTX)); + VERIFY(OsslToTpmBn(quotient, bnQ)); + VERIFY(OsslToTpmBn(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); + goto Exit; + Error: + OK = FALSE; + Exit: + BN_clear_free(bnSor); // libtpms added + BN_clear_free(bnDend); // libtpms added + OSSL_LEAVE(); + return OK; +} + +#if ALG_RSA +#if !RSA_KEY_SIEVE // libtpms added +/* B.2.3.2.3.6. BnGcd() */ +/* Get the greatest common divisor of two numbers */ +/* Return Value Meaning */ +/* TRUE(1) success */ +/* FALSE(0) failure in operation */ + +LIB_EXPORT BOOL +BnGcd( + bigNum gcd, // OUT: the common divisor + bigConst number1, // IN: + bigConst number2 // IN: + ) +{ + OSSL_ENTER(); + BIGNUM *bnGcd = BN_NEW(); + BOOL OK = TRUE; + BIG_INITIALIZED(bn1, number1); + BIG_INITIALIZED(bn2, number2); + // + BN_set_flags(bn1, BN_FLG_CONSTTIME); // number1 is secret prime number + VERIFY(BN_gcd(bnGcd, bn1, bn2, CTX)); + VERIFY(OsslToTpmBn(gcd, bnGcd)); + goto Exit; + Error: + OK = FALSE; + Exit: + BN_clear_free(bn2); // libtpms added + BN_clear_free(bn1); // libtpms added + OSSL_LEAVE(); + return OK; +} +#endif // libtpms added + +/* B.2.3.2.3.7. BnModExp() */ +/* Do modular exponentiation using bigNum values. The conversion from a bignum_t to a bigNum is + trivial as they are based on the same structure */ +/* Return Value Meaning */ +/* TRUE(1) success */ +/* FALSE(0) failure in operation */ + +LIB_EXPORT BOOL +BnModExp( + bigNum result, // OUT: the result + bigConst number, // IN: number to exponentiate + bigConst exponent, // IN: + bigConst modulus // IN: + ) +{ + OSSL_ENTER(); + BIGNUM *bnResult = BN_NEW(); + BOOL OK = TRUE; + BIG_INITIALIZED(bnN, number); + BIG_INITIALIZED(bnE, exponent); + BIG_INITIALIZED(bnM, modulus); + // + BN_set_flags(bnE, BN_FLG_CONSTTIME); // exponent may be private + VERIFY(BN_mod_exp(bnResult, bnN, bnE, bnM, CTX)); + VERIFY(OsslToTpmBn(result, bnResult)); + goto Exit; + Error: + OK = FALSE; + Exit: + BN_clear_free(bnM); // libtpms added + BN_clear_free(bnE); // libtpms added + BN_clear_free(bnN); // libtpms added + OSSL_LEAVE(); + return OK; +} + +/* B.2.3.2.3.8. BnModInverse() */ +/* Modular multiplicative inverse */ +/* Return Value Meaning */ +/* TRUE(1) success */ +/* FALSE(0) failure in operation */ + +LIB_EXPORT BOOL +BnModInverse( + bigNum result, + bigConst number, + bigConst modulus + ) +{ + OSSL_ENTER(); + BIGNUM *bnResult = BN_NEW(); + BOOL OK = TRUE; + BIG_INITIALIZED(bnN, number); + BIG_INITIALIZED(bnM, modulus); + // + BN_set_flags(bnN, BN_FLG_CONSTTIME); // number may be private + VERIFY(BN_mod_inverse(bnResult, bnN, bnM, CTX) != NULL); + VERIFY(OsslToTpmBn(result, bnResult)); + goto Exit; + Error: + OK = FALSE; + Exit: + BN_clear_free(bnM); // libtpms added + BN_clear_free(bnN); // libtpms added + OSSL_LEAVE(); + return OK; +} + +#endif // TPM_ALG_RSA + +#if ALG_ECC + +/* B.2.3.2.3.9. PointFromOssl() */ +/* Function to copy the point result from an OSSL function to a bigNum */ +/* Return Value Meaning */ +/* TRUE(1) success */ +/* FALSE(0) failure in operation */ +static BOOL +PointFromOssl( + bigPoint pOut, // OUT: resulting point + EC_POINT *pIn, // IN: the point to return + bigCurve E // IN: the curve + ) +{ + 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); + if(y == NULL) + FAIL(FATAL_ERROR_ALLOCATION); + // If this returns false, then the point is at infinity +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !defined(LIBRESSL_VERSION_NUMBER) // libtpms added begin + OK = EC_POINT_get_affine_coordinates(E->G, pIn, x, y, E->CTX); +#else // libtpms added begin + OK = EC_POINT_get_affine_coordinates_GFp(E->G, pIn, x, y, E->CTX); +#endif // libtpms added end + 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; +} +/* B.2.3.2.3.10. EcPointInitialized() */ +/* Allocate and initialize a point. */ + +LIB_EXPORT EC_POINT * // libtpms: exported function +EcPointInitialized( + pointConst initializer, + bigCurve E + ) +{ + EC_POINT *P = NULL; + + if(initializer != NULL) + { + BIG_INITIALIZED(bnX, initializer->x); + BIG_INITIALIZED(bnY, initializer->y); + if(E == NULL) + FAIL(FATAL_ERROR_ALLOCATION); + P = EC_POINT_new(E->G); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !defined(LIBRESSL_VERSION_NUMBER) // libtpms added begin + if(!EC_POINT_set_affine_coordinates(E->G, P, bnX, bnY, E->CTX)) +#else // libtpms added end + if(!EC_POINT_set_affine_coordinates_GFp(E->G, P, bnX, bnY, E->CTX)) +#endif // libtpms added + P = NULL; + BN_clear_free(bnX); // libtpms added + BN_clear_free(bnY); // libtpms added + } + return P; +} + +/* B.2.3.2.3.11. BnCurveInitialize() */ +/* This function initializes the OpenSSL group definition */ +/* It is a fatal error if groupContext is not provided. */ +/* Return Values Meaning */ +/* NULL the TPM_ECC_CURVE is not valid */ +/* non-NULL points to a structure in groupContext */ + +LIB_EXPORT bigCurve +BnCurveInitialize( + bigCurve E, // IN: curve structure to initialize + TPM_ECC_CURVE curveId // IN: curve identifier + ) +{ + const ECC_CURVE_DATA *C = GetCurveData(curveId); + if(C == NULL) + E = NULL; + if(E != NULL) + { + // This creates the OpenSSL memory context that stays in effect as long as the + // curve (E) is defined. + OSSL_ENTER(); // if the allocation fails, the TPM fails + EC_POINT *P = NULL; + BIG_INITIALIZED(bnP, C->prime); + BIG_INITIALIZED(bnA, C->a); + BIG_INITIALIZED(bnB, C->b); + BIG_INITIALIZED(bnX, C->base.x); + BIG_INITIALIZED(bnY, C->base.y); + BIG_INITIALIZED(bnN, C->order); + BIG_INITIALIZED(bnH, C->h); + // + E->C = C; + E->CTX = CTX; + + // initialize EC group, associate a generator point and initialize the point + // from the parameter data + // Create a group structure + E->G = EC_GROUP_new_curve_GFp(bnP, bnA, bnB, CTX); + VERIFY(E->G != NULL); + + // Allocate a point in the group that will be used in setting the + // generator. This is not needed after the generator is set. + P = EC_POINT_new(E->G); + VERIFY(P != NULL); + + // Need to use this in case Montgomery method is being used +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !defined(LIBRESSL_VERSION_NUMBER) // libtpms added begin + VERIFY(EC_POINT_set_affine_coordinates(E->G, P, bnX, bnY, CTX)); +#else // libtpms added end + VERIFY(EC_POINT_set_affine_coordinates_GFp(E->G, P, bnX, bnY, CTX)); +#endif // libtpms added + // Now set the generator + VERIFY(EC_GROUP_set_generator(E->G, P, bnN, bnH)); + + EC_POINT_free(P); + goto Exit_free; // libtpms changed + Error: + EC_POINT_free(P); + BnCurveFree(E); + E = NULL; + + Exit_free: // libtpms added begin + BN_clear_free(bnH); + BN_clear_free(bnN); + BN_clear_free(bnY); + BN_clear_free(bnX); + BN_clear_free(bnB); + BN_clear_free(bnA); + BN_clear_free(bnP); // libtpms added end + } +// Exit: + return E; +} + +/* B.2.3.2.3.15. BnCurveFree() */ +/* This function will free the allocated components of the curve and end the frame in which the + curve data exists */ +LIB_EXPORT void +BnCurveFree( + bigCurve E + ) +{ + if(E) + { + EC_GROUP_free(E->G); + OsslContextLeave(E->CTX); + } +} + +/* B.2.3.2.3.11. BnEccModMult() */ +/* This functi2n does a point multiply of the form R = [d]S */ +/* Return Values Meaning */ +/* FALSE failure in operation; treat as result being point at infinity */ + +LIB_EXPORT BOOL +BnEccModMult( + bigPoint R, // OUT: computed point + pointConst S, // IN: point to multiply by 'd' (optional) + bigConst d, // IN: scalar for [d]S + bigCurve E + ) +{ + EC_POINT *pR = EC_POINT_new(E->G); + EC_POINT *pS = EcPointInitialized(S, E); + BIG_INITIALIZED(bnD, d); + + 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_clear_free(pR); // libtpms changed + EC_POINT_clear_free(pS); // libtpms changed + BN_clear_free(bnD); // libtpms added + return !BnEqualZero(R->z); +} + +/* B.2.3.2.3.13. BnEccModMult2() */ +/* This function does a point multiply of the form R = [d]G + [u]Q */ +/* FALSE failure in operation; treat as result being point at infinity */ + +LIB_EXPORT BOOL +BnEccModMult2( + bigPoint R, // OUT: computed point + pointConst S, // IN: optional point + bigConst d, // IN: scalar for [d]S or [d]G + pointConst Q, // IN: second point + bigConst u, // IN: second scalar + 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)&(AccessCurveData(E)->base)) + EC_POINT_mul(E->G, pR, bnD, pQ, bnU, E->CTX); + else + { + 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); + } + PointFromOssl(R, pR, E); + EC_POINT_clear_free(pR); // libtpms changed + EC_POINT_clear_free(pS); // libtpms changed + EC_POINT_clear_free(pQ); // libtpms changed + BN_clear_free(bnD); // libtpms added + BN_clear_free(bnU); // libtpms added + + return !BnEqualZero(R->z); +} + +/* B.2.3.2.4. BnEccAdd() */ +/* This function does addition of two points. */ +/* Return Values Meaning */ +/* FALSE failure in operation; treat as result being point at infinity */ +LIB_EXPORT BOOL +BnEccAdd( + bigPoint R, // OUT: computed point + pointConst S, // IN: point to multiply by 'd' + pointConst Q, // IN: second point + bigCurve E // IN: curve + ) +{ + EC_POINT *pR = EC_POINT_new(E->G); + EC_POINT *pS = EcPointInitialized(S, E); + EC_POINT *pQ = EcPointInitialized(Q, E); + // + EC_POINT_add(E->G, pR, pS, pQ, E->CTX); + PointFromOssl(R, pR, E); + EC_POINT_clear_free(pR); // libtpms changed + EC_POINT_clear_free(pS); // libtpms changed + EC_POINT_clear_free(pQ); // libtpms changed + return !BnEqualZero(R->z); +} + +#endif // ALG_ECC +#endif // MATH_LIB_OSSL |